2015-04-17 6 views
5

Ho problemi durante la chiusura di una finestra in JavaFX.Come posso attivare la richiesta di chiusura interna?

Definisco il mio setOnCloseRequest come volevo e funziona quando faccio clic sulla x nella finestra. Tuttavia, ho anche bisogno di un pulsante per chiudere la finestra e questo onCloseRequest deve funzionare, il problema è che non funziona. L'evento non sparisce affatto.

Sto usando JavaFX 2.2 (Java 7) e ho notato che la domanda di setOnCloseRequest dice chiudere la finestra su richiesta esterna

risposta

10

Soluzione

fuoco un evento dal vicino richiesta interna (sul pulsante push), in modo che l'applicazione ritenga di aver ricevuto una richiesta di chiusura esterna. Quindi la logica della richiesta di chiusura può essere identica sia che la richiesta provenga da un evento esterno o da uno interno.

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 
       ) 
     ) 
); 

Nota

Questa è una soluzione Java 8+, per JavaFX 2, è necessario convertire le funzioni lambda nelle classi interne anonime e sarà in grado di utilizzare la finestra di dialogo Avviso, ma sarà è necessario fornire un proprio sistema di dialogo di avviso in quanto JavaFX 2 non è dotato di un sistema integrato. Consiglio vivamente l'aggiornamento a Java 8+ piuttosto che restare con JavaFX 2.

Esempio UI

close app

close confirm

codice di esempio

Il codice di esempio mostrerà l'utente un avviso di conferma ravvicinato e annulla la richiesta di chiusura se l'utente non conferma t lui chiude.

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); 
    } 

} 
+0

piccola nota, OP sta usando JavaFX 2. –

+0

Grazie Uluk, ho perso il tag JavaFX-2 sulla questione. Ho aggiornato la risposta per discutere le potenziali implicazioni di rimanere con JavaFX 2. – jewelsea