How to bind controls across two fxml from the Main

2019-02-20 14:59发布

I Need to bind controls from different fxml in the main controller. I have 3 fxml files named MainView.fxml, ChildView1.fxml and ChildView2.fxml.

MainView.fxml

<AnchorPane fx:id="view" prefHeight="280.0" prefWidth="500.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="binding.example2.MainViewController">
<children>
<VBox prefHeight="280.0" prefWidth="500.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
  <children>
    <fx:include fx:id="child1" source="ChildView1.fxml" />
    <fx:include fx:id="child2" source="ChildView2.fxml" />
  </children>
</VBox>
</children>
</AnchorPane>

ChildView1.fxml

<AnchorPane fx:id="view" prefHeight="78.0" prefWidth="464.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="binding.example2.ChildView1Controller">
<children>
<HBox layoutX="32.0" layoutY="14.0" prefHeight="51.0" prefWidth="200.0" spacing="10.0">
 <children>
    <Button fx:id="button1" mnemonicParsing="false" prefHeight="37.0" text="Button1" />
    <Button fx:id="button2" mnemonicParsing="false" prefHeight="37.0" text="Button2" />
  </children>
</HBox>
</children>
</AnchorPane>

ChildView2.fxml

<AnchorPane fx:id="view" prefHeight="244.0" prefWidth="568.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="binding.example2.ChildView2Controller">
 <children>
   <TableView fx:id="tableView" prefHeight="244.0" prefWidth="568.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
 </children>
</AnchorPane>

MainController.java

package binding.example2;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.layout.AnchorPane;        
public class MainViewController {
@FXML
private Parent view;
@FXML
private AnchorPane child1;
@FXML
private AnchorPane child2;
@FXML
private ChildView1Controller childView1Controller;
@FXML
private ChildView2Controller childView2Controller; 
@FXML
 void initialize() {
      System.out.println("MainViewController.initialize()");
   // childView1Controller.getButton1() ;
 }

public Parent getView() {
     return view;
  }

}

ChildView1Controller.java

package binding.example2;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;


public class ChildView1Controller {

@FXML private ResourceBundle resources;

@FXML private URL location;

@FXML private Button button1;

@FXML private Button button2;

@FXML private Node view;


@FXML
void initialize() {
    System.out.println("ChildView1Controller.initialize()");

    button1.setDisable(true);

}

 public Node getView()
 {
    return view;
 }

 public Button getButton1(){
    return button1; 
 }

}

ChildView2Controller.java

package binding.example2;


import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;


public class ChildView2Controller {

@FXML private Node view;

@FXML private TableView<Person> tableView;

ObservableList<Person> data ;

public Node getView(){
    return view ;
   }

 @FXML
 void initialize() {
    System.out.println("ChildView2Controller.initialize()");

    //populateTable();
 }

public TableView<Person> getTableView(){
    return tableView ;
}   
 }

By default, button1 is disabled from ChildView1Controller.

I want to enable it when a table row in my other view (ChildView2.fxml) is selected. Again disable it when the table row is deselected. Basically i want to bind the button and table so that button is enabled when a table row is selected. Please help me with the MainViewController code to bind the button and the table row.

标签: javafx-2
1条回答
劫难
2楼-- · 2019-02-20 15:50

You can inject the controllers of the included fxml on the MainViewController controller, as indicated here.

Then, you can perform the desired bindings at MainViewController's initialize method. Considering that the child controllers expose the Button and the TableView with getter methods, the MainViewController could be:

public class MainViewController {
    @FXML
    private ChildView1Controller childView1Controller;
    @FXML
    private ChildView2Controller childView2Controller;

    @FXML
    public void initialize() {
        childView1Controller.getButton1().visibleProperty().bind(
            childView2Controller.getTableView().getSelectionModel().selectedItemProperty().isNotNull());
    }
}

To correctly inject these child controllers, it is needed to change the include elements at MainView.fxml, updating their fx:id attribute:

<fx:include fx:id="childView1" source="ChildView1.fxml" />
<fx:include fx:id="childView2" source="ChildView2.fxml" />

Relevant comment from @Dil:

The requirement is that if the fx:id of your included resource is "xxx", the variable name for the corresponding controller is xxxController (so details -> detailsController)

查看更多
登录 后发表回答