JavaFX对话框:仅在按下“确定”按钮时运行onClosingRequest

时间:2018-12-04 10:56:38

标签: java javafx

我有一个对话框对话框,我想在对话框关闭之前添加确认警报。

在确认确定之前,对话框不会关闭。 我可以通过使用事件来避免这种情况。

它只应在单击“确定”对话框时确认,而不应在“取消”上确认。 问题是,我看不到该事件上单击了哪个按钮。因此,对话框上的“确定”和“取消”按钮都会显示“警报”确认。

如何防止onClosingReqeust for cancel按钮?

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;

public class DialogTestApplication extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    class MyDialog extends Dialog<ButtonType> {

        public MyDialog(Window window) {
            setTitle("MyDialog");
            initModality(Modality.WINDOW_MODAL);
            initOwner(window);
            setResizable(true);

            GridPane contentPane = new GridPane();
            contentPane.add(new TextField(), 0, 0);
            getDialogPane().setContent(contentPane);

            getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);

            setOnCloseRequest(event -> {
                Alert alert = new Alert(AlertType.CONFIRMATION);
                alert.showAndWait().ifPresent(response -> {
                    if (response == ButtonType.CANCEL) {
                        event.consume();
                    }
                });
            });
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        final StackPane root = new StackPane();
        final Label rootLabel = new Label("DialogTestApplication");
        root.getChildren().add(rootLabel);
        final Scene scene = new Scene(root, 400, 150);
        primaryStage.setScene(scene);
        primaryStage.setTitle("DialogTestApplication");
        primaryStage.show();

        Platform.setImplicitExit(true);
        MyDialog dialog = new MyDialog(primaryStage);
        dialog.showAndWait().ifPresent(response -> {
            if (response == ButtonType.OK) {
                System.out.println("OK");
            }
            Platform.exit();
        });
    }
}

3 个答案:

答案 0 :(得分:1)

final Button btnCancel = (Button) dialog.getDialogPane().lookupButton( ButtonType.CANCEL);
    btnCancel.addEventFilter(ActionEvent.ACTION, event -> {
    // handle cancel button code here
    event.consume();     
});

public boolean displayDialog() {
    Optional<ButtonType> result = dialog.showAndWait();
    if(result.get().getText().equals("Ok")) {
        //handle OK action. The dialog panel will close automatically.
    }
    return true;
} 

实例化警报时,处理“取消”按钮事件。 event.consume()方法将阻止按CANCEL时关闭警报对话框。您可以添加一种方法来显示您的警报,在该方法内可以处理“确定”操作。

答案 1 :(得分:0)

您可以处理“确定”按钮的动作事件,而不是处理对话框的关闭请求。像这样

    // I tested with onMouseClicked but the event doesn't get fired
    // onAction on the other hand works normally but we need to cast the node to a button
    Button button = (Button) getDialogPane().lookupButton(ButtonType.OK);

    button.setOnAction(e -> {
            Alert alert = new Alert(AlertType.CONFIRMATION);

            alert.showAndWait().ifPresent(response -> {
                if (response == ButtonType.CANCEL) {
                    event.consume();
                }
            });
    });

答案 2 :(得分:0)

阅读Dialog Javadoc之后,我找到了可行的解决方案。 https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Dialog.html

Button button = (Button) getDialogPane().lookupButton(ButtonType.OK);

button.addEventFilter(ActionEvent.ACTION, event -> {
    final Alert alert = new Alert(AlertType.CONFIRMATION);
    alert.initOwner(window);
    alert.showAndWait().ifPresent(response -> {
        if (response == ButtonType.CANCEL) {
            event.consume();
        }
    });
});