2

I'm writing small application using JavaFX but I stuck with one problem.

I have fxml files:

MainPane.fxml
Stream.fxml
Play.fxml

and each of them has its own controller:

MainPaneController.java
StreamController.java
PlayController.java

Where in MainPane is:

<GridPane fx:controller="model.MainController" fx:id="mainGrid"
    xmlns:fx="http://javafx.com/fxml" alignment="CENTER" gridLinesVisible="true">

    <children>
        <fx:include source="Stream.fxml"/>
    </children>

    <children>
        <fx:include source="Play.fxml"/>
    </children>
</GridPane>

Play.fxml has this field:

<TextField fx:id="searchField" text="Search" onAction="#search"/>

now when action (enter button) if fired I want to access and change a label in Stream.fxml as follows:

public class PlayController implements Initializable {

    @FXML
    private TextField searchField;

    @FXML
    protected void search() {
        System.out.println("Search");
        String text = searchField.getText();
        //how to access Label in StreamController
    }
}

I would like to avoid binding like

MainPaneController <-> StreamController
MainController <-> PlayController

and access fields like:

mainController.getStreamController.changeLabel(text)

because I hope there is some better way to do this.

swch
  • 1,432
  • 4
  • 21
  • 37

2 Answers2

4

Expose properties in the "nested" controllers StreamController and PlayController. Those controllers can bind the properties to the UI components they define as needed.

Then inject the nested controllers into MainController as described in the Nested Controllers section of the Introduction to FXML.

Update: Here's a more similar example, where the interacting controllers are both included in a common FXML.

James_D
  • 201,275
  • 16
  • 291
  • 322
  • As I understand in Your example there is a situation where You access fields from Child Controller (PersonEditorController class) in Root controller (MainController class). In my case there is different situation, because I want access fields from Controller that has no relation with this second Controller (they are both children of another fxml - there is no fx:include between them) – swch Apr 14 '14 at 18:16
  • Just expose properties in both "sibling" controllers and bind them together in the "parent" controller. – James_D Apr 14 '14 at 18:20
  • Updated in case anyone else came across this and was looking to do something similar. – James_D Apr 14 '14 at 19:30
  • I have one more question and maybe You know the answer. Now I have binding between label.textProperty and textField.textProperty. When I type something in text field, label is changing simultaneously. Is it possible to bind these values so label changes only after calling onAction (press enter) in textField? – swch Apr 14 '14 at 19:39
  • In general, when you have a new question, post a new one. In this case, see [this question](http://stackoverflow.com/questions/23058980/javafx-binding-between-textfield-and-a-property/23060020#23060020) – James_D Apr 14 '14 at 19:41
0

You need to send your Fxmlloader from controller to other ,i mean create a method in playController to get your fxmloader from StreamController.

public class PlayController implements Initializable {

pulic StreamController stream;
@FXML
private TextField searchField;

@FXML
protected void search() {
    System.out.println("Search");
    String text = searchField.getText();
   //how to access Label in StreamControlle
    stream._yourLabeL ....

}
public StreamController StreamController(){
      return stream;
} 
public StreamController setStreamController(StreamController streamController){
      stream=streamController
}

and in class that contain fxml loader add this line

StreamController streamcontroller=myStreamFxml.getController();
 new PlayController().setStreamController(streamController);