This question already has answers here:
Alert Box For When User Attempts to close application using setOnCloseRequest in JavaFx
(2 answers)
Closed 4 years ago.
I want to implement a dialogue alert when the user clicks the close button. With the option for yes they do want to leave and no they don't.
Button button = new Button("Exit");
gridPane.add(button, 12, 12);
button.setOnAction(e ->{
primaryStage.close();
});
How would I go about this?
Use the onCloseRequest event of the stage for closing the window using the X button of the window:
private static boolean confirmClose() {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setContentText("Do you really want to close the app?");
return alert.showAndWait().orElse(ButtonType.CANCEL) == ButtonType.OK;
}
primaryStage.setOnCloseRequest(event -> {
if (!confirmClose()) {
event.consume();
}
});
Note that this event is not triggered when closing the window programmatically. You need to request user confirmation yourself in such a case:
button.setOnAction(evt -> {
if (confirmClose()) {
primaryStage.close();
}
});
You have a pretty good article which explains et give some examples about Alert
The one you need is a Confirmation-Dialog :
button.setOnAction(e ->
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Exit Application");
alert.setHeaderText("Exit of the App");
alert.setContentText("Do you really want to exit ? ");
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK){
primaryStage.close();
Platform.exit();
System.exit(0);
} else {
// ... user chose CANCEL or closed the dialog
}
});
Try something like:
Button button = new Button("Exit");
gridPane.add(button, 12, 12);
button.setOnAction(e ->{
if(confirmDialog(
"Sure you want to quit?",
"Sure you want to quit?",
"We're really closing - click yes to quit, no to stay in the app")
) {
primaryStage.close();
}
});
...
public boolean confirmDialog(String title, String headerText, String message) {
Alert alert = new Alert(AlertType.CONFIRMATION, message, ButtonType.YES, ButtonType.NO);
alert.initModality(Modality.APPLICATION_MODAL);
alert.initOwner(scene); //scene must be accessible as a field
alert.setTitle(title);
alert.setHeaderText(headerText);
ButtonType result = alert.showAndWait().orElse(ButtonType.NO);
return ButtonType.YES==result;
}
Related
I want to modify the default exit procedure in my javafx application to display a confirmation dialogue to the user. The confirmation dialogue will exit the application if the user chooses OK and will keep the application running when user chooses Cancel.
What should I do to make this in javaFX?
You can use Alert since 8.40
stage.setOnCloseRequest(evt -> {
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirm Close");
alert.setHeaderText("Close program?");
alert.showAndWait().filter(r -> r != ButtonType.OK).ifPresent(r->evt.consume());
});
primaryStage.addEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST, e->{
e.consume();
Popup popup = new Popup();
HBox buttons = new HBox();
Button close = new Button("close");
Button cancel = new Button("cancel");
buttons.getChildren().addAll(close,cancel);
buttons.setPadding(new Insets(5,5,5,5));
popup.getContent().add(buttons);
popup.show(primaryStage);
close.setOnAction(ex -> {
Platform.exit();
});
cancel.setOnAction(ec -> {
popup.hide();
});
});
I am using JavaFX have a list of items in a combobox , when a user trys to register i want that a condition cheks if he selected an item or not in that combo. i have tryed this but it doesent work , how to do it please .
public void ADDuser(ActionEvent event) {
String username = usernametf.getText();
String pass = passtf.getText();
LocalDate datebirth = dateofbirth.getValue();
String situation = situationcombobox.getSelectionModel().getSelectedItem().toString();
if (!username.equals("") &&
!pass.equals("") &&
!datebirth.equals(null) &&
!situation.equals(null)) {// situaion problem
mainc.con.AdduserDatabase(username, pass, datebirth, situation, gender);
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Information Ajout");
alert.setHeaderText(null);
alert.setContentText("Ajout réussi merci " );
alert.showAndWait();
Stage stage = (Stage) btnadd.getScene().getWindow();
stage.close();
} else {
System.out.println(situation);
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Information Ajout");
alert.setHeaderText(null);
alert.setContentText("Please Fill All the fields ! " );
alert.showAndWait();
}
}
}
my code opens another window but the first one is still open. How can I close the first window?
ButtonType continue = new ButtonType("Continue");
ButtonType exit= new ButtonType("Exit");
alert.getButtonTypes().setAll(continue, exit);
Optional<ButtonType> result = alert.showAndWait();
if (result .get() == continue ) {
Controllerxx = new commandCenter();
centerFX newFX= new centerFX ();
Stage stage = new Stage();
newFX.start(stage);
} else if (result .get() == exit) {
Platform.exit();
}
You can try something like below :
btn.setOnAction((ActionEvent event) -> {
((Node) (event.getSource())).getScene().getWindow().hide();
});
You can get the current scene by the Action event of your exit button and close it.
I made a JavaFX alert dialog box to prompt the user, asking if they want to save the output from the console before closing the application.
I have the yes and no options taken care of. If the user clicks cancel, I want it to just close the dialog box and leave everything open. As of right now, if I hit cancel it will close the GUI.
Here is my code for overriding the close button on the GUI.
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>()
{
#Override
public void handle(WindowEvent event)
{
Alert alert = new Alert(AlertType.WARNING);
alert.setTitle("Warning");
alert.setHeaderText("Would You Like To Save Your Console Output?");
alert.setContentText("Please choose an 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)
{
Main.setConsoleVisible();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
else if(result.get() == noButton)
{
System.exit(0);
}
else if(result.get() == cancelButton)
{
}
}
});
Both in "yesButton" and "cancelButton" if-blocks consume the CloseRequest WindowEvent:
else if(result.get() == cancelButton)
{
event.consume();
}
Use Platform.exit() instead of System.exit(0).
Use primaryStage.close(); instead of System.exit(0);
From the documentation for onCloseRequest:
Called when there is an external request to close this Window. The installed event handler can prevent window closing by consuming the received event.
Be aware that result.get() will throw an exception if the user closes the alert dialog without pressing any buttons. The Dialog documentation explains this thoroughly.
Since jdk 8u40, I'm using the new javafx.scene.control.Alert API to display a confirmation dialog. In the example below, "Yes" button is focused by default instead of "No" button:
public boolean showConfirmDialog(String title, String header, String content, AlertType alertType) {
final Alert alert = new Alert(alertType);
alert.setTitle(title);
alert.setHeaderText(header);
alert.setContentText(content);
alert.getButtonTypes().clear();
alert.getButtonTypes().addAll(ButtonType.YES, ButtonType.NO);
final Optional<ButtonType> result = alert.showAndWait();
return result.get() == ButtonType.YES;
}
And I don't know how to change it.
EDIT :
Here a screenshot of the result where "Yes" button is focused by default :
I am not sure if the following is the way to usually do this, but you could change the default button by looking up the buttons and setting the default-behavior yourself:
public boolean showConfirmDialog(String title, String header, String content, AlertType alertType) {
final Alert alert = new Alert(alertType);
alert.setTitle(title);
alert.setHeaderText(header);
alert.setContentText(content);
alert.getButtonTypes().clear();
alert.getButtonTypes().addAll(ButtonType.YES, ButtonType.NO);
//Deactivate Defaultbehavior for yes-Button:
Button yesButton = (Button) alert.getDialogPane().lookupButton( ButtonType.YES );
yesButton.setDefaultButton( false );
//Activate Defaultbehavior for no-Button:
Button noButton = (Button) alert.getDialogPane().lookupButton( ButtonType.NO );
noButton.setDefaultButton( true );
final Optional<ButtonType> result = alert.showAndWait();
return result.get() == ButtonType.YES;
}
A simple function thanks to crusam:
private static Alert setDefaultButton ( Alert alert, ButtonType defBtn ) {
DialogPane pane = alert.getDialogPane();
for ( ButtonType t : alert.getButtonTypes() )
( (Button) pane.lookupButton(t) ).setDefaultButton( t == defBtn );
return alert;
}
Usage:
final Alert alert = new Alert(
AlertType.CONFIRMATION, "You sure?", ButtonType.YES, ButtonType.NO );
if ( setDefaultButton( alert, ButtonType.NO ).showAndWait()
.orElse( ButtonType.NO ) == ButtonType.YES ) {
// User selected the non-default yes button
}
If you have a look at (private) ButtonBarSkin class, there is a method called doButtonOrderLayout() that performs the layout of the buttons, based in some default OS behavior.
Inside of it, you can read this:
/* now that all buttons have been placed, we need to ensure focus is
set on the correct button. [...] If so, we request focus onto this default
button. */
Since ButtonType.YES is the default button, it will be the one focused.
So #ymene answer is correct: you can change the default behavior and then the one focused will be NO.
Or you can just avoid using that method, by setting BUTTON_ORDER_NONE in the buttonOrderProperty(). Now the first button will have the focus, so you need to place first the NO button.
alert.getButtonTypes().setAll(ButtonType.NO, ButtonType.YES);
ButtonBar buttonBar=(ButtonBar)alert.getDialogPane().lookup(".button-bar");
buttonBar.setButtonOrder(ButtonBar.BUTTON_ORDER_NONE);
Note that YES will still have the default behavior: This means NO can be selected with the space bar (focused button), while YES will be selected if you press enter (default button).
Or you can change also the default behavior following #crusam answer.