繁体   English   中英

使用 JavaFX 打开多个窗口

[英]Opening multiple windows with JavaFX

我正在尝试使用 JavaFX 打开多个窗口,我有一个事件监听器,当单击按钮时会打开一个新窗口,如下所示:

@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我有这一行:

<TextField id="chat_bar" onAction="#sendChat" layoutX="14.0" layoutY="106.0" prefHeight="22.0" prefWidth="403.0"/>

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

@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 <-> MainController形式的命名约定。

如果您的控制器需要共享数据,请使用传递参数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注释),则此方法很好。 如果是,那么很难跟踪这些字段的设置时间。 此外,如果多次调用joinAction处理程序,您将拥有main.fxml创建的节点的多个实例,但所有实例共享一个控制器实例(并因此覆盖相同的注入字段)。 还要注意的是这种方法,您initialize()方法将被调用时, 双方原有的FXML文件被加载加载main.fxml文件时,它几乎肯定会产生意外效果。

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

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

我创建了 Borderpane,在它里面左边的 vbox 和中心的场景,还实现了 initializable 。 每次我单击 vbox 中的 diff 按钮时,它只会改变场景。 对于每个场景,我都会创建 scene.fxml 文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM