首页 文章

如何将FXML Controller1中创建的对象传递给内部FXML控件的Controller2

提问于
浏览
13

我有JavaFX 2.0应用程序,它由两个FXML文件和2个控制器组成,它们是一个“主”.java文件 .

在开始时,FXML1被初始化,如下所示:

public void start(Stage stage) throws Exception {
    stage.setTitle("Demo Jabber JavaFX Chat");

    Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml"),
        ResourceBundle.getBundle("fxmlexample.fxml_example"));        
    Scene scene = new Scene(root, 226, 264);
    stage.setScene(scene);
    scene.getStylesheets().add("fxmlexample/fxmlstylesheet.css");
    stage.show();
}

然后,当单击来自scene1的按钮时,在Controller1类的事件处理程序中,我更改scene1 root,以显示用户的新gui-view . 在这个控制器中我初始化了一些对象 . 例如这样:

public class FXMLExampleController {
   //some fields...
   private MySuperObject c;
   @FXML protected void handleSubmitButtonAction(ActionEvent event) {
    //some fields...
    c = new MySuperObject(); //here i initialize my object, i'm interested in
    try {
        c.login(username, password); // some actions with this object, which i need to make.
        Scene cc = buttonStatusText.getScene();
        Parent root = null;
        try {
            //changing a scene content...
            root = FXMLLoader.load(getClass().getResource("fxml_example2.fxml"),
            ResourceBundle.getBundle("fxmlexample.fxml_example"));
        } catch (IOException ex) {
            Logger.getLogger(FXMLExampleController.class.getName()).log(Level.SEVERE, null, ex);
        }
        cc.setRoot(root);
      }

之后,我必须在下一个场景中对该对象进行一些处理,并且它必须不是同一个类的新实例,而是对象,我已经在第一个场景上初始化了 .

我理解如何使用“标准java”来完成所有这些,但我对使用JavaFX FXML的这项任务感到困惑 .

2 回答

  • 25

    在FX 2.2中引入了用于控制器节点的新API:

    // create class which is both controller and node
    public class InnerFxmlControl extends HBox implements Initializable {
      @FXML public ComboBox cb;
    
      public InnerFxmlControl () {
         FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxml_example2.fxml"));
         fxmlLoader.setRoot(this);
         fxmlLoader.setController(this);
         try {
             fxmlLoader.load();            
         } catch (IOException exception) {
             throw new RuntimeException(exception);
         }
      }
    

    使用下一个fxml(注释标签 fx:root ):

    <fx:root type="javafx.scene.layout.HBox" xmlns:fx="http://javafx.com/fxml">
      <children>
        <ComboBox fx:id="cb" />
      </children>
    </fx:root>
    

    通过这个,您创建了一个新控件,您可以将其用作常规JavaFX控件 . 例如 . 在你的情况下:

    @FXML protected void handleSubmitButtonAction(ActionEvent event) {
        // you just create new control, all fxml tricks are encapsulated
        InnerFxmlControl root = new InnerFxmlControl();
        // and you can access all its' methods and fields including matched by @FXML tag:
        root.cb.getItems().add("new item");
    
        Scene cc = buttonStatusText.getScene();
        cc.setRoot(root);
      }
    

    并在fxml中:

    <InnerFxmlControl />
    
  • 3

    我正在使用1.7.0_21,它现在可以像这样编码:在主应用程序fxml文件中,

    <VBox ...>
          <fx:include fx:id="tom" source="Tom.fxml" />
    </VBox>
    

    并且包含的fxml可以定义它自己的fxml文件,如下所示:

    <AnchorPane id="AnchorPane" fx:id="tomPan" ... xmlns:fx="http://javafx.com/fxml" fx:controller="**com.tom.fx.TomController**">
    

    然后,在主应用程序中,控制器需要“Tom.fxml”的控制器,如下所示:

    @FXML private TomController tomController;
    

    注意“@FXML” . 也许它会自动调用控制器 .

相关问题