2015-04-17 10 views
5

Mam problem z zamknięciem okna w JavaFX.Jak mogę uruchomić żądanie zamknięcia wewnętrznego?

Definiuję moją setOnCloseRequest tak, jak chciałem i działa, gdy klikam x w oknie. Potrzebuję jednak przycisku, aby zamknąć okno i to musi zadziałać onCloseRequest, problem polega na tym, że nie działa. Wydarzenie wcale się nie uruchamia.

Używam JavaFX 2.2 (Java 7) i zauważyłem, że wniosek o setOnCloseRequest mówi zamknąć okno na zamówienie zewnętrznego

Odpowiedz

10

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

close app

close confirm

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

} 
+0

Mała uwaga, PO jest za pomocą JavaFX 2. –

+0

Thanks Uluk, tęskniłem tag javafx-2 w tej kwestii. Zaktualizowałem odpowiedź, aby omówić potencjalne konsekwencje pozostania w JavaFX 2. – jewelsea

Powiązane problemy