0

I have been working on JavaFX and trying figure out how to connect classes contained withing the package. I want the "text1btn" button from MainController class to send a text from "scene1TextField" also in MainController class to TextArea in LeftTextArea class. I would appreciate any comments on that. Thank you.

package sample;

public class Main extends Application {

    public static BorderPane root = new BorderPane();

    public static BorderPane getRoot() {
        return root;
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        URL url1 = getClass().getResource("../view/MainView.fxml");
        BorderPane bp1 = FXMLLoader.load(url1);

        URL url2 = getClass().getResource("../view/LeftTextArea.fxml");
        AnchorPane bp2 = FXMLLoader.load(url2);    
        root.setTop(bp1);
        root.setCenter(bp2);    
        primaryStage.setScene(new Scene(root, 500, 400));
        primaryStage.setResizable(false);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

package Controller;

public class MainController {    
    @FXML
    Button scene1btn;
    @FXML
    Button scene2btn;
    @FXML
    TextField scene1TextField;
    @FXML
    TextField scene2TextField;

    @FXML
    Button text1btn;
    @FXML
    Button text2btn;
    @FXML
    TextArea mainViewTextArea;


    @FXML
    public void initialize() {

    }

    @FXML
    public void text1btnClicked() {

    }

    @FXML
    public void text2btnClicked() {

    }

    @FXML
    private void scene1btnClicked() {    
        try {
            URL url1 = getClass().getResource("../view/LeftTextArea.fxml");
            AnchorPane bp1 = FXMLLoader.load(url1);
            BorderPane border = Main.getRoot();
            border.setCenter(bp1);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }    
    @FXML
    private void scene2btnClicked() {

        try {
            URL url2 = getClass().getResource("../view/RightTextArea.fxml");
            AnchorPane bp2 = FXMLLoader.load(url2);
            BorderPane border = Main.getRoot();
            border.setCenter(bp2);    
        } catch (IOException e) {
            e.printStackTrace();
        }    
    }    
}

package Controller;

public class LeftTextArea {    
    @FXML
    public TextArea leftTextArea;    
}
Przemek
  • 1
  • 2

2 Answers2

1

A quick and simple approach is just to expose a StringProperty in the MainController, and when it changes call a method in the LeftTextArea:

public class MainController {  

    private final StringProperty text = new SimpleStringProperty();

    public StringProperty textProperty() {
        return text ;
    }

    // existing code ...

    @FXML
    public void text1btnClicked() {
        textProperty().set(scene1TextField.getText());
    }

    // ...
}

In LeftTextArea do

public class LeftTextArea {    
    @FXML
    public TextArea leftTextArea;    

    public void setText(String text) {
        leftTextArea.setText(text);
    }
}

And then you can tie it all together with

@Override
public void start(Stage primaryStage) throws Exception {
    URL url1 = getClass().getResource("../view/MainView.fxml");
    FXMLLoader loader1 = new FXMLLoader(url1);
    BorderPane bp1 = loader1.load();
    MainController mainController = loader1.getController();

    URL url2 = getClass().getResource("../view/LeftTextArea.fxml");
    FXMLLoader loader2 = new FXMLLoader(url2);
    AnchorPane bp2 = loader2.load();
    LeftTextArea leftTextArea = loader2.getController();

    mainController.textProperty().addListener((obs, oldText, newText) ->
        leftTextArea.setText(newText));

    root.setTop(bp1);
    root.setCenter(bp2);    
    primaryStage.setScene(new Scene(root, 500, 400));
    primaryStage.setResizable(false);
    primaryStage.show();
}

If you end up needing multiple properties like this that are essentially shared between controllers, you probably need to define a "model" class to encapsulate them all in one place, and pass the model to the controllers. See, e.g. JavaFX controller to controller - access to UI Controls or Applying MVC With JavaFx

James_D
  • 201,275
  • 16
  • 291
  • 322
-1

If you want to set any field in the class LeftTextArea just simply create a public setter method in Class LeftTextArea like

public void setTextArea(Text text){
        //do what you want to do
}

Then call the method from MainController class with the object of LeftTextArea class. like LeftTextArea leftTextArea = new LeftTextArea(); leftTextArea.setTextArea(text); //text is the desired you want to send

IR Emon
  • 360
  • 3
  • 14
  • Hi IR Emon. Thank you for your comment. I did try that approach many times and I cant get that working. I think I am missing something here which I cant figure out. I don't have a problem to make button and text area work together if they belong to one class but when they are in different classes it is a problem. – Przemek Sep 25 '17 at 11:40
  • Presumably the OP wants to change the text in the existing text area, not call the method on an arbitrary new instance of the controller class. – James_D Sep 25 '17 at 11:54