如何将FXML Controller1中创build的对象传递给内部FXML控件的Controller2
我有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的button时,在其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。
在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>
通过这个,你创build了一个新的控件,你可以使用它作为普通的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 />
我使用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”。 也许它会自动调用控制器。