15

我有一个 JavaFX 2.0 应用程序,它由两个 FXML 文件和它们的两个控制器 + 一个“主”.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 根目录,以便为用户显示新的gui 视图。在这个控制器中,我初始化了一些对象。例如,像这样:

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 的这项任务感到有些困惑。

4

2 回答 2

27

在 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 />
于 2012-05-23T11:06:15.533 回答
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" 。也许它会自动调用控制器。

于 2013-06-15T21:50:10.113 回答