[英]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.