JavaFX - 如何从另一个控制器使用控制器中的方法? [英] JavaFX - How to use a method in a controller from another controller?

查看:84
本文介绍了JavaFX - 如何从另一个控制器使用控制器中的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 SceneBuilder.我有 2 个阶段,每个阶段都有一个控制器:
stage1Controller,
stage2Controller.
Stage1Controller :

Working with SceneBuilder. I have 2 stages, each one with a controller:
stage1Controller,
stage2Controller.
Stage1Controller :

public class Stage1Controller {
    @FXML
    private MenuItem translate;
    @FXML
    private Menu file;
    @FXML
    private Menu edit;
    @FXML
    private Menu help;


    @FXML 
    private void handleTranslate (ActionEvent event){
        translateFirstStage();
        //HOW TO ACCESS THE stage2Controller setLabel()??
    }

    private void translateFirstStage(){
        file.setText("Fichier");
        edit.setText("Modifier");
        help.setText("Aide");
    }
}

Stage2Controller:

public class Stage2Controller {
    @FXML
    private Label lb;


    private void setLabel(String string){
        lb.setText("string");
    }
}

以下是使用两种方法在 Main.java 类中加载两个 fxml 文件的方法
(在 Start(Stage primaryStage) 方法中调用):

Here is how both fxml files are loaded in Main.java class using 2 methods
(called in Start(Stage primaryStage) method):

public void firstStage() {
        try {
            // Load root layout from fxml file.
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(Main.class.getResource("view/stage1.fxml"));
            rootLayout = (BorderPane) loader.load();

            // Show the scene containing the root layout.
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void secondStage() {

        try {
            // Load root layout from fxml file.
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(Main.class.getResource("view/stage2.fxml"));
            XD = (AnchorPane) loader.load();

            // Show the scene containing the root layout.
            Scene scene = new Scene(XD);
            Stage stage = new Stage();
            stage.setScene(scene);
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

  • handleTranslate(ActionEvent event) 方法用作第一个 Stage 中 MenuItem translateOnAction 方法,它转换视图在两个阶段.
    • The handleTranslate(ActionEvent event) method is used as an OnAction method for the MenuItem translate in the first Stage, it translates the view in both stages.
    • 如何将 setLabel 放入 handleTranslate 方法中?谢谢

      How Can i put setLabel in handleTranslate Method ? Thanks

      推荐答案

      又快又脏"的方法是给 Stage1Controller 一个对 Stage2Controller 的引用:

      The "quick and dirty" way is to give the Stage1Controller a reference to the Stage2Controller:

      public class Stage1Controller {
      
          private final Stage2Controller stage2Controller ;
      
          public void setStage2Controller(Stage2Controller stage2Controller) {
              this.stage2Controller = stage2Controller ;
          }
      
          // ...
      
          @FXML 
          private void handleTranslate (ActionEvent event){
              translateFirstStage();
              stage2Controller.setLabel(...);
          }
      
          // other code as before ...
      }
      

      现在在您的主应用中:

      public class MainApp  extends Application {
      
          private Stage1Controller stage1Controller ;
          private Stage2Controller stage2Controller ;
      
          @Override
          public void start(Stage primaryStage) {
              firstStage();
              secondStage();
      
              stage1Controller.setStage2Controller(stage2Controller);
      
              // ...
          }
      
          public void firstStage() {
              try {
                  // Load root layout from fxml file.
                  FXMLLoader loader = new FXMLLoader();
                  loader.setLocation(Main.class.getResource("view/stage1.fxml"));
                  rootLayout = (BorderPane) loader.load();
      
                  stage1Controller = loader.getController();
      
                  // Show the scene containing the root layout.
                  Scene scene = new Scene(rootLayout);
                  primaryStage.setScene(scene);
                  primaryStage.show();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
          public void secondStage() {
      
              try {
                  // Load root layout from fxml file.
                  FXMLLoader loader = new FXMLLoader();
                  loader.setLocation(Main.class.getResource("view/stage2.fxml"));
                  XD = (AnchorPane) loader.load();
      
                  stage2Controller = loader.getController();
      
                  // Show the scene containing the root layout.
                  Scene scene = new Scene(XD);
                  Stage stage = new Stage();
                  stage.setScene(scene);
                  stage.show();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
          // ...
      }
      

      不过,一个更健壮的方法是让两个控制器访问共享模型类,存储数据.如果您使用 JavaFX 可观察属性表示数据,则控制器可以监听他们关心的属性的变化.例如:

      A more robust approach to this, though, is to let both controllers access a shared model class, storing the data. If you represent the data using JavaFX observable properties, the controllers can listen for changes on the properties they care about. For example:

      public class Model {
      
          private final StringProperty text = new SimpleStringProperty("Initial text...");
      
          public StringProperty textProperty() {
              return text ;
          }
      
          public final void setText(String text) {
              textProperty().set(text);
          }
      
          public final String getText() {
              return textProperty().get();
          }
      
          // other properties as needed...
      }
      

      现在您的控制器将如下所示:

      Now your controllers will look like this:

      public class Stage1Controller {
      
          private Model model ;
      
          public void setModel(Model model) {
              this.model = model ;
          }
      
          @FXML 
          private void handleTranslate (ActionEvent event){
              translateFirstStage();
      
              model.setText(...); // value will appear in stage2 controller's label!
          }
      
          // ...
      }
      

      public class Stage2Controller {
      
          @FXML
          private Label lb ;
      
          private Model model ;
      
          public void setModel(Model model) {
              lb.textProperty().unbind();
              this.model = model ;
              lb.textProperty().bind(model.textProperty());
          }
      
          // ...
      }
      

      在这种情况下,您的主应用程序如下所示:

      And in this case your main app looks like:

      public class MainApp extends Application {
      
          private final Model = new Model();
      
          @Override
          public void start(Stage primaryStage) {
              // ...
          }
      
          public void firstStage() {
              try {
                  // Load root layout from fxml file.
                  FXMLLoader loader = new FXMLLoader();
                  loader.setLocation(Main.class.getResource("view/stage1.fxml"));
                  rootLayout = (BorderPane) loader.load();
      
                  Stage1Controller controller = loader.getController();
                  controller.setModel(model);
      
                  // Show the scene containing the root layout.
                  Scene scene = new Scene(rootLayout);
                  primaryStage.setScene(scene);
                  primaryStage.show();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
          public void secondStage() {
      
              try {
                  // Load root layout from fxml file.
                  FXMLLoader loader = new FXMLLoader();
                  loader.setLocation(Main.class.getResource("view/stage2.fxml"));
                  XD = (AnchorPane) loader.load();
      
                  Stage2Controller controller = loader.getController();
                  controller.setModel(model);
      
                  // Show the scene containing the root layout.
                  Scene scene = new Scene(XD);
                  Stage stage = new Stage();
                  stage.setScene(scene);
                  stage.show();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      

      这篇关于JavaFX - 如何从另一个控制器使用控制器中的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆