Java 如何启动内部关闭请求?

Java 如何启动内部关闭请求?,java,javafx,javafx-2,Java,Javafx,Javafx 2,在JavaFX中关闭窗口时遇到问题 我根据需要定义我的setOnCloseRequest,当我单击窗口中的x时,它就工作了。但是,我还需要一个按钮来关闭窗口,这个onCloseRequest必须工作,问题是它不能工作。事件根本没有发生 我正在使用JavaFX2.2(Java7),我注意到,setOnCloseRequest的参考说明在外部请求上关闭窗口 从内部关闭请求(按下按钮)触发事件,使应用程序认为收到了外部关闭请求。然后,无论请求来自外部事件还是内部事件,关闭请求逻辑都可以相同 priva

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

我根据需要定义我的
setOnCloseRequest
,当我单击窗口中的x时,它就工作了。但是,我还需要一个按钮来关闭窗口,这个
onCloseRequest
必须工作,问题是它不能工作。事件根本没有发生

我正在使用JavaFX2.2(Java7),我注意到,
setOnCloseRequest
的参考说明在外部请求上关闭窗口

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

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
                )
        )
);
private EventHandler confirmCloseEventHandler=event->{
//关闭事件处理逻辑。
//如果要取消关闭操作,请使用该事件。
}
...
stage.setOnCloseRequest(confirmCloseEventHandler);
按钮关闭按钮=新按钮(“关闭应用程序”);
关闭按钮。设置操作(事件->
舞台火灾事件(
新窗口事件(
阶段
WindowEvent.WINDOW\u关闭\u请求
)
)
);

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

示例用户界面

示例代码

示例代码将向用户显示关闭确认警报,如果用户未确认关闭,则取消关闭请求

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);
    }

}
导入javafx.application.application;
导入javafx.event.EventHandler;
导入javafx.geometry.Insets;
导入javafx.scene.scene;
导入javafx.scene.control.*;
导入javafx.scene.layout.StackPane;
导入javafx.stage.*;
导入javafx.stage.WindowEvent;
导入java.util.Optional;
公共类CloseConfirm扩展应用程序{
私人舞台主体;
@凌驾
public void start(Stage)引发异常{
这个.主干=阶段;
stage.setOnCloseRequest(confirmCloseEventHandler);
按钮关闭按钮=新按钮(“关闭应用程序”);
关闭按钮。设置操作(事件->
舞台火灾事件(
新窗口事件(
阶段
WindowEvent.WINDOW\u关闭\u请求
)
)
);
StackPane布局=新建StackPane(关闭按钮);
布局。设置填充(新插图(10));
舞台场景(新场景(布局));
stage.show();
}
私有事件处理程序confirmCloseEventHandler=事件->{
警报关闭确认=新警报(
Alert.AlertType.CONFIRMATION,
“确实要退出吗?”
);
按钮exitButton=(按钮)closeConfirmation.getDialogPane().lookupButton(
好的
);
setText(“退出”);
closeConfirmation.setHeaderText(“确认退出”);
closeConfirmation.initmodel(model.APPLICATION_model);
closeConfirmation.initOwner(主页面);
//通常,您只需使用默认的警报定位,
//但是对于这个简单的样品,主阶段很小,
//因此,请明确定位警报,以便仍能看到主窗口。
closeConfirmation.setX(mainStage.getX());
closeConfirmation.setY(mainStage.getY()+mainStage.getHeight());
可选closeResponse=closeConfirmation.showAndWait();
如果(!ButtonType.OK.equals(closeResponse.get())){
event.consume();
}
};
公共静态void main(字符串[]args){
发射(args);
}
}

请注意,OP使用的是JavaFX2。谢谢Uluk,我错过了问题的JavaFX-2标签。我更新了答案,以讨论使用JavaFX2的潜在影响。