如何从JavaFX的内部阶段获取TextField? [英] How can I get TextField from inner stage in JavaFX?

查看:1622
本文介绍了如何从JavaFX的内部阶段获取TextField?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为两个窗户/舞台编写了一个控制器。
第一个窗口在MainClass中打开。如果用户点击按钮,则控制器中的第二个。
如何在applyFor() - 方法中从second.fxml获取TextFields?

I have written a controller for two windows /stages. The first window is opened in the MainClass. The second in the Controller, if the user clicks onto a button. How can I get the TextFields from second.fxml in the applyFor()-method?

谢谢。

@FXML
    protected void requestNewAccount(ActionEvent event) {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("second.fxml")); // TextFields in there
            Parent root = (Parent) fxmlLoader.load();
            Stage stage = new Stage();
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.setTitle("Second Window");
            Scene scene = new Scene(root);
            String css = MainOnlineCustomer.class.getResource("/style.css").toExternalForm();
            scene.getStylesheets().clear();
            scene.getStylesheets().add(css);
            stage.setScene(scene);
            stage.show();
        } catch (IOException e) {
            logger.error(e);
        }
    }

    /**
     * closes the "second"-Window
     * @param event
     */
    @FXML
    protected void cancel(ActionEvent event) {
        final Node source = (Node) event.getSource();
        final Stage stage = (Stage) source.getScene().getWindow();
        stage.close();
    }

    @FXML
    protected void applyFor(ActionEvent event) {
        // get values from TextField in second.fxml here!!!
    }


推荐答案

共享控制器并不好在fxmls之间,除非它们用于相同的目的。在这里,两个fxml似乎都有不同的用途(帐户管理,登录或类似的其中一个,并为另一个创建一个新帐户)。更糟糕的是,这些类不共享相同的控制器实例,这意味着您可以从使用相同的控制器获得的小(并且可能是唯一的)益处,这里不使用。你最好使用不同的控制器。

It's not good to share controllers between fxmls unless they serve the same purpose. Here both fxml seem to serve a different purpose (account management, login or something similar for one of them and creating a new account for the other). What is even worse is that those classes do not share the same controller instance, which means the small (and probably only) benefit you could get from using the same controller, is not used here. You should better use different controllers.

由于你使用 Modality.APPLICATION_MODAL 作为模态,我建议使用< a href =https://docs.oracle.com/javase/8/javafx/api/javafx/stage/Stage.html#showAndWait-- =nofollow> showAndWait 而不是 show 来打开新阶段。这将进入一个嵌套的事件循环,它允许UI保持响应,并在关闭阶段后调用 showAndWait 后继续。

Since you use Modality.APPLICATION_MODAL as modality, I'd recommend using showAndWait instead of show to open the new stage. This will enter a nested event loop, which allows the UI to remain responsive and continues after the invocation of showAndWait once the stage is closed.

此外,向 second.fxml 的控制器添加一个允许您检索结果的方法。

Furthermore add a method to the controller of second.fxml that allows you to retrieve the result.

这将创建一个具有给定名称的 Person 对象姓。

This creates a Person object with given name and family name.

FXMLLoader loader = new FXMLLoader(getClass().getResource("second.fxml"));
Stage subStage = new Stage();
subStage.initModality(Modality.APPLICATION_MODAL);
subStage.setTitle("Second Window");
Scene scene = new Scene(loader.load());
subStage.setScene(scene);
subStage.showAndWait();

Optional<Person> result = loader.<Supplier<Optional<Person>>>getController().get();

if (result.isPresent()) {
    // do something with the result
}



内部的控制器content



controller for "inner" content

public class SecondController implements Supplier<Optional<Person>> {
    @FXML
    private TextField givenName;
    @FXML
    private TextField familyName;

    private boolean submitted = false;

    // handler for submit action
    @FXML
    private void submit() {
        submitted = true;
        givenName.getScene().getWindow().hide();
    }

    // handler for cancel action
    @FXML
    private void cancel() {
        givenName.getScene().getWindow().hide();
    }

    @Override
    public Optional<Person> get() {
        return submitted ? Optional.of(new Person(givenName.getText(), familyName.getText())) : Optional.empty();
    }

}

请注意,您可以访问以这种方式可用于控制器的任何数据。我不建议直接访问任何节点(例如 TextField s),因为这会更难以更改UI。

Note that you can gain access to any data available to the controller this way. I wouldn't recommend accessing any nodes (like TextFields) directly though, since this makes changing the UI harder.

在这里使用 Supplier 界面是没有必要的,但我选择这样做以实现 SecondController 之间的松散耦合和主窗口。

Using the Supplier interface here is not necessary, but I chose to do this to achieve a loose coupling between SecondController and the main window.

这篇关于如何从JavaFX的内部阶段获取TextField?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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