javafx - 如何防止primaryStage在用户从javafx对话框中选择一个选项之前关闭?
问题描述
现在,当用户单击关闭窗口按钮时,窗口会关闭,然后才会出现对话框。我希望对话框首先出现,如果用户选择是或否,只有这样,窗口才会关闭。
这是我的代码:
@Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("/application/LoginScreen.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setResizable(true);
} catch(Exception e) {
e.printStackTrace();
}
primaryStage.setOnHiding(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
Platform.runLater(new Runnable() {
@Override
public void run() {
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Exist Confirmation Dialog");
alert.setHeaderText("Do you want to save your changes?");
alert.setContentText("Choose your option.");
ButtonType yesButton = new ButtonType("Yes");
ButtonType noButton = new ButtonType("No");
ButtonType cancelButton = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE);
alert.getButtonTypes().setAll(yesButton, noButton, cancelButton);
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == yesButton){
//Serialize();
System.exit(0);
} else if (result.get() == noButton) {
System.exit(0);
} else {
// ... user chose CANCEL or closed the dialog
}
}
});
}
});
解决方案
您必须捕获窗口关闭事件。
stage.setOnCloseRequest(event -> {
//Code that will be called if the user tries to close the window
//Close the window with a cross, as the user would do. Do not close via IDEA.
});
如果您不想关闭窗口,请吸收该事件。
stage.setOnCloseRequest(event -> {
event.consume();
});
注意。我不需要调用 System.exit(0); 如果我没有使用 event.consumer(); 窗口将自行关闭。
public class App extends Application {
@Override
public void start(Stage stage) throws Exception {
Pane pane = new Pane();
pane.setPrefSize(400, 400);
stage.setScene(new Scene(pane));
//window close request
stage.setOnCloseRequest(event -> {
Alert alert = getAlert();
Optional<ButtonType> result = alert.showAndWait();
if (result.get().getText().equalsIgnoreCase("Yes")){
//Save the changes
} else if (result.get().getText().equalsIgnoreCase("No")) {
//Save the changes
}else if(result.get().getText().equalsIgnoreCase("Cancel")){
//Absorb the event, the window will not close
event.consume();
}
});
stage.show();
}
private Alert getAlert(){
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setTitle("Exist Confirmation Dialog");
alert.setHeaderText("Do you want to save your changes?");
alert.setContentText("Choose your option.");
ButtonType yesButton = new ButtonType("Yes");
ButtonType noButton = new ButtonType("No");
ButtonType cancelButton = new ButtonType("Cancel",
ButtonBar.ButtonData.CANCEL_CLOSE);
alert.getButtonTypes().setAll(yesButton, noButton, cancelButton);
return alert;
}
public static void main(String[] args) {
launch(args);
}
}
推荐阅读
- c++ - 使用 Sublime Text 3 在 Powershell 中构建 C++ 而不是 CMD
- html - 防止两个引导容器相互重叠。?
- javascript - 为什么有些函数需要在函数名之前声明“函数”?
- php - 在其他页面 PHP MySql 中获取会话数据
- java - RecyclerView 中的网格项未正确显示
- node.js - 与 API 服务器的云存储连接域
- android - Android Studio 未检测到 USB 设备
- haskell - 为什么在 Haskell 函数应用程序中使用逗号会导致不同的类型?
- java - 斯坦福 NLP:加载标记器模型时出错(可能缺少模型文件)
- python - 使用 Django 将 mongoDB 列中的值获取到 HTML 表中