在一个主FXML中具有多个控制器的多个XML

时间:2015-03-30 14:10:04

标签: java javafx javafx-8 fxml scenebuilder

最近我开始学习JavaFX,现在有些事情困扰着我,我无法找到解决我的“问题”的方法。我已经找到类似的问题和几个解决我的问题的解决方案,但我找不到一个对我有用或只是我做错了什么。我想要做的是有一个主要的FXML文件与自己的FXML控制器类。然后我想在主FXML中添加(导入)其他FXML文件,这些文件也有控制器。我尝试了几件事,但没有任何效果,所以我决定描述我在做什么。首先,我使用Scene Builder创建主FXML文件,然后我为主FXML创建Controller。然后我在Scene Builder中设置主FXML的控制器类作为主控制器(当然......)。在那之后,我对第二个FXML做了同样的事情。然后我试图将第二个FXML导入主FXML并且它工作正常,如果我没有为第二个FXML设置控制器。如果我在将第二个FXML导入到主FXML之前选择了第二个FXML的控制器,我仍然可以导入FXML文件并保存它,但在我尝试运行程序后,我收到错误。所以基本上我要做的就是在一个Main FXML文件中有多个带有自己控制器的FXML文件,这个文件也有一个Controller类。我不完全确定这是可能的,所以请告诉我这是可能的,如果可能的话,我做错了什么。这是我的代码:

public class MainSceneController implements Initializable {

@FXML 
private TextField mainTxtField;

public MainSceneController() { 
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("MainScene.fxml"));
fxmlLoader.setController(this);
fxmlLoader.setRoot(this);

    try { 
        fxmlLoader.load();
    } catch (IOException exc) { 
        } }
@FXML
public void buttonActionMethod(ActionEvent event) { 
    mainTxtField.setText("Button1 is clicked");
}

@Override
public void initialize(URL location, ResourceBundle resources) {    
} }

我调用了第二个FXML和第二个控制器LeftScene和LeftSceneController,所以这里是第二个控制器的代码:

public class LeftSceneController implements Initializable {

@FXML
private TextField leftTxtField;

public LeftSceneController() { 
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("MainScene.fxml"));
    fxmlLoader.setController(this);
    fxmlLoader.setRoot(this);

        try { 
            fxmlLoader.load();
        } catch (IOException exc) { 
            }
}
@FXML 
public void button2Action(ActionEvent event) { 
    leftTxtField.setText("Button 2 is clicked");
}

@Override
public void initialize(URL location, ResourceBundle resources) {    
} }

最后,这是MainClass,其中主要方法和启动方法:

public class MainClass extends Application {

public static void main(String[] args) { 
    launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("MainScene.fxml"));
    Scene scene = new Scene(root);
    primaryStage.setScene(scene);
    primaryStage.setTitle("Multiple FXMLs in one");
    primaryStage.show();
} }

我希望你能得到我想做的事。正如我所说,我已经尝试了很多东西,但没有一个能按照我的意愿行事。这个版本正在编译并且正在运行,如果我在导入之前没有为第二个FXML设置控制器类,但正如您所料,导入的FXML中的第二个按钮没有做任何事情。我会发布截图,如果可以的话,但我是新来的,通常我只是在阅读,所以我不允许发布截图。我也尝试发布我的FXML代码,但是我遇到了系统问题,我无法发布多行代码。

所以...是否有可能让我的工作方式与否?

如果你读完所有这些烂摊子,至少谢谢你的时间! :)

1 个答案:

答案 0 :(得分:6)

已经有一段时间了,但最后我找到了答案。我在YouTube上发现了this视频,它正好显示了我需要的内容。虽然我一步一步地从视频中做了一些事情,但我发现了一些问题。

首先,如果我将另一个FXML文件导入到主FXML中,就像在本教程中一样,SceneBuilder正在导入FXML,就像导入的FXML中的东西在主FXML中一样,这会导致问题。我的意思是,例如,如果您在导入的FXML中有一个Button,当您使用SceneBuilder在主FXML中导入它时,导入的Button会出现在主FXML中,就像一个新的Button,包含所有信息(postion,onClickMethod,并且它不是应该如何。这会导致错误,因为Java正在为主控制器中的导入按钮而不是导入的FXML的Controller中查找onClickMethod。我不知道为什么它与我不同,它不像视频,但解决方案很简单。如果要将FXML文件导入另一个FXML,您应该使用编辑器进行操作,只需在主FXML的内容中添加以下行:

<fx:include fx:id="importedFXML" source="ImportedFXML.fxml" />

在这种情况下,重要的是fx:id应与.FXML文件同名,但首字母小。

另一件事,在视频中显示并导致我的问题是,如果你想要一个多个导入的FXML文件,你希望他们相互通信。该视频展示了如何做到这一点,但没有提到您必须在MainController中创建的导入FXML文件的Controller对象必须具有相同的名称,如fx:id +单词Controller。例如,使用上面的fx:id,对象应如下所示:

@FXML private ImportedFXMLController importedFXMLController 

如果ImportedFXMLController是importedFXML的控制器

所以,我希望这会对某人有所帮助。