【问题标题】:Mutiple FXMLs with multiple controllers in one Main FXML在一个主 FXML 中具有多个控制器的多个 FXML
【发布时间】:2015-06-03 14:23:06
【问题描述】:

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

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,其中有 main 方法和 start 方法:

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 代码,但我遇到了系统问题,我不能发布超过一行的代码。

那么……是否有可能按照我的意愿进行这项工作?

如果您阅读了所有这些乱七八糟的内容,请至少感谢您的宝贵时间! :)

【问题讨论】:

  • 为什么要在控制器中加载主场景?你读过Nested Controllers section of the FXML documentation?
  • 是的,我已经阅读了嵌套控制器部分,这就是我在两个控制器中都有构造函数的原因。我的想法是在主控制器中使用第二个控制器(LeftSceneController)对象,这样我就可以使用第二个控制器。这就是第二个控制器加载场景的原因,但可能这不是一个好主意或做得不对...
  • 为什么不按照文档中的方式进行操作?
  • 我想我找到了问题所在。我再次尝试了文档中的方法,但这次不是使用 SceenBuilder 将第二个 FXML 导入到主 FXML,而是通过在 FXML 文件中添加 手动完成,并且工作正常。现在的问题是,当我使用 SceneBuilder 打开主 FXML 时,我什至无法更改导入的 FXML 文件的位置,所以我必须通过在编辑器中打开代码来手动完成。现在我只需要找出是我在使用 SceneBuilder 时做错了什么还是只是一个错误。
  • 我没有意识到您正在使用 SceneBuilder。我很确定 SceneBuilder 不支持 <fx:include>

标签: java javafx javafx-8 fxml scenebuilder


【解决方案1】:

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

首先,如果我将另一个 FXML 文件导入到主 FXML 中,就像在本教程中一样,SceneBuilder 正在导入 FXML,就像导入的 FXML 中的内容在主 FXML 中一样,这会导致问题。我的意思是,例如,如果您在导入的 FXML 中有一个 Button,当您使用 SceneBuilder 将其导入主 FXML 时,导入的 Button 会出现在主 FXML 中,就像一个带有所有信息的新 Button(位置、onClickMethod、等),这不是它应该是的样子。这会导致错误,因为 Java 在主控制器中而不是在导入的 FXML 的控制器中寻找导入按钮的 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 的控制器

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

【讨论】:

    猜你喜欢
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    相关资源
    最近更新 更多