0

I have one button in one FXML and two text fields in another FXML. These two FXMLs are independent, I mean they are not nested. I want to print the text (which are in the two text fields) in the console/output whenever there is a click in the button. Below are the fxmls and their controllers:

Button.fxml

    <AnchorPane id="AnchorPane" prefHeight="200.0" prefWidth="320.0" xmlns:fx="http://javafx.com/fxml" fx:controller="textboxandbuttonbinding.ButtonController">
      <children>
         <Button fx:id="button" layoutX="126.0" layoutY="90.0" onAction="#handleButtonAction" text="Button" />
      </children>
    </AnchorPane>

ButtonController.java

    public class ButtonController implements Initializable {

        @FXML
        private void handleButtonAction(ActionEvent event) {

        }

        @Override
        public void initialize(URL url, ResourceBundle rb) {

        }    
    }

Text.fxml

    <AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" fx:controller="textboxandbuttonbinding.Sample1111Controller">
       <children>
           <TextField fx:id="textField1" layoutX="186.0" layoutY="133.0" prefWidth="200.0" promptText="text 1" />
           <TextField fx:id="textField2" layoutX="186.0" layoutY="200.0" prefWidth="200.0" promptText="text2" />
       </children>
    </AnchorPane>

TextController.java

    public class TextController implements Initializable {
        @FXML
        private TextField textField1;
        @FXML
        private TextField textField2;

        @Override
        public void initialize(URL url, ResourceBundle rb) {

        }    
    }

How can I achieve this functionality? I have taken into consideration that these two FXMLs are loaded at the same time as two different windows.

BungBung
  • 29
  • 1
  • 4
  • you can use this solution: http://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml or this solution http://stackoverflow.com/questions/14511016/how-can-i-use-a-variable-from-another-controller-in-javafx or even this solution http://stackoverflow.com/questions/9717852/how-to-pass-object-created-in-fxml-controller1-to-controller2-of-inner-fxml-cont/10718683#10718683 – Sergey Grinev Nov 09 '13 at 22:25
  • Hi the solutions you provide are mainly setting data to another controller. What I want is getting data from another FXML, especially from TextField. I thought the solution given by SnakeDoc should work but I am not sure why it is not working. Please help I am totally stuck here. – BungBung Nov 10 '13 at 09:03

2 Answers2

2

With some modification in above answer (by SnakeDoc), i am able to achieved the functionality.

I have created a separate Singleton class:

Singleton.java

    public class Singleton {
        private static Singleton instance = new Singleton();
        public static Singleton getInstance(){
            return instance;
        }

        private TextField txtField1;
        private TextField txtField2;

        public TextField getTxtField2() {
            return txtField2;
        }

        public void setTxtField2(TextField txtField2) {
           this.txtField2 = txtField2;
        }

        public TextField getTxtField1() {
           return txtField1;
        }

       public void setTxtField1(TextField txtField1) {
           this.txtField1 = txtField1;
       }

    }

The text fields are set in the initialize method.

TextController.java

    public class TextController implements Initializable {

       @FXML
       private TextField textField1;

       @FXML
       private TextField textField2;

       @Override
       public void initialize(URL url, ResourceBundle rb) {
            Singleton.getInstance().setTxtField1(textField1);
            Singleton.getInstance().setTxtField2(textField2);
       }    
    }

The getter methods are called in the class ButtonController.java

ButtonController.java

    public class ButtonController implements Initializable {    

        @FXML
        private void handleButtonAction(ActionEvent event) {
            String str1 = Singleton.getInstance().getTxtField1().getText();
            String str2 = Singleton.getInstance().getTxtField2().getText();

            System.out.println(str1);
            System.out.println(str2);

        }

        @Override
        public void initialize(URL url, ResourceBundle rb) {

        }    
    }
BungBung
  • 29
  • 1
  • 4
1

Turn your controller into a Singleton, then have a setter/getter and the other Controller and then access the values.

public class TextController implements Initializable {

    private TextController instance;

    private TextController() {};

    public static TextController getInstance() {
        if (TextController.instance == null) {
            synchronized (TextController.class) {
                if (TextController.instance == null) {
                    TextController.instance = new TextController();
                }
            }
        }
        return TextController.instance;
    }

    @FXML
    private TextField textField1;

    public TextField getTextField1() {
        return textField1;
    }
    @FXML
    private TextField textField2;

    public TextField getTextField2() {
        return textField2;
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {

    }    
}

Then in your other controller you can do something like:

TextController.getInstance().getTextField1();

etc.

SnakeDoc
  • 13,611
  • 17
  • 65
  • 97
  • I have tried using singleton design pattern but I am not sure why it is throwing null pointer exception getting the TextField. Here is my code for accessing the getter method: @FXML private void handleButtonAction(ActionEvent event) { String str1 = TextController.getInstance().getTextField1().getText(); String str2 = TextController.getInstance().getTextField2().getText(); System.out.println("text 1 ::: "+str1); System.out.println("text 1 ::: "+str2); } – BungBung Nov 09 '13 at 23:13
  • Hi, I tried lazy initialization and early initialization of Singleton, but none of them are working. The problem is TextController.getInstance() returns NULL. Seems like instance is not yet create. Please help. – BungBung Nov 10 '13 at 08:52
  • Hi SnakeDoc, It is working now. The problem in your code is that there is not setter method for the singleton Instance. I have created a separate singleton class which have getter and setter for the Textfields. and I set the setter method in the initialize method of TextController.java. Thanks – BungBung Nov 10 '13 at 10:09
  • was away from the office -- yes, i forgot to add the setter to my sample code, was in a hurry! Glad you got it working :) – SnakeDoc Nov 11 '13 at 15:40
  • That's fine in this case, but won't work if, for example, you wanted to include multiple nodes created by the same FXML file (they would all share the same controller, so they wouldn't work correctly). JavaFX provides plenty of mechanisms for handling this situation without restructuring the design like this. See the solution I posted at https://forums.oracle.com/thread/2601811 – James_D Nov 16 '13 at 21:00
  • does the bound `SimpleTextProperty`'s throw events when they update? If not, then you would have to continuously poll it to see if/when it changes. Bindings is nice, but if both controllers are singletons, then its' mostly the same. You call `getInstance()` on one controller from the other, and then your getter or setter... since the controller is a singleton, only the only instance of it will be returned. so it's thread safe, etc. – SnakeDoc Nov 16 '13 at 21:40