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

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

问题描述

使用SceneBuilder。我有两个阶段,每个阶段都有一个控制器:stage1Controller,stage2Controller。

Stage1Controller:

  class Stage1Controller {
@FXML
private MenuItem translate;
@FXML
私人菜单文件;
@FXML
私人菜单编辑;
@FXML
private菜单帮助;


@FXML
private void handleTranslate(ActionEvent event){
translateFirstStage();
//如何访问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中加载fxml文件。 java类使用2种方法(在Start(Stage primaryStage)方法中调用):

  public void firstStage(){
try {
//从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage1.fxml));
rootLayout =(BorderPane)loader.load();

//显示包含根布局的场景。
场景scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch(IOException e){
e.printStackTrace();
}
}

public void secondStage(){

try {
//从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage2.fxml));
XD =(AnchorPane)loader.load();

//显示包含根布局的场景。
场景scene =新场景(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch(IOException e){
e.printStackTrace();
}
}




  • handleTranslate事件)方法用作第一阶段中的MenuItem翻译的OnAction方法,它在两个阶段翻译视图。



如何将setLabel放在handleTranslate方法中?谢谢 快速和脏的方式是给予 Stage1Controller 引用 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(...);
}

//其他代码如前...
}


b $ b

现在在您的主要应用程式:

  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 {
//从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage1.fxml));
rootLayout =(BorderPane)loader.load();

stage1Controller = loader.getController();

//显示包含根布局的场景。
场景scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch(IOException e){
e.printStackTrace();
}
}

public void secondStage(){

try {
//从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage2.fxml));
XD =(AnchorPane)loader.load();

stage2Controller = loader.getController();

//显示包含根布局的场景。
场景scene =新场景(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch(IOException e){
e.printStackTrace();
}
}

// ...
}

一个更可靠的方法是,让两个控制器访问共享模型类,存储数据。如果使用JavaFX observable属性表示数据,控制器可以监听他们关心的属性的更改。例如:

  public class Model {

private final StringProperty text = new SimpleStringProperty ...);

public StringProperty textProperty(){
return text;
}

public final void setText(String text){
textProperty()。set(text);
}

public final String getText(){
return textProperty()。get();
}

//所需的其他属性...
}


b $ b

现在你的控制器看起来像这样:

  public class Stage1Controller {

私人模型模型;

public void setModel(Model model){
this.model = model;
}

@FXML
private void handleTranslate(ActionEvent event){
translateFirstStage();

model.setText(...); //值将出现在stage2控制器的标签中!
}

// ...
}

  public class Stage2Controller {

@FXML
private Label lb;

私人模型;

public void setModel(Model model){
lb.textProperty()。unbind();
this.model = model;
lb.textProperty()。bind(model.textProperty());
}

// ...
}



<在这种情况下,你的主要应用程序看起来像:

  public class MainApp extends Application {

private final Model = new Model();

@Override
public void start(Stage primaryStage){
// ...
}

public void firstStage
try {
//从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage1.fxml));
rootLayout =(BorderPane)loader.load();

Stage1Controller controller = loader.getController();
controller.setModel(model);

//显示包含根布局的场景。
场景scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch(IOException e){
e.printStackTrace();
}
}

public void secondStage(){

try {
}从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage2.fxml));
XD =(AnchorPane)loader.load();

Stage2Controller controller = loader.getController();
controller.setModel(model);

//显示包含根布局的场景。
场景scene =新场景(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch(IOException e){
e.printStackTrace();
}
}
}


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

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();
        }
    }

  • 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.

How Can i put setLabel in handleTranslate Method ? Thanks

解决方案

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 ...
}

Now in your main app:

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();
        }
    }

    // ...
}

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!
    }

    // ...
}

and

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天全站免登陆