如何从JavaFX中的另一个控制器类访问UI元素? [英] How do I access a UI element from another controller class in JavaFX?

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

问题描述

我有一个用NetBeans 8编写的JavaFX / Java 8应用程序(没有 SceneBuilder )。

I have a JavaFX / Java 8 application written with NetBeans 8 (no SceneBuilder).

我的应用程序有一个主窗口,它有自己的FXML文件(primary.fxml)和自己的控制器类(FXMLPrimaryController.java)。 FXML中的一个项目是 TextArea 。 FXMLPrimaryController.java中的一些方法是附加到 TextArea

My application has a main window that has its own FXML file (primary.fxml) and its own controller class (FXMLPrimaryController.java). One of the items in the FXML is a TextArea. Some of the methods in FXMLPrimaryController.java are about appending to that TextArea.

此应用程序现在生成第二个窗口(另一个阶段)有自己的FXML(second.fxml)和自己的控制器类(FXMLsecondController.java)。

This application now spawns a second window (another "stage") with its own FXML (second.fxml) and its own controller class (FXMLsecondController.java).

在第二个控制器类中,我怎么能访问主要的TextArea?

Within the second controller class, how can I access the TextArea in the primary?

以下是相关代码的示例:

Here's a sample of the relevant code:

primary.fxml:

primary.fxml:

<Button text="press me!" onAction="#openSecondWindow" />
<TextArea fx:id="myArea" />

FXMLPrimaryController.java:

FXMLPrimaryController.java:

public class FXMLPrimaryController implements Initializable {

    @Override
    public void initialize(URL url, ResourceBundle rb) {
    }

    @FXML private TextArea myArea;

    final public void writeToTextArea() {
        myArea.appendText("hi!");
    }

    @FXML
    private void openSecondWindow(ActionEvent event) throws Exception {

        Group root = new Group();
        Stage stage = new Stage();

        AnchorPane frame = FXMLLoader.load(getClass().getResource("second.fxml"));
        root.getChildren().add(frame);
        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();
    }

}

第二个没什么特别的。 FXML。假设有一个按钮 onAction =#writeSomething

There is nothing fancy about second.fxml. Assume there is a button with onAction="#writeSomething".

在FXMLsecondController.java中,我想要一个引用上述 TextArea 的函数。

In FXMLsecondController.java, I would like a function that references the above TextArea.

推荐答案

加载FXML时对于辅助控制器,执行以下操作:

When you load the FXML for the secondary controller, do this:

FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("second.fxml"));
AnchorPane frame = fxmlLoader.load();
FXMLSecondaryController c = (FXMLSecondaryController) fxmlLoader.getController();

然后你可以将引用传递给第二个控制器。这可能只是TextArea。

Then you can pass references to the second controller. This could just be the TextArea.

编辑:

替换 load() 在上面的代码段中调用并添加 setLocation()调用。旧行 AnchorPane frame = fxmlLoader.load(getClass()。getResource(second.fxml)); 错误,因为它调用静态加载功能,这里没用。

Replaced the load() call in the snippet above and added the setLocation() call. The old line AnchorPane frame = fxmlLoader.load(getClass().getResource("second.fxml")); was wrong as it called the static load function, which is useless here.

编辑:

(更改了上面的代码片段可以更好地匹配您的变量名称。)
上面的代码片段替换了这部分代码:

(Changed the code snippet above to better match your variable names.) The code snippet above replaces this part of your code:

AnchorPane frame = FXMLLoader.load(getClass().getResource("second.fxml"));

该行使用FXMLLoader加载视图并创建控制器实例 - 在这种情况下 FXMLSecondaryController 。但是,你不能使用静态 FXMLLoader.load 方法,你需要一个 FXMLLoader 的实例。该实例在加载后保存对控制器的引用,您可以使用 getController()检索它。并且您需要将返回的值强制转换为控制器类(使用(FXMLSecondaryController))。

That line uses the FXMLLoader to load the view and also creates the instance of the controller - in this case FXMLSecondaryController. However, you cannot use the static FXMLLoader.load method for that, you need an instance of FXMLLoader. That instance holds a reference to the controller after load and you can retrieve that with getController(). And you need to cast the returned value to your controller class (with (FXMLSecondaryController)).

您的主控制器有一个字段:

Your primary controller has a field:

@FXML private TextArea myArea;

这包含对 TextArea 的引用,由fxml加载器初始化。 (如果删除 @FXML 注释,加载程序将不会触及它。)

This holds a reference to your TextArea and is initialized by the fxml loader. (If you remove the @FXML annotation, the loader won't touch it.)

在辅助控制器中,添加以下字段:

In your secondary controller, add this field:

public TextArea primaryTextArea;

请注意 @FXML 已消失( fxml加载器不应该触及字段)以及 private (你想设置字段,因此其他人必须看到它)。
现在您可以在加载控制器后设置此字段。所以回到加载代码:

Note that @FXML is gone (the fxml loader shall not touch the field) as well as private (you want to set the field, hence others must see it). Now you can set this field after the controller has been loaded. So back to the loading code:

FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("second.fxml"));
AnchorPane frame = fxmlLoader.load();
FXMLSecondaryController c = (FXMLSecondaryController) fxmlLoader.getController();
// Add this too:
c.primaryTextArea = myArea;

编辑:替换 load()来电在上面的代码段中,添加了 setLocation()调用。旧行 AnchorPane frame = fxmlLoader.load(getClass()。getResource(second.fxml)); 错误,因为它调用静态加载函数,这里没用。

Replaced the load() call in the snippet above and added the setLocation() call. The old line AnchorPane frame = fxmlLoader.load(getClass().getResource("second.fxml")); was wrong as it called the static load function, which is useless here.

FXMLSecondaryController 现在有一个引用主控制器的 TextArea 。在其中一种方法中,您应该能够访问其内容:

The FXMLSecondaryController now has a reference to the TextArea of the primary controller. In one of its methods you should be able to access its content:

public class FXMLSecondaryController implements Initializable {
    // ...

    public TextArea primaryTextArea;

    // ...

    @FXML
    private void doSomething(ActionEvent event) throws Exception {
        primaryTextArea.appendText("Hi ho!");
    }

}

请注意,此解决方案不是最好的方法,但它很简单,可以作为一个开始。当然建议使用绑定。我会尝试创建一个包含数据的类,其他控制器绑定在该类上。但是如果你现在采用简单的方法,那就足够了。

Note that this solution is not the best approach, but it is simple and can serve as a start. Using binding is certainly recommended. I would try to create a class which holds the data and on which the other controllers bind. But if you take the simple approach for now, it should be sufficient.

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

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