JavaFX passing data between screens - javafx

I have two screens which will be loaded at the start of program. I have a text field and a button on screen 1 and a label on screen2.
Now when I enter any text in text field of screen1 and and press the button, the label on screen2 should be set to that text (which was entered in screen1). (both the screens are active all the time right from program launch, so we need to update the label after the FXML is loaded).
I have tried properties and binding but had no success.
Controller 1: (Mapped to Controller1.fxml)
public class Controller1 {
#FXML private Button button;
#FXML private TextField tfield;
}
Controller 2: (Mapped to Controller2.fxml)
public class Controller2 {
#FXML private Label label;
}
Both the stages/screens are created from MainDriver.java class.

Related

How to create validated TextField entensions in JavaFX

I want to create a JavaFX fxml based dialog, where the user can enter a bunch of integer and double values. I created the dialog in SceneBuilder using for each of the values a dedicated TextField.
Intentionally I am not using Binding between the TextFields and the model. In order to NOT add a ChangeListener or set a TextFormatter to each of these TextFields in the controller again and again, I created a dedicated IntegerTextField and DoubleTextField class, e.g.
public class IntegerTextField extends TextField {
protected static Pattern decimalPattern = Pattern.compile("^-?\\d+$"); // Double ("-?\\d*(\\.\\d{0,1})?");
public IntegerTextField() {
super();
setTextFormatter(new TextFormatter<>(c -> (decimalPattern.matcher(c.getControlNewText()).matches()) ? c : null ));
}
public int getInt() {
try {
return Integer.parseInt(getText());
}
catch (NumberFormatException e) {
return 0;
}
}
}
and in the Controller class I replaced the previous
#FXML private TextField setsTextField;
with
#FXML private IntegerTextField setsTextField;
When I got the
javafx.fxml.LoadException:...Can not set util.IntegerTextField field ctrl.ExerciseEditorCtrl.setsTextField to javafx.scene.control.TextField
I realized that this implicit downcasting doesn't work.
Is there a way to do this properly with fxml or is it neccessary to have the dialog setup in a java class when using IntegerTextField?

How to solve JavaFX ContextMenu source node?

I have multiple CheckBoxes in the user interface I created in the FXML file.
<CheckBox..>
<contextMenu>
<ContextMenu>
<items>
<MenuItem text="%uncheckall" onAction="#uncheckAll" />
<MenuItem text="%checkall" onAction="#checkAll" />
</items>
</ContextMenu>
</contextMenu>
</CheckBox>
...
All CheckBoxes use the same methods, i.e. uncheckAll and checkAll.
How can I return ContextMenu's source Node i.e. CheckBox in the handling methods from Event?
#FXML private void uncheckAll(Event event) {
MenuItem mni = (MenuItem)event.getSource();
ContextMenu cm = mni.getParentPopup();
...???
}
There doesn't appear to be anything in the API for obtaining the owner of a Node's context menu, however the ancestor class of ContextMenu has method setUserData. You can set the CheckBox as the user data of the ContextMenu. Here is an example using code only, i.e. not FXML.
CheckBox cb = new CheckBox("check");
MenuItem mi = new MenuItem("menu item");
mi.setOnAction(this::uncheckAll);
ContextMenu cm = new ContextMenu(mi);
cm.setUserData(cb);
cb.setContextMenu(cm);
Then, in your uncheckAll method, you can retrieve the CheckBox via method getUserData.
#FXML private void uncheckAll(Event event) {
MenuItem mi = (MenuItem) event.getSource();
ContextMenu cm = mi.getParentPopup();
CheckBox cb = (CheckBox) cm.getUserData();
}
Edit
In FXML simply add a userData attribute to the ContextMenu tag.
<ContextMenu userData="cbxGroup1">
You probably don’t actually need to work out which checkbox the context menu is attached to.
Your task can probably be accomplished through standard fxml injection into a controller.
Assign the checkbox an fx:id in your fxml:
fx:id="cb"
Inject it in your controller:
#FXML private CheckBox cb;
After the fxml is loaded, you can refer to the check box by name cb anywhere in the controller, including in an event handler implementation.
#FXML private void uncheckAll(Event e) {
// you can refer to cb directly here.
}
As you have multiple checkboxes in your interface, do all of the above multiple times, including the event handler definition.
If you want to share common processing for the event handlers, you can call a separate method, passing in the reference to the checkbox associated with the event handler.
#FXML private CheckBox cb1;
#FXML private CheckBox cb2;
#FXML private void uncheckAllForCb1(Event e) {
uncheckAll(cb1);
}
#FXML private void uncheckAllForCb2(Event e) {
uncheckAll(cb2);
}
private void uncheckAll(CheckBox sourceBox) {
// take action for box.
}

javafx/ fxml - Switching Screens/ add a new Tab in controller

Firstly, sorry for my English. I hope, you unterstand it.
Last Month I started developing a little programm with FXML/ JavaFX.
I have two screens, and I'm switching between them. This is not the problem.
The problem is: On one Screen i have a listview, where i can choose an item. When i have chosen an item, i want to open a new tab on the other screen with the content of the item. Therefore, i have to click on a button.
When i have chosen an item, i can print out the selected item, but how do I open a new tab on the other screen. Both Screens a two different FXML and are activited from the controller. How can I add a Tab, although loading fxml?
public class Controller{
#FXML
private ListView<String> lv;
#FXML
private Button check;
#FXML
public void projectview (Event e3) throws Exception{
Stage stage = null;
Parent root = null;
if(e3.getSource()==check){
//Check is the declaration for the Button on the screen with the listview
String projectview= lv.getSelectionModel().getSelectedItem();
stage = (Stage) check.getScene().getWindow();
root = FXMLLoader.load(getClass().getResource("FXML1.fxml"));
//Here I want to add a tab in FXML1.fxml
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
}
If something is missing or not clear, please ask. I read other similar questions, but i don't know, what to do.
Thanks for help

Changing prompt text for JavaFX textfield

I have a choicebox and textfield next to that choicebox in a JavaFX application. I want grey textbox in the textfield to tell the user what to input. However, I want the prompt text to change according to what is selected in the choicebox.
I looked online and found code on how to have a textfield with prompt text but I couldn't get the prompt text to change with a changeListener on the choicebox.
I tried
textfield = new Textfield(newPrompt);
with the textfield already previously declared with a different prompt text. This did not work. How do I achieve the effect of having changing prompt text based on the users selection in the choicebox?
Instead of reassigning the textfield variable to a new TextField object (via textfield = new TextField(newPrompt);), use the TextField's setPromptText(String s) method in your ChangeListener:
final ChoiceBox<String> box = ...; //choicebox created and filled
box.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
textfield.setPromptText("New Prompt Text!");
}
});

JavaFX FXML menuItem action

I'm trying to set a variable value when a MenuItem i chosen in a MenuButton object.
I've tried to search for this but I've came up empty handed.
Here's the code to set the MenuItems:
private ObservableList<MenuItem> templateMenuItems = FXCollections.observableArrayList();
#FXML private MenuButton menu = new MenuButton();
#FXML
protected void getTemplates() throws IOException {
CaspReturn tls = this.socket.runCmd(new Tls(""));
String tlsList = tls.getResponse();
String[] tlsListSplitt = tlsList.split("\\n");
for (int i = 0; i < tlsListSplitt.length; i++) {
String[] tlsLine = tlsListSplitt[i].split("\"");
this.templateMenuItems.add(new MenuItem(tlsLine[1]));
}
this.menu.getItems().setAll(this.templateMenuItems);
}
I'm not sure how to write the code to get the text from a menuItem or which field in scenebuilder the method should be in.
It's not clear what your asking, but I'll assume that you want to know the text of a menu item when it is clicked. To do that, you need to add an event handler onto the menu item. The following is clipped from the JavaDoc for ContextMenu:
MenuItem item1 = new MenuItem("About");
item1.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
System.out.println("About");
}
});
You can get the event source, cast in to MenuItem and then get the text from that.
There's a real problem with your code the way it's written, though. You have calls to an external database in getTemplates, and as it's implemented as an #FXML element that almost guarantees that it'll be run on the FXAT, which is really, really bad.
I'd refactor that so that the database access is in a Task, and then the MenuItem creation is a handler for the onSucceeded event of the Task. Then you need instantiate a ContextMenu and install the MenuItem's on it in that event handler.
The getTemplates() method should be called as the onAction event for the button.

Resources