Как создать модальное окно в JavaFX 2.1

Я не могу понять, как создать модальное окно в JavaFX. По сути, у меня есть средство выбора файлов, и я хочу задать пользователю вопрос, когда он выбирает файл. Мне нужна эта информация, чтобы разобрать файл, поэтому выполнение должно дождаться ответа.

Я видел этот вопрос, но не смог понять, как это реализовать поведение.


person Luka    schedule 07.05.2012    source источник


Ответы (3)


Вот ссылка на решение, которое я создал ранее для модальных диалогов в JavaFX 2.1 Решение создает модальный этап поверх текущего этапа и выполняет действия над результатами диалога с помощью обработчиков событий для элементов управления диалога.

Обновить

Предыдущее связанное решение использует устаревший подход обработчика событий для выполнения действия после закрытия диалогового окна. Этот подход был действителен для реализаций до JavaFX 2.2. Для JavaFX 8+ нет необходимости в обработчиках событий, вместо этого используйте новый этап 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, если они соответствуют вашим требованиям, я советую использовать их, а не разрабатывать свои собственные. Те встроенные JavaFX Dialog и Классы Alert также имеют initOwner и initModality и showAndWait< /a>, чтобы вы могли установить для них модальность по своему усмотрению (обратите внимание, что по умолчанию встроенные диалоги являются модальными для приложения).

person jewelsea    schedule 07.05.2012

На мой взгляд, это не очень хорошее решение, потому что родительское окно все время активно.
Например, если вы хотите открыть окно как модальное после нажатия кнопки...

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
person Krzysztof Szewczyk    schedule 12.04.2013
comment
Мне пришлось использовать stage.initModality(Modality.APPLICATION_MODAL); чтобы заблокировать вызов родителя. Даже использование showAndWait() не блокировало вызывающего абонента (я звонил из JFXPanel — не уверен, что это имело какое-либо значение). - person torwalker; 25.11.2015

Вы можете создать приложение, подобное моему образцу. Это только однофайловое приложение 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);
    }
}
person user7182326    schedule 06.04.2017
comment
Это может улучшить качество вашего ответа, если вы добавите объяснение того, что в вашем ответе, по вашему мнению, поможет и почему. - person toonice; 06.04.2017