Пользовательский диалог JavaFX

#java #javafx #dialog

#java #javafx #диалог

Вопрос:

Я хочу создать пользовательский диалог JavaFX. До сих пор я создавал что-то подобное:

 public class LoginDialog extends Dialog {

    public LoginDialog(Data data) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/LoginDialog.fxml"));
            Parent root = loader.load();
            LoginDialogController controller = loader.<LoginDialogController>getController();
            controller.setModel(new LoginModel(data));
            getDialogPane().setContent(root);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  

Но — сначала я не уверен, что это правильный способ сделать это.

Во-вторых, я хочу использовать кнопку, объявленную в файле LoginDialog.fxml, чтобы закрыть этот LoginDialog после вызова showAndWait(). Возможно ли это? Как я могу установить возвращаемое значение?

Ответ №1:

Закройте окно из контроллера:

 public class LoginDialogController {

    @FXML
    private Button button ;

    @FXML
    private void handleButtonPress() {
        button.getScene().getWindow().hide();
    }

    // ...
}
  

(и в FXML вам нужно что-то вроде <Button fx:id="button" onAction="#handleButtonPress" ... /> )

Чтобы вернуть значение, укажите тип для диалога и задайте преобразователь результатов:

 public class LoginDialog extends Dialog<SomeDataType> {

    public LoginDialog(Data data) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/LoginDialog.fxml"));
            Parent root = loader.load();
            LoginDialogController controller = loader.<LoginDialogController>getController();
            controller.setModel(new LoginModel(data));
            getDialogPane().setContent(root);

            setResultConverter(buttonType -> {
                SomeDataType someData = ... ;
                return someData ;
            });

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
  

Очевидно, что вы можете ссылаться на контроллер в преобразователе результатов, вызывать на нем методы и т. Д., Поэтому Вы можете возвращать разные значения в зависимости от того, что пользователь делает в пользовательском интерфейсе.

Ответ №2:

Вы можете создать диалоговое окно, используя следующий способ

 public void popup() {
        final Stage dialog = new Stage();
        dialog.setTitle("Confirmation");
        Button yes = new Button("Yes");
        Button no = new Button("No");

        Label displayLabel = new Label("What do you want to do ?");
        displayLabel.setFont(Font.font(null, FontWeight.BOLD, 14));

        dialog.initModality(Modality.NONE);
        dialog.initOwner((Stage) tableview.getScene().getWindow());

        HBox dialogHbox = new HBox(20);
        dialogHbox.setAlignment(Pos.CENTER);

        VBox dialogVbox1 = new VBox(20);
        dialogVbox1.setAlignment(Pos.CENTER_LEFT);

        VBox dialogVbox2 = new VBox(20);
        dialogVbox2.setAlignment(Pos.CENTER_RIGHT);

        dialogHbox.getChildren().add(displayLabel);
        dialogVbox1.getChildren().add(yes);
        dialogVbox2.getChildren().add(no);

        yes.addEventHandler(MouseEvent.MOUSE_CLICKED,
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent e) {
                        // inside here you can use the minimize or close the previous stage//
                        dialog.close();
                    }
                });
        no.addEventHandler(MouseEvent.MOUSE_CLICKED,
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent e) {
                        dialog.close();
                    }
                });

        dialogHbox.getChildren().addAll(dialogVbox1, dialogVbox2);
        Scene dialogScene = new Scene(dialogHbox, 500, 40);
        dialogScene.getStylesheets().add("//style sheet of your choice");
        dialog.setScene(dialogScene);
        dialog.show();
    }
  

Этот метод для меня предпочтительнее, так как мне не нужно создавать отдельный контроллер, и я получаю всплывающее окно

Комментарии:

1. Действительно ли это все еще действует как dialoge? Например, сохраняет ли он фокус при нажатии на другие окна?