如何解除内部关闭请求?

时间:2015-04-17 22:31:34

标签: java javafx javafx-2

在JavaFX中关闭窗口时遇到问题。

我按照自己的意愿定义了setOnCloseRequest,当我点击窗口中的x时,它可以正常工作。但是,我还需要一个按钮来关闭窗口,这个onCloseRequest必须工作,问题是它没有。事件根本不会发生。

我正在使用JavaFX 2.2(Java 7),我注意到setOnCloseRequest的引用说明关闭了外部请求

的窗口

1 个答案:

答案 0 :(得分:13)

解决方案

从内部关闭请求(按下按钮)触发事件,以便应用程序认为它收到了外部关闭请求。然后,无论请求来自外部事件还是内部事件,您的关闭请求逻辑都可以是相同的。

private EventHandler<WindowEvent> confirmCloseEventHandler = event -> {
        // close event handling logic.
        // consume the event if you wish to cancel the close operation.
}

...

stage.setOnCloseRequest(confirmCloseEventHandler);

Button closeButton = new Button("Close Application");
closeButton.setOnAction(event ->
        stage.fireEvent(
                new WindowEvent(
                        stage,
                        WindowEvent.WINDOW_CLOSE_REQUEST
                )
        )
);

注意

这是Java 8+解决方案,对于JavaFX 2,您需要转换匿名内部类中的lambda函数,并且无法使用“警告”对话框,但需要提供自己的警报对话框系统,如JavaFX 2没有内置的。我强烈建议升级到Java 8+,而不是继续使用JavaFX 2.

示例用户界面

close app

close confirm

示例代码

示例代码将向用户显示关闭确认提醒,并在用户未确认关闭时取消关闭请求。

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.StackPane;
import javafx.stage.*;
import javafx.stage.WindowEvent;

import java.util.Optional;

public class CloseConfirm extends Application {

    private Stage mainStage;

    @Override
    public void start(Stage stage) throws Exception {
        this.mainStage = stage;
        stage.setOnCloseRequest(confirmCloseEventHandler);

        Button closeButton = new Button("Close Application");
        closeButton.setOnAction(event ->
                stage.fireEvent(
                        new WindowEvent(
                                stage,
                                WindowEvent.WINDOW_CLOSE_REQUEST
                        )
                )
        );

        StackPane layout = new StackPane(closeButton);
        layout.setPadding(new Insets(10));

        stage.setScene(new Scene(layout));
        stage.show();
    }

    private EventHandler<WindowEvent> confirmCloseEventHandler = event -> {
        Alert closeConfirmation = new Alert(
                Alert.AlertType.CONFIRMATION,
                "Are you sure you want to exit?"
        );
        Button exitButton = (Button) closeConfirmation.getDialogPane().lookupButton(
                ButtonType.OK
        );
        exitButton.setText("Exit");
        closeConfirmation.setHeaderText("Confirm Exit");
        closeConfirmation.initModality(Modality.APPLICATION_MODAL);
        closeConfirmation.initOwner(mainStage);

        // normally, you would just use the default alert positioning,
        // but for this simple sample the main stage is small,
        // so explicitly position the alert so that the main window can still be seen.
        closeConfirmation.setX(mainStage.getX());
        closeConfirmation.setY(mainStage.getY() + mainStage.getHeight());

        Optional<ButtonType> closeResponse = closeConfirmation.showAndWait();
        if (!ButtonType.OK.equals(closeResponse.get())) {
            event.consume();
        }
    };

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

}