如何从另一个窗口(JavaFX + FXML)更改按钮中的文本?

时间:2016-07-13 16:42:39

标签: java javafx fxml

我是使用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方面没有多少经验。

1 个答案:

答案 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...");
      }
   }

或者在控制器中有一个特定的方法,它将设置按钮的文本,而不必返回按钮对象。

参见示例herehere

但请注意,您获得的错误似乎通常归因于缺少@FXML注释,因此可能确保在此实例中您还注释了所有控制器中的所有变量。有关详细信息,请参阅here