Reputation: 1864
If I just create an empty class extending from javafx.scene.control.Dialog<R>
, it won't close when I'm pressing the "x" button in the top right corner.
How do I implement this behaviour? The API seems to tell me that I need to implement a close button. But in my case I don't want a close button, I just want to close the window with the x button or by pressing ESC. Is this possible?
Upvotes: 14
Views: 19476
Reputation: 1
I have faced this situation with alerts with the below code.
Alert alert = new Alert(Alert.AlertType.NONE);
alert.setTitle("Export Successful");
alert.setContentText("All the posts have been exported to Posts.txt file
successfully");
alert.show();
The only workaround would be to create an alert or dialog with a button in it like below.
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Export Successful");
alert.setContentText("All the posts have been exported to Posts.txt file
successfully");
alert.showAndWait();
Upvotes: 0
Reputation: 1329
In my Dialog<ButtonType>
I'm using what @vbargl said:
Window window = alert.getDialogPane().getScene().getWindow();
window.setOnCloseRequest(event -> window.hide());
It closes the dialog, but it's bringing me a no value present error.
To avoid it, I'm also checking result.get()
and that result.isPresent()
.
Upvotes: 1
Reputation: 651
The workaround from @eckig or @jewelsea works pretty fine. But I would use something like this:
// Somewhere in code
Dialog<?> dialog = new Dialog<>();
Window window = dialog.getDialogPane().getScene().getWindow();
window.setOnCloseRequest(event -> window.hide());
I do not know any constrains of this use, but it worked for me. And I recommend initialize window right after dialog initialization, like above.
Upvotes: 27
Reputation: 159486
To work-around this, you could add a hidden close button to the dialog.
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.stage.Stage;
public class DialogClosure extends Application{
@Override
public void start(Stage stage) throws Exception {
Button openDialog = new Button("Open Dialog");
openDialog.setOnAction(event -> {
Dialog dialog = new Dialog();
dialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE);
Node closeButton = dialog.getDialogPane().lookupButton(ButtonType.CLOSE);
closeButton.managedProperty().bind(closeButton.visibleProperty());
closeButton.setVisible(false);
dialog.showAndWait();
});
stage.setScene(new Scene(openDialog));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Then the dialog meets both your requirement of being able to be closed via the native windowing system's window close icon as well as the JavaFX Dialog requirement of including a close button in the dialog for the close icon to work.
Alternately, you could use a Stage with showAndWait instead of a Dialog. A Stage without any included buttons is closable using the windowing system's close window icon.
Upvotes: 17
Reputation: 11144
To quote the Api Docs:
JavaFX dialogs can only be closed 'abnormally' (as defined above) in two situations:
When the dialog only has one button, or
When the dialog has multiple buttons, as long as one of them meets one of the following requirements:
- The button has a ButtonType whose ButtonData is of type ButtonData.CANCEL_CLOSE.
- The button has a ButtonType whose ButtonData returns true when ButtonData.isCancelButton() is called.
...
So either add at least one button or multiple buttons, and one of them is of type ButtonData.CANCEL_CLOSE
, for example:
Dialog<ButtonType> dialog = new Dialog<>();
dialog.getDialogPane().getButtonTypes().add(new ButtonType("Got it!", ButtonData.CANCEL_CLOSE));
dialog.setContentText("test");
dialog.showAndWait();
Edit:
This behavior is implemented in javafx.scene.control.FXDialog.requestPermissionToClose(Dialog<?>)
, but the real FXDialog
shown is HeavyweightDialog
which is not public API so not really an extension point.
Upvotes: 10