我是使用JavaFX的新手,并且在使用带有FXML的JavaFX时遇到了一些麻烦。我正在使用" Setup"创建一个程序。单击按钮,打开一个带有连接(到Arduino)设置的新窗口。在菜单上是另一个连接到电路板的按钮(" Connect")。这关闭了窗口。我希望将此更改原始"设置"按钮到"断开"但是,我似乎无法从"设置窗口"访问该按钮。每当我点击" connect"我收到以下错误:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
我在网上读到这是一个空指针异常的包装器。我假设"设置"按钮为空,这就是为什么我无法改变它,但我无法解决原因。
以下是MainController.java的摘录:
@FXML
protected void setUpConnection(ActionEvent e) {
SetupController setupController = new SetupController();
setupController.init(this);
}
当"设置"单击按钮(在文件中设置:setupMenu.fxml)。然后打开单独的窗口。以下是SetupController.java中打开窗口的代码:
private void openSetupWindow() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("setupMenu.fxml"));
Parent root1 = (Parent)loader.load();
Stage stage = new Stage();
stage.setTitle("Setup Connection");
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception exc) {
exc.printStackTrace();
}
}
单击连接按钮时,将调用以下方法(在SetupController.java中):
private void changeButtonText(ConnectionEventType e) {
Button b = main.getSetupButton();
if(e == ConnectionEventType.CONNECT) {
b.setText("Disconnect");
}
else {
b.setText("Setup Connection...");
}
}
(main是传入setupController.init()的MainController对象) 上面的代码是我收到错误的地方。 为了澄清,我有2个单独的fxml文件,一个用于主窗口,另一个用于弹出窗口。 sample.fxml(主窗口)将其控制器设置为MainController,并在Main.java(下面)中设置:
@Override
public void start(Stage primaryStage) throws Exception{
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
GridPane root = loader.load();
Scene scene = new Scene(root, 1200, 900);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setTitle("Nest Control");
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
我是否试图错误地访问按钮?有人能帮忙吗?就像我说的,我在使用JavaFX或FXML方面没有多少经验。
答案 0 :(得分:0)
我认为您正在寻找的答案是为您打开的每个窗口存储控制器,以便您可以访问控制器中的变量,但是如果没有其余的代码则很难为您提供建议,但这是一个示例我的意思是:
private SetupController yourController;
@Override
public void start(Stage primaryStage) throws Exception{
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
GridPane root = loader.load();
this.yourController=loader.<SetupController>getController();
Scene scene = new Scene(root, 1200, 900);
}
}
然后,您可以以模型 - 视图 - 控制器类型的方式将变量yourController传递给其他实例并访问其方法。
在您的情况下或类似的事情:
private void changeButtonText(ConnectionEventType e) {
Button b = this.yourController.getButton(); //a method that returns your @FXML button object in your controller
if(e == ConnectionEventType.CONNECT) {
b.setText("Disconnect");
}
else {
b.setText("Setup Connection...");
}
}
或者在控制器中有一个特定的方法,它将设置按钮的文本,而不必返回按钮对象。
但请注意,您获得的错误似乎通常归因于缺少@FXML注释,因此可能确保在此实例中您还注释了所有控制器中的所有变量。有关详细信息,请参阅here。