使用JavaFX打开多个窗口

我正在尝试使用JavaFX打开多个窗口,我有一个eventlistener,当单击一个按钮时会打开一个新窗口,它看起来像这样:

@FXML private void joinAction() { Parent root; try { Stage stage = (Stage) joinButton.getScene().getWindow(); stage.close(); root = FXMLLoader.load(getClass().getResource("main.fxml")); stage = new Stage(); stage.setTitle("TuneUs"); stage.setScene(new Scene(root)); stage.show(); } catch (IOException e) {e.printStackTrace();} } 

第一个窗口打开,新窗口打开,但我的问题是让事件与我的第二个窗口一起工作

main.fxml我有这一行:

  

然后在我的控制器类中我有这个方法:

 @FXML private void sendChat() { System.out.println("test"); } 

但是Intellij告诉我的是; 没有为顶级元素指定控制器

所以,我的问题是:我是否需要创建多个控制器类,或者我可以只使用一个用于多个窗口,如果是这样的话?

推荐的方法是为每个FXML定义一个控制器。 由于控制器非常轻巧,因此不应增加太多开销。 main.fxml文件的控制器可能很简单

 import javafx.fxml.FXML ; public class MainController { @FXML private void sendChat() { // ... } } 

我在单个项目中使用了相当大量的FXML文件和相应的控制器这种方法,并且在管理代码等方面没有任何问题。我建议使用Main.fxml <-> MainControllerforms的命名约定。

如果您的控制器需要共享数据,请使用传递参数JavaFX FXML中概述的技术

正如@Vertex在评论中指出的那样, FXMLLoader.setController(...)方法提供了另一种方法。 所以在上面的例子中,你可以做到

 @FXML private void joinAction() { Parent root; try { Stage stage = (Stage) joinButton.getScene().getWindow(); stage.close(); FXMLLoader loader = new FXMLLoader (getClass().getResource("main.fxml")); loader.setController(this); root = loader.load(); stage = new Stage(); stage.setTitle("TuneUs"); stage.setScene(new Scene(root)); stage.show(); } catch (IOException e) {e.printStackTrace();} } @FXML private void sendChat() { // ... } 

如果你没有通过FXML注入设置任何字段(控件)(即在fxml中使用fx:id属性并在控制器中使用相应的@FXML注释),这种方法@FXML 。 如果是,那么很难跟踪这些字段的设置时间。 此外,如果多次调用joinAction处理程序,您将拥有main.fxml创建的节点的多个实例,但所有实例共享一个控制器实例(并因此覆盖相同的注入字段)。 另请注意,使用此方法时,将在加载原始fxml文件时以及加载main.fxml文件时调用initialize()方法,这几乎肯定会导致意外的影响。

最后一点:如果您有许多FXML文件和相应的控制器,您可能需要查看afterburner.fx框架 。 这是一个非常轻量级的框架,它要求FXML文件及其相应控制器的命名约定,并且还提供了一种(非常)简单的机制,用于在它们之间共享数据。

您需要添加顶级元素fx:controller。 看看这个答案: https : //stackoverflow.com/a/41316536/4247308