如何从JavaFX的内部阶段获取TextField?

时间:2016-06-27 19:56:28

标签: java javafx

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

感谢。

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

1 个答案:

答案 0 :(得分:0)

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

由于您使用Modality.APPLICATION_MODAL作为模态,因此我建议您使用showAndWait代替show来打开新阶段。这将进入一个嵌套的事件循环,它允许UI保持响应,并在阶段关闭后调用showAndWait后继续。

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

实施例

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

"主窗口(打开"内部"阶段)

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
}

&#34;内部&#34;含量

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。

此处不需要使用Supplier界面,但我选择这样做以实现SecondController与主窗口之间的松散耦合。