Rozwiązanie
Ogień zdarzenie ze swojego wewnętrznego bliskiego życzenie (na przycisku push), aby aplikacja uznała, że otrzymała żądanie zamknięcia zewnętrznego. Następnie logika żądania zamknięcia może być identyczna, niezależnie od tego, czy żądanie pochodziło ze zdarzenia zewnętrznego, czy wewnętrznego.
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
)
)
);
Uwaga
Jest to rozwiązanie Java 8+, dla JavaFX 2, trzeba będzie przekształcić funkcje lambda w anonimowych klas wewnętrznych i nie będzie w stanie użyć okna dialogowego Alert ale trzeba zapewnić własny system dialogu alarmowego, ponieważ JavaFX 2 nie ma wbudowanego systemu alarmowego. Gorąco polecam uaktualnienie do Java 8+ zamiast pobytu z JavaFX 2.
UI Próbka


Przykładowy kod
Przykładowy kod pokaże użytkownik zamyka komunikat potwierdzenia i anuluje żądanie zamknięcia, jeśli użytkownik nie potwierdzi potwierdzenia on blisko.
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);
}
}
Mała uwaga, PO jest za pomocą JavaFX 2. –
Thanks Uluk, tęskniłem tag javafx-2 w tej kwestii. Zaktualizowałem odpowiedź, aby omówić potencjalne konsekwencje pozostania w JavaFX 2. – jewelsea