java - JavaFX 8 - Layout swapping or similar/equivalent functionality to Qt's StackedWidget? -
i've been asked write conversion program in javafx, need allow user set different options depending on conversion direction.
in reaction swapping conversion direction, need show 2 different (unique) sets of controls options relating current direction only.
in 1 direction need display 2 textfields, in other direction, pair of radiobuttons. show both @ same time , enable/disable when needed, i'm trying less cluttered approach first.
i'm looking solution has similar layout-switching functionality qt's stackedwidget i've used in c++, can swap out textfields radiobuttons , vice versa depending on conversion direction.
it's important note window has many other options common both directions, it's small part needs change according conversion direction. i'd prefer if access swapped controls within same controller.
i don't want tabs or page numbers user controls direction elsewhere, tabpane , pagination out, unless undesirable pieces of functionality can disabled.
i've heard there's called cardlayout in java framework (it's in awt if heard right) job want, what's javafx 8 equivalent? or there solution should using instead?
i'm using scenebuilder ideally can implement in that, can use pure code if need be.
you can use pane subclass (e.g. stackpane) , call pane.getchildren().setall(textfielddisplay); or pane.getchildren().setall(radiobuttondisplay); needed. different displays can kind of node, since hold other controls typically subclass of pane. in example below use gridpane 1 , vbox other. in real application, might define each 1 in own fxml file , load them independently, etc.
complete example (using fxml):
main.fxml:
<?xml version="1.0" encoding="utf-8"?> <?import javafx.scene.layout.vbox?> <?import javafx.scene.layout.stackpane?> <?import javafx.scene.control.checkbox?> <?import javafx.geometry.insets?> <?import javafx.scene.control.button?> <vbox xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.maincontroller" alignment="center"> <padding> <insets top="20" left="20" right="20" bottom="20" /> </padding> <checkbox text="show text fields" fx:id="showtextfields" vbox.vgrow="never"> <vbox.margin> <insets top="10" left="10" right="10" bottom="10"/> </vbox.margin> </checkbox> <stackpane fx:id="display" vbox.vgrow="always" /> <button text="ok" onaction="#submit" vbox.vgrow="never" /> </vbox> maincontroller.java:
package application; import javafx.fxml.fxml; import javafx.fxml.fxmlloader; import javafx.scene.node; import javafx.scene.control.checkbox; import javafx.scene.layout.stackpane; public class maincontroller { @fxml private checkbox showtextfields ; @fxml private stackpane display ; private node radiodisplay ; private node textfielddisplay ; private radiobuttoncontroller radiobuttoncontroller ; private textfieldcontroller textfieldcontroller ; public void initialize() throws exception { fxmlloader radiodisplayloader = new fxmlloader(getclass().getresource("radiodisplay.fxml")); radiodisplay = radiodisplayloader.load(); radiobuttoncontroller = radiodisplayloader.getcontroller(); fxmlloader textfielddisplayloader = new fxmlloader(getclass().getresource("textfielddisplay.fxml")); textfielddisplay = textfielddisplayloader.load(); textfieldcontroller = textfielddisplayloader.getcontroller(); showtextfields.selectedproperty().addlistener((obs, wasselected, isselected) -> { if (isselected) { display.getchildren().setall(textfielddisplay); } else { display.getchildren().setall(radiodisplay); } }); display.getchildren().add(radiodisplay); } @fxml private void submit() { if (showtextfields.isselected()) { system.out.println("value 1 "+ textfieldcontroller.gettext1()); system.out.println("value 2 "+ textfieldcontroller.gettext2()); } else { system.out.println("chosen value "+radiobuttoncontroller.getselecteditem()); } } } radiodisplay.fxml
<?xml version="1.0" encoding="utf-8"?> <?import javafx.scene.layout.vbox?> <?import javafx.geometry.insets?> <?import javafx.scene.control.radiobutton?> <vbox xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.radiobuttoncontroller" alignment="top_center" spacing="10"> <padding> <insets top="10" left="10" right="10" bottom="10"/> </padding> <radiobutton text="choice 1" selected="true" fx:id="choice1"/> <radiobutton text="choice 2" fx:id="choice2"/> </vbox> radiobuttoncontroller.java:
package application; import javafx.fxml.fxml; import javafx.scene.control.radiobutton; import javafx.scene.control.togglegroup; public class radiobuttoncontroller { @fxml private radiobutton choice1 ; @fxml private radiobutton choice2 ; public void initialize() { togglegroup togglegroup = new togglegroup(); choice1.settogglegroup(togglegroup); choice2.settogglegroup(togglegroup); } public string getselecteditem() { if (choice1.isselected()) { return "choice 1"; } else if (choice2.isselected()) { return "choice 2"; } else return "" ; } } textfielddisplay.fxml
<?xml version="1.0" encoding="utf-8"?> <?import javafx.scene.layout.gridpane?> <?import javafx.scene.layout.columnconstraints?> <?import javafx.scene.control.label?> <?import javafx.scene.control.textfield?> <gridpane xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.textfieldcontroller" hgap="10" vgap="10"> <columnconstraints> <columnconstraints hgrow="never" halignment="right"/> <columnconstraints hgrow="sometimes" /> </columnconstraints> <label text="value 1:" gridpane.columnindex="0" gridpane.rowindex="0"/> <label text="value 2:" gridpane.columnindex="0" gridpane.rowindex="1"/> <textfield fx:id="textfield1" gridpane.columnindex="1" gridpane.rowindex="0"/> <textfield fx:id="textfield2" gridpane.columnindex="1" gridpane.rowindex="1"/> </gridpane> textfieldcontroller.java:
package application; import javafx.fxml.fxml; import javafx.scene.control.textfield; public class textfieldcontroller { @fxml private textfield textfield1 ; @fxml private textfield textfield2 ; public string gettext1() { return textfield1.gettext() ; } public string gettext2() { return textfield2.gettext(); } } main.java:
package application; import javafx.application.application; import javafx.stage.stage; import javafx.scene.scene; import javafx.scene.layout.vbox; import javafx.fxml.fxmlloader; public class main extends application { @override public void start(stage primarystage) throws exception { vbox root = (vbox)fxmlloader.load(getclass().getresource("main.fxml")); scene scene = new scene(root,400,400); primarystage.setscene(scene); primarystage.show(); } public static void main(string[] args) { launch(args); } } all fxml files in same package (application) .java files.
update
if prefer not "modularize" extent, can put in single fxml single controller. in case, main.fxml looks like
<?xml version="1.0" encoding="utf-8"?> <?import javafx.scene.layout.vbox?> <?import javafx.scene.layout.stackpane?> <?import javafx.scene.control.checkbox?> <?import javafx.geometry.insets?> <?import javafx.scene.control.button?> <?import javafx.scene.control.radiobutton?> <?import javafx.scene.layout.gridpane?> <?import javafx.scene.layout.columnconstraints?> <?import javafx.scene.control.label?> <?import javafx.scene.control.textfield?> <vbox xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.maincontroller" alignment="center"> <padding> <insets top="20" left="20" right="20" bottom="20" /> </padding> <checkbox text="show text fields" fx:id="showtextfields" vbox.vgrow="never"> <vbox.margin> <insets top="10" left="10" right="10" bottom="10"/> </vbox.margin> </checkbox> <stackpane fx:id="display" vbox.vgrow="always"> <vbox fx:id="radiodisplay" alignment="top_center" spacing="10"> <padding> <insets top="10" left="10" right="10" bottom="10" /> </padding> <radiobutton text="choice 1" selected="true" fx:id="choice1" /> <radiobutton text="choice 2" fx:id="choice2" /> </vbox> <fx:define> <gridpane fx:id="textfielddisplay" hgap="10" vgap="10"> <columnconstraints> <columnconstraints hgrow="never" halignment="right" /> <columnconstraints hgrow="sometimes" /> </columnconstraints> <label text="value 1:" gridpane.columnindex="0" gridpane.rowindex="0" /> <label text="value 2:" gridpane.columnindex="0" gridpane.rowindex="1" /> <textfield fx:id="textfield1" gridpane.columnindex="1" gridpane.rowindex="0" /> <textfield fx:id="textfield2" gridpane.columnindex="1" gridpane.rowindex="1" /> </gridpane> </fx:define> </stackpane> <button text="ok" onaction="#submit" vbox.vgrow="never" /> </vbox> and corresponding controller is
package application; import javafx.fxml.fxml; import javafx.scene.node; import javafx.scene.control.checkbox; import javafx.scene.control.radiobutton; import javafx.scene.control.textfield; import javafx.scene.control.togglegroup; import javafx.scene.layout.stackpane; public class maincontroller { @fxml private checkbox showtextfields ; @fxml private stackpane display ; @fxml private node radiodisplay ; @fxml private node textfielddisplay ; @fxml private textfield textfield1 ; @fxml private textfield textfield2 ; @fxml private radiobutton choice1 ; @fxml private radiobutton choice2 ; public void initialize() throws exception { showtextfields.selectedproperty().addlistener((obs, wasselected, isselected) -> { if (isselected) { display.getchildren().setall(textfielddisplay); } else { display.getchildren().setall(radiodisplay); } }); togglegroup togglegroup = new togglegroup(); choice1.settogglegroup(togglegroup); choice2.settogglegroup(togglegroup); } @fxml private void submit() { if (showtextfields.isselected()) { system.out.println("value 1 "+ textfield1.gettext()); system.out.println("value 2 "+ textfield2.gettext()); } else { string chosenvalue ; if (choice1.isselected()) { chosenvalue = "choice 1"; } else if (choice2.isselected()) { chosenvalue = "choice 2"; } else { chosenvalue = "none"; } system.out.println("chosen value "+chosenvalue); } } } (and in case, remove other 2 fxml files , controllers).
Comments
Post a Comment