如何在 JavaFX 2.1 中创建模态窗口

Posted

技术标签:

【中文标题】如何在 JavaFX 2.1 中创建模态窗口【英文标题】:How to create a modal window in JavaFX 2.1 【发布时间】:2012-05-16 05:38:56 【问题描述】:

我不知道如何在 JavaFX 中创建模式窗口。基本上我有文件选择器,我想在用户选择文件时问他们一个问题。我需要这些信息来解析文件,所以执行需要等待答案。

我见过this question,但我不知道如何实现这种行为。

【问题讨论】:

【参考方案1】:

在我看来,这不是一个好的解决方案,因为父窗口一直处于活动状态。 例如,如果您希望在单击按钮后以模态形式打开窗口...

private void clickShow(ActionEvent event) 
    Stage stage = new Stage();
    Parent root = FXMLLoader.load(
        YourClassController.class.getResource("YourClass.fxml"));
    stage.setScene(new Scene(root));
    stage.setTitle("My modal window");
    stage.initModality(Modality.WINDOW_MODAL);
    stage.initOwner(
        ((Node)event.getSource()).getScene().getWindow() );
    stage.show();

现在你的新窗​​口真的是模态的——父窗口是块。 你也可以使用

Modality.APPLICATION_MODAL

【讨论】:

我不得不使用 stage.initModality(Modality.APPLICATION_MODAL);阻止呼叫父母。即使使用 showAndWait() 也不会阻止调用者(我是从 JFXPanel 调用的——不确定这是否有什么不同。)【参考方案2】:

这里是 link to a solution 我之前为 JavaFX 2.1 中的模式对话框创建的 该解决方案在当前阶段之上创建一个模态阶段,并通过对话框控件的事件处理程序对对话框结果执行操作。

更新

先前的链接解决方案使用过时的事件处理程序方法在对话框关闭后采取行动。该方法对 JavaFX 2.2 之前的实现有效。对于 JavaFX 8+,不需要事件处理程序,而是使用新的 Stage showAndWait() 方法。例如:

Stage dialog = new Stage();

// populate dialog with controls.
...

dialog.initOwner(parentStage);
dialog.initModality(Modality.APPLICATION_MODAL); 
dialog.showAndWait();

// process result of dialog operation. 
... 

请注意,为了让事情按预期工作,初始化舞台的所有者很重要将舞台的模态初始化为WINDOW_MODAL 或APPLICATION_MODAL。

JavaFX 8 和 ControlsFX 中有一些高质量的标准 UI 对话框,如果它们符合您的要求,我建议使用它们而不是自己开发。那些内置的 JavaFX Dialog 和 Alert 类也有 initOwnerinitModalityshowAndWait 方法,因此您可以根据需要为它们设置模态(注意,默认情况下,in-构建的对话框是应用程序模式的)。

【讨论】:

ControlsFX 库是为 JavaFX 8.0 及更高版本开发的,将于 2014 年第一季度发布,因此必须考虑到这一点。 @jewelsea javafx 1.3 有文件选择器功能吗? Avinash,最好将新问题作为新问题提出。 JavaFX 1.3 已经过时,我不建议使用它。我不认为它直接有一个 FileChooser,尽管你可以使用 Swing JFileChooser 。【参考方案3】:

您可以像我的示例一样创建应用程序。这只是单个文件 JavaFX 应用程序。

public class JavaFXApplication1 extends Application 
    @Override
    public void start(Stage primaryStage) 
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(new EventHandler<ActionEvent>() 
            @Override
            public void handle(ActionEvent event) 
                Stage stage; 
                stage = new Stage();

                final SwingNode swingNode = new SwingNode();

                createSwingContent(swingNode);

                StackPane pane = new StackPane();
                pane.getChildren().add(swingNode);

                stage.initModality(Modality.APPLICATION_MODAL);
                stage.setTitle("Swing in JavaFX");
                stage.setScene(new Scene(pane, 250, 150));
                stage.show();
            
        );

        StackPane root = new StackPane();
        root.getChildren().add(btn);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    

    private void createSwingContent(final SwingNode swingNode) 
        SwingUtilities.invokeLater(() -> 
            try 
                Path currentRelativePath = Paths.get("");
                String s = currentRelativePath.toAbsolutePath().toString();
                JasperDesign jasperDesign = JRXmlLoader.load(s + "/src/reports/report1.jrxml");

                String query = "SELECT * FROM `accounttype`";
                JRDesignQuery jrquery = new JRDesignQuery();
                jrquery.setText(query);
                jasperDesign.setQuery(jrquery);

                JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
                JasperPrint JasperPrint = JasperFillManager.fillReport(jasperReport, null, c);
                //JRViewer viewer = new JRViewer(JasperPrint);

                swingNode.setContent(new JRViewer(JasperPrint));
             catch (JRException ex) 
                Logger.getLogger(AccountTypeController.class.getName()).log(Level.SEVERE, null, ex);
            
        );
    

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) 
        launch(args);
    

【讨论】:

如果您添加了关于您认为对您的答案有什么帮助以及为什么有帮助的解释,它可能会提高您的答案质量。

以上是关于如何在 JavaFX 2.1 中创建模态窗口的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX如何实现模态窗口

Swing 的 JavaFX 模态窗口所有权

XIB 模态窗口 ios

如何在 Flutter 中创建带有圆角的模态底页?

如何创建一个模态的对话框

如何在javafx中创建一个弹出窗口[重复]