diff --git a/CodenameOne/src/com/codename1/ui/package-info.java b/CodenameOne/src/com/codename1/ui/package-info.java index 0cf4aee799d..caebccdeeca 100644 --- a/CodenameOne/src/com/codename1/ui/package-info.java +++ b/CodenameOne/src/com/codename1/ui/package-info.java @@ -299,7 +299,7 @@ /// /// ### FloatingHint /// -/// ![](https://www.codenameone.com/developer-guide/img/components-floatinghint.png) +/// ![](https://www.codenameone.com/developer-guide/img/generated/components-floatinghint.png) /// `com.codename1.components.FloatingHint` animates the text field hint into a label on top of /// the text field and visa versa /// diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/FloatingHintFigure.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/FloatingHintFigure.java new file mode 100644 index 00000000000..d779b4eed81 --- /dev/null +++ b/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/FloatingHintFigure.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ + +package com.codenameone.developerguide.screenshots; + +import com.codename1.components.FloatingHint; +import com.codename1.ui.Button; +import com.codename1.ui.Form; +import com.codename1.ui.TextField; +import com.codename1.ui.layouts.BoxLayout; + +/// The FloatingHint component beside the sample that builds it. +/// +/// The sample creates both fields empty, and the hint animates up on focus +/// gained, so the field the renderer focuses shows the floated state and the +/// other shows the hint still inside it. That is both states of the component +/// in one still, which is why focus is left where the renderer puts it rather +/// than moved or cleared. +class FloatingHintFigure implements GuideFigure { + @Override + public String id() { + return "components-floatinghint"; + } + + @Override + public Form build() { + // tag::the-components-of-codename-one-java-137[] + Form hi = new Form("Floating Hint", BoxLayout.y()); + TextField first = new TextField("", "First Field"); + TextField second = new TextField("", "Second Field"); + hi.add(new FloatingHint(first)). + add(new FloatingHint(second)). + add(new Button("Go")); + hi.show(); + // end::the-components-of-codename-one-java-137[] + hi.setFocused(null); + return hi; + } +} diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/GuideFigures.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/GuideFigures.java index 1a2542b7e7c..895d5da90d1 100644 --- a/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/GuideFigures.java +++ b/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/GuideFigures.java @@ -77,6 +77,10 @@ public static FigureVariant[] variants() { new FigureVariant(new GraphicsFontimageStyleFigure(), FigureDevice.ANDROID, false, "graphics-fontimage-style.png"), new FigureVariant(new GraphicsFontimageMaterialFigure(), FigureDevice.ANDROID, false, "graphics-fontimage-material.png"), new FigureVariant(new CsvParsingFigure(), FigureDevice.ANDROID, false, "csv-parsing.png"), + new FigureVariant(new PropertiesBindingFigure(), FigureDevice.ANDROID, false, + "properties-demo-binding.png"), + new FigureVariant(new FloatingHintFigure(), FigureDevice.ANDROID, false, + "components-floatinghint.png"), new FigureVariant(new ToggleButtonFigure(), FigureDevice.ANDROID, false, "components-toggle-buttons-android.png"), new FigureVariant(new ToggleButtonFigure(), FigureDevice.IOS, false, diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/PropertiesBindingFigure.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/PropertiesBindingFigure.java new file mode 100644 index 00000000000..29fdad58313 --- /dev/null +++ b/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/PropertiesBindingFigure.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ + +package com.codenameone.developerguide.screenshots; + +import com.codename1.ui.ButtonGroup; +import com.codename1.ui.Container; +import com.codename1.ui.Display; +import com.codename1.ui.Form; +import com.codename1.ui.RadioButton; +import com.codename1.ui.TextField; +import com.codename1.ui.layouts.BorderLayout; +import com.codename1.ui.layouts.BoxLayout; +import com.codename1.ui.layouts.GridLayout; +import com.codename1.ui.spinner.Picker; +import com.codename1.properties.IntProperty; +import com.codename1.properties.Property; +import com.codename1.properties.PropertyBusinessObject; +import com.codename1.properties.PropertyIndex; +import com.codename1.properties.UiBinding; +import java.util.Date; + +/// The contact form the properties chapter shows beside its binding sample. +/// +/// Nothing here reads the network, the clock or the filesystem: every field is +/// bound to a property of one freshly constructed `Contact`, so the render is +/// the same on any host. The date picker is deliberately left unset -- it shows +/// its empty placeholder, which is both what the sample produces and one less +/// thing that could differ between runs. +class PropertiesBindingFigure implements GuideFigure { + @Override + public String id() { + return "properties-demo-binding"; + } + + @Override + public Form build() { + Form hi = new Form("Contact", new BorderLayout()); + Contact c = new Contact(); + // tag::io-java-172[] + Container resp = new Container(BoxLayout.y()); + UiBinding uib = new UiBinding(); + + TextField nameTf = new TextField(); + uib.bind(c.name, nameTf); + resp.add(c.name.getLabel()). // <1> + add(nameTf); + + TextField emailTf = new TextField(); + emailTf.setConstraint(TextField.EMAILADDR); + uib.bind(c.email, emailTf); + resp.add(c.email.getLabel()). + add(emailTf); + + TextField phoneTf = new TextField(); + phoneTf.setConstraint(TextField.PHONENUMBER); + uib.bind(c.phone, phoneTf); + resp.add(c.phone.getLabel()). + add(phoneTf); + + Picker dateOfBirth = new Picker(); + dateOfBirth.setType(Display.PICKER_TYPE_DATE); // <2> + uib.bind(c.dateOfBirth, dateOfBirth); + resp.add(c.dateOfBirth.getLabel()). + add(dateOfBirth); + + ButtonGroup genderGroup = new ButtonGroup(); + RadioButton male = RadioButton.createToggle("Male", genderGroup); + RadioButton female = RadioButton.createToggle("Female", genderGroup); + RadioButton undefined = RadioButton.createToggle("Undefined", genderGroup); + uib.bindGroup(c.gender, new String[] {"M", "F", "U"}, male, female, undefined); // <3> + resp.add(c.gender.getLabel()). + add(GridLayout.encloseIn(3, male, female, undefined)); + + TextField rankTf = new TextField(); + rankTf.setConstraint(TextField.NUMERIC); + uib.bind(c.rank, rankTf); // <4> + resp.add(c.rank.getLabel()). + add(rankTf); + // end::io-java-172[] + hi.add(BorderLayout.CENTER, resp); + hi.show(); + // Focus lands on the first focusable control, and a focused toggle resolves + // sel# -- the accent ring -- whether or not it is checked. Focusing a text + // field instead keeps that ring off the gender row, which is what this + // figure is showing. + hi.setFocused(nameTf); + return hi; + } + + /// The business object the sample binds against. + /// + /// It matches the Contact the chapter prints for this section, field for + /// field, deliberately: the figure exists so that the picture is what the + /// printed listing produces. That listing calls no setLabel, and + /// PropertyBase.getLabel() answers with the property's name when none was + /// set, so the form is labelled name, email, dateOfBirth. Prettier labels + /// would need setLabel calls, and adding them only here would make the + /// picture show something the chapter's own Contact cannot produce -- the + /// exact mismatch this figure replaced. If the form should read Name and + /// Date Of Birth, the chapter's Contact is where that belongs, and then + /// this class follows it. + public static class Contact implements PropertyBusinessObject { + public final IntProperty id = new IntProperty<>("id"); + public final Property name = new Property<>("name"); + public final Property email = new Property<>("email"); + public final Property phone = new Property<>("phone"); + public final Property dateOfBirth = new Property<>("dateOfBirth", Date.class); + public final Property gender = new Property<>("gender"); + public final IntProperty rank = new IntProperty<>("rank"); + public final PropertyIndex idx = + new PropertyIndex(this, "Contact", id, name, email, phone, dateOfBirth, gender, rank); + + public PropertyIndex getPropertyIndex() { + return idx; + } + } +} diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/IoJava172Snippet.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/IoJava172Snippet.java deleted file mode 100644 index d5f9b92a538..00000000000 --- a/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/IoJava172Snippet.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Codename One designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Codename One through http://www.codenameone.com/ if you - * need additional information or have any questions. - */ -package com.codenameone.developerguide.snippets.generated; - -import com.codename1.gpu.*; -import com.codename1.ui.*; -import com.codename1.ui.animations.*; -import com.codename1.ui.events.*; -import com.codename1.ui.geom.*; -import com.codename1.ui.layouts.*; -import com.codename1.ui.list.*; -import com.codename1.ui.plaf.*; -import com.codename1.ui.util.*; -import com.codename1.components.*; -import com.codename1.charts.models.*; -import com.codename1.charts.renderers.*; -import com.codename1.charts.views.*; -import com.codename1.capture.*; -import com.codename1.io.*; -import com.codename1.l10n.*; -import com.codename1.location.*; -import com.codename1.maps.*; -import com.codename1.media.*; -import com.codename1.messaging.*; -import com.codename1.payment.*; -import com.codename1.processing.*; -import com.codename1.properties.*; -import com.codename1.push.*; -import com.codename1.security.*; -import com.codename1.social.*; -import com.codename1.ui.spinner.*; -import java.io.*; -import com.codename1.io.rest.*; -import com.codename1.xml.*; -import com.codename1.ui.tree.*; -import com.codename1.ui.table.*; -import com.codename1.db.*; -import com.codename1.io.gzip.*; -import com.codename1.util.*; -import com.codename1.system.*; -import com.codename1.annotations.*; -import com.codename1.io.services.*; -import java.util.*; - - -class IoJava172Snippet { - - - Object context; - String url = "https://example.com"; - Object value; - Object body; - Object event; - String apiKey = "test-key"; - String myHttpsURL = "https://example.com"; - java.util.List validKeysList = new java.util.ArrayList<>(); - Image myImage; - Graphics graphics; - Graphics g; - GraphicsDevice device; - Form form; - Form hi; - Container cnt; - Container myForm; - Component component; - Button button; - MultiButton myMultiButton; - Label label; - BrowserComponent browserComponent; - Resources theme; - String myUrl = "https://example.com"; - String baseUrl = "https://example.com"; - String token = "token"; - String myToken = "token"; - String password = "password"; - String user = "user"; - String email = "user@example.com"; - String fullPathToFile = "/path/to/file.txt"; - String bodyValueAsString = "{}"; - String petId = "1"; - Result result; - ConnectionRequest request; - java.io.Reader reader; - java.io.Writer writer; - java.io.InputStream input; - java.io.OutputStream outputStream; - - void snippet() throws Exception { - // tag::io-java-172[] - Container resp = new Container(BoxLayout.y()); - UiBinding uib = new UiBinding(); - - TextField nameTf = new TextField(); - uib.bind(c.name, nameTf); - resp.add(c.name.getLabel()). // <1> - add(nameTf); - - TextField emailTf = new TextField(); - emailTf.setConstraint(TextField.EMAILADDR); - uib.bind(c.email, emailTf); - resp.add(c.email.getLabel()). - add(emailTf); - - TextField phoneTf = new TextField(); - phoneTf.setConstraint(TextField.PHONENUMBER); - uib.bind(c.phone, phoneTf); - resp.add(c.phone.getLabel()). - add(phoneTf); - - Picker dateOfBirth = new Picker(); - dateOfBirth.setType(Display.PICKER_TYPE_DATE); // <2> - uib.bind(c.dateOfBirth, dateOfBirth); - resp.add(c.dateOfBirth.getLabel()). - add(dateOfBirth); - - ButtonGroup genderGroup = new ButtonGroup(); - RadioButton male = RadioButton.createToggle("Male", genderGroup); - RadioButton female = RadioButton.createToggle("Female", genderGroup); - RadioButton undefined = RadioButton.createToggle("Undefined", genderGroup); - uib.bindGroup(c.gender, new String[] {"M", "F", "U"}, male, female, undefined); // <3> - resp.add(c.gender.getLabel()). - add(GridLayout.encloseIn(3, male, female, undefined)); - - TextField rankTf = new TextField(); - rankTf.setConstraint(TextField.NUMERIC); - uib.bind(c.rank, rankTf); // <4> - resp.add(c.rank.getLabel()). - add(rankTf); - // end::io-java-172[] - } - - public class Contact implements PropertyBusinessObject { - public final IntProperty id = new IntProperty<>("id"); - public final Property name = new Property<>("name"); - public final Property email = new Property<>("email"); - public final Property phone = new Property<>("phone"); - public final Property dateOfBirth = new Property<>("dateOfBirth", Date.class); - public final Property gender = new Property<>("gender"); - public final IntProperty rank = new IntProperty<>("rank"); - public final PropertyIndex idx = new PropertyIndex(this, "Contact", id, name, email, phone, dateOfBirth, gender, rank); - public PropertyIndex getPropertyIndex() { return idx; } - } - Contact c = new Contact(); - -} diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/TheComponentsOfCodenameOneJava137Snippet.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/TheComponentsOfCodenameOneJava137Snippet.java deleted file mode 100644 index cd60b9289de..00000000000 --- a/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/TheComponentsOfCodenameOneJava137Snippet.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Codename One designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Codename One through http://www.codenameone.com/ if you - * need additional information or have any questions. - */ - -package com.codenameone.developerguide.snippets.generated; - -import com.codename1.gpu.*; -import com.codename1.ui.*; -import com.codename1.ui.animations.*; -import com.codename1.ui.events.*; -import com.codename1.ui.geom.*; -import com.codename1.ui.layouts.*; -import com.codename1.ui.list.*; -import com.codename1.ui.plaf.*; -import com.codename1.ui.util.*; -import com.codename1.components.*; -import com.codename1.charts.models.*; -import com.codename1.charts.renderers.*; -import com.codename1.charts.views.*; -import com.codename1.capture.*; -import com.codename1.io.*; -import com.codename1.l10n.*; -import com.codename1.location.*; -import com.codename1.maps.*; -import com.codename1.media.*; -import com.codename1.messaging.*; -import com.codename1.payment.*; -import com.codename1.processing.*; -import com.codename1.properties.*; -import com.codename1.push.*; -import com.codename1.security.*; -import com.codename1.social.*; -import com.codename1.ui.spinner.*; -import java.io.*; -import java.util.*; - - -class TheComponentsOfCodenameOneJava137Snippet { - - Object context; - Object url; - Object value; - Object body; - Object event; - String apiKey = "test-key"; - String myHttpsURL = "https://example.com"; - java.util.List validKeysList = new java.util.ArrayList<>(); - Image myImage; - Graphics graphics; - Graphics g; - GraphicsDevice device; - Form form; - Form hi; - Container cnt; - Container myForm; - Component component; - Button button; - MultiButton myMultiButton; - Label label; - BrowserComponent browserComponent; - Resources theme; - void snippet() throws Exception { - // tag::the-components-of-codename-one-java-137[] - Form hi = new Form("Floating Hint", BoxLayout.y()); - TextField first = new TextField("", "First Field"); - TextField second = new TextField("", "Second Field"); - hi.add(new FloatingHint(first)). - add(new FloatingHint(second)). - add(new Button("Go")); - hi.show(); - // end::the-components-of-codename-one-java-137[] - } -} diff --git a/docs/developer-guide/The-Components-Of-Codename-One.asciidoc b/docs/developer-guide/The-Components-Of-Codename-One.asciidoc index 57f18aab23a..b18d7c72702 100644 --- a/docs/developer-guide/The-Components-Of-Codename-One.asciidoc +++ b/docs/developer-guide/The-Components-Of-Codename-One.asciidoc @@ -2616,11 +2616,11 @@ https://www.codenameone.com/javadoc/com/codename1/components/FloatingHint.html[F [source,java] ---- -include::../demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/TheComponentsOfCodenameOneJava137Snippet.java[tag=the-components-of-codename-one-java-137,indent=0] +include::../demos/common/src/main/java/com/codenameone/developerguide/screenshots/FloatingHintFigure.java[tag=the-components-of-codename-one-java-137,indent=0] ---- -.The FloatingHint component with one component that contains text and another that doesn't -image::img/components-floatinghint.png[The FloatingHint component with one component that contains text and another that doesn't,scaledwidth=30%] +.The hint floats on the field being edited and stays inside the one that isn't +image::img/generated/components-floatinghint.png[Floating hint,scaledwidth=30%] === Floating Button diff --git a/docs/developer-guide/img/components-floatinghint.png b/docs/developer-guide/img/components-floatinghint.png deleted file mode 100644 index eb32ae0b1ed..00000000000 Binary files a/docs/developer-guide/img/components-floatinghint.png and /dev/null differ diff --git a/docs/developer-guide/img/generated/components-floatinghint.png b/docs/developer-guide/img/generated/components-floatinghint.png new file mode 100644 index 00000000000..794cd8ee23d Binary files /dev/null and b/docs/developer-guide/img/generated/components-floatinghint.png differ diff --git a/docs/developer-guide/img/generated/properties-demo-binding.png b/docs/developer-guide/img/generated/properties-demo-binding.png new file mode 100644 index 00000000000..263dca7135d Binary files /dev/null and b/docs/developer-guide/img/generated/properties-demo-binding.png differ diff --git a/docs/developer-guide/img/properties-demo-binding.png b/docs/developer-guide/img/properties-demo-binding.png deleted file mode 100644 index c1de9df7b5d..00000000000 Binary files a/docs/developer-guide/img/properties-demo-binding.png and /dev/null differ diff --git a/docs/developer-guide/io.asciidoc b/docs/developer-guide/io.asciidoc index abfb3d1e4bc..ecebdc6a705 100644 --- a/docs/developer-guide/io.asciidoc +++ b/docs/developer-guide/io.asciidoc @@ -1769,7 +1769,7 @@ You can build a UI that would allow you to edit the `Contact` property in memory [source,java] ---- -include::../demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/IoJava172Snippet.java[tag=io-java-172,indent=0] +include::../demos/common/src/main/java/com/codenameone/developerguide/screenshots/PropertiesBindingFigure.java[tag=io-java-172,indent=0] ---- <1> Notice the use of the property's label, which allows better encapsulation @@ -1781,7 +1781,7 @@ include::../demos/common/src/main/java/com/codenameone/developerguide/snippets/g <4> Numeric bindings "work" .Properties form for the contact -image::img/properties-demo-binding.png[Properties form for the contact,scaledwidth=20%] +image::img/generated/properties-demo-binding.png[Properties form for the contact,scaledwidth=30%] ====== Binding object & auto commit