zu www.bildungsgueter.de nächster Abschnitt zur Inhaltsübersicht des Kapitels vorheriger Abschnitt

Ein Fenster nach einer Rückfrage schliessen


Gelegentlich ist es wünschenswert, beim Schliessen eines Fensters eine Rückfrage zu stellen, bevor das Fenster tat­säch­lich ge­schlos­sen wird. Zu diesem Zweck muss das Hauptfenster mit einer Ereig­nis­be­hand­lungs­routine für das Ereignis CloseRequest ausgestattet werden. Die Ereig­nis­be­hand­lungs­routine wird als Klasse bereitgestellt; die Klasse muss die Schnittstelle EventHandler<Window> implementieren. Eine Instanz dieser Klasse wird dem Hauptfenster mit einem Aufruf der Methode setOnCloseRequest übergeben.

Die Ereig­nis­be­hand­lungs­routine zeigt einen Dialog an und wartet auf die Entcheidung des Benutzers. Der Dialog wird als Instanz von Alert realisiert; die Antwort des Benutzers wird als Instanz von Optional<ButtonType> empfangen.

Ein leeres Fenster

Die Rückfrage

Archivdatei mit diesem Beispiel: FXCloseWindow01.zip

Das Fenster ist mit einem EventHandler ausgestattet, der vor dem Schliessen des Fensters die Zustimmung des An­wen­ders erfragt.

Klasse FXCloseWindow01:

package fxclosewindow01;

import java.util.Optional;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

/**
 * Die Klasse implementiert das Hauptfenster der Anwendung.
 * Das Fenster hat keinen Inhalt, ist aber mit einem Eventhandler
 * für das Schliessen des Fensters ausgestattet.
 * @author BG
 */
public class FXCloseWindow01 extends Application {
    
    @Override
    public void start(Stage primaryStage) {
        /**
         * Eine Instanz von CloseHandler bittet den Anwender vor dem
         * Schliessen des Fensters um seine Zustimmung.
         * Das Fenster wird nur geschlossen, wenn der Anwender der
         * Schliessung nicht widerspricht.
         */
        class CloseHandler implements EventHandler<WindowEvent> {

            @Override
            public void handle(WindowEvent event) {
                if (event.getEventType() == WindowEvent.WINDOW_CLOSE_REQUEST) {
                    Alert dialog = new Alert(Alert.AlertType.CONFIRMATION,
                                             "Wollen Sie das Fenster nun schliessen?");
                    Optional<ButtonType> result = dialog.showAndWait();
                    boolean okToClose = result.isPresent() &&
                                        result.get() == ButtonType.OK;
                    if (!okToClose) {
                        event.consume();
                        // Diese Anweisung verhindert das Schliessen des Fensters
                    }
                }
            }
        }
        primaryStage.setOnCloseRequest(new CloseHandler());
        
        StackPane root = new StackPane();
        Scene scene = new Scene(root, 300, 250);
        primaryStage.setTitle("Window Demo");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

Um vor dem Schliessen des Fensters eine Rückfrage stellen zu können, muss das Fenster mit einem Eventhandler für das Ereignis CloseRequest ausgestattet werden. Dieser EventHandler wird als Klasse realisiert, die die Schnittstelle EventHandler<WindowEvent> implementieren muss. Die verlangte Schnittstelle spezifiziert lediglich die Methode handle.

Die Methode handle erhält als Aufrufparameter eine Instanz von WindowEvent Aus diesem Ereignis kann ausgelesen werden, aus welchem Grund das Ereignis gesendet wurde. An das Ereignis muss die Methode comsume() gesendet werden, falls das Schliessen des Fensters noch verhindert werden soll.

Der Dialog, mit dem der Benutzer um seine Entscheidung gebeten wird, wird in JavaFX mit der Klasse Alert realisiert.

Für Kenner von Swing:

EventHandler ist in JavaFX eine generische Schnittstelle. Die Generizität ermöglicht in der überschriebenen Methode handle die korrekte Angabe des Ereignisses; ein Downcast von Object, wie er in Swing erforderlich ist, ist daher nicht nötig.


vorheriger Abschnitt zur Inhaltsübersicht des Kapitels nächster Abschnitt