如何从 JavaFX 中的另一个控制器类访问 UI 元素?

2024-05-16

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

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

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

在第二个控制器类中,如何访问主控制器中的 TextArea?

这是相关代码的示例:

主要.fxml:

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

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

}

Second.fxml 没有什么特别之处。假设有一个按钮onAction="#writeSomething".

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


当您加载辅助控制器的 FXML 时,请执行以下操作:

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

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

EDIT:

更换了load()调用上面的代码片段并添加setLocation()称呼。旧线AnchorPane frame = fxmlLoader.load(getClass().getResource("second.fxml"));是错误的,因为它称为静态load函数,这里没用。

EDIT:

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

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

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

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

@FXML private TextArea myArea;

这包含对您的参考TextArea并由 fxml 加载器初始化。 (如果您删除@FXML注解,加载器不会碰它。)

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

public TextArea primaryTextArea;

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

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"));是错误的,因为它称为静态load函数,这里没用。

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

public class FXMLSecondaryController implements Initializable {
    // ...

    public TextArea primaryTextArea;

    // ...

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

}

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 JavaFX 中的另一个控制器类访问 UI 元素? 的相关文章

随机推荐