Як закрити програму JavaFX при закритті вікна?


79

У Swing ви можете просто використовувати setDefaultCloseOperation() для вимкнення всієї програми, коли вікно закрито.

Однак у JavaFX я не можу знайти еквівалента. У мене відкрито кілька вікон, і я хочу закрити всю програму, якщо вікно закрито. Який спосіб це зробити в JavaFX?

Редагувати:

Я розумію, що можу замінити setOnCloseRequest()виконання певної операції при закритті вікна. Питання в тому, яку операцію слід виконати, щоб припинити роботу всієї програми?

stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent event) {
        stop();
    }
});

stop()Метод , визначений у Applicationкласі нічого не робить.

Відповіді:


90

Програма автоматично зупиняється, коли Stageзакривається остання . На даний момент викликається stop()метод вашого Applicationкласу, тому вам не потрібен еквівалентsetDefaultCloseOperation()

Якщо ви хочете зупинити програму до цього, ви можете зателефонувати Platform.exit(), наприклад, у своєму onCloseRequestдзвінку.

Ви можете отримати всю цю інформацію на сторінці Javadoc за адресоюApplication : http://docs.oracle.com/javafx/2/api/javafx/application/Application.html


7
Для довідки (як зазначено на пов’язаній сторінці javadoc): Додаток зупиняється автоматично, лише якщо для implicitExitатрибута on Platformвстановлено значення true.
Рахель Люті

60

Деякі з наданих відповідей у ​​мене не працювали (javaw.exe все ще працює після закриття вікна), або eclipse показав виняток після закриття програми.

З іншого боку, це чудово працює:

primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent t) {
        Platform.exit();
        System.exit(0);
    }
});

Ви робили щось багатопотокове? Мені здається, що він не вимикається (для мене) при використанні ExecutorService (що може бути передбаченою поведінкою, я ще не перевірив документи).
Manius

1
Для мене додавання System.exit(0);- це єдине, що змусило процес завершитись після закриття головного вікна.
Йоганнес

1
Якщо вам подобається це коротко, це працює в Java 8: theStage.setOnCloseRequest (e -> System.exit (0));
Jaco Van Niekerk

1
Якщо ви запустите свій власний ExecutorService(тобто пул потоків), як це зробив @Manius, то вам потрібно явно вимкнути його (якщо потоки не є демоном). Ви можете зробити це #stop()методом вашого класу програми, якщо хочете. Однак JavaFX самостійно не керує ExecutorServiceекземплярами (або будь-якою іншою утилітою паралельності, що створює потоки).
Slaw

27

Для довідки, ось мінімальна реалізація з використанням Java 8:

@Override
public void start(Stage mainStage) throws Exception {

    Scene scene = new Scene(new Region());
    mainStage.setWidth(640);
    mainStage.setHeight(480);
    mainStage.setScene(scene);

    //this makes all stages close and the app exit when the main stage is closed
    mainStage.setOnCloseRequest(e -> Platform.exit());

    //add real stuff to the scene...
    //open secondary stages... etc...
}

21
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent event) {
        Platform.exit();
        System.exit(0);
    }
});

Я просто хочу зазначити, що в цьому випадку метод stop () взагалі не буде викликаний (принаймні з JavaFX 8 у вікнах), оскільки System.exit () закриває все занадто рано. У цьому випадку ви можете просто зателефонувати лише System.exit (). Але якщо ви хочете щось зробити в методі stop (), я б рекомендував зателефонувати Platform.exit () тут і System.exit (0) в кінці методу stop (), якщо це необхідно.
завтра

Тут якийсь поганий синтаксис. Вам не вистачає закриття ')'
Нібб,


3

Використовуючи Java 8, це працювало для мене:

@Override
public void start(Stage stage) {
    Scene scene = new Scene(new Region());
    stage.setScene(scene);

    /* ... OTHER STUFF ... */

    stage.setOnCloseRequest(e -> {
        Platform.exit();
        System.exit(0);
    });
}

2

Замість того, щоб пограти з обробниками onCloseRequest або подіями вікна, я віддаю перевагу називанню Platform.setImplicitExit(true)початку програми.

Відповідно до JavaDocs:

"Якщо цей атрибут істинний, час роботи JavaFX неявно вимкнеться, коли закриється останнє вікно; програма запуску JavaFX викличе метод Application.stop () і завершить потік програми JavaFX."

Приклад:

@Override
void start(Stage primaryStage) {
    Platform.setImplicitExit(true)
    ...
    // create stage and scene
}

1
Приємно, але принаймні в FX 12 це включено за замовчуванням. The default value is true.
Бенджамін Пітер

1

Для мене працює лише наступне:

primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent event) {

        Platform.exit();

        Thread start = new Thread(new Runnable() {
            @Override
            public void run() {
                //TODO Auto-generated method stub
                system.exit(0);     
            }
        });

        start.start();
    }
});

0

Здавалося, це спрацювало для мене:

EventHandler<ActionEvent> quitHandler = quitEvent -> {

        System.exit(0);

    };
    // Set the handler on the Start/Resume button
    quit.setOnAction(quitHandler);



-2

Ви ПОВИННІ замінити метод "stop ()" у своєму екземплярі програми, щоб він працював. Якщо ви перевизначили навіть порожній "stop ()", то програма вимикається поступово після закриття останнього етапу (насправді останній етап повинен бути основним, щоб він працював повністю, як передбачалося). У такому випадку не потрібні додаткові виклики Platform.exit або setOnCloseRequest.


будь-ласка, надайте робочий приклад - у мене не вийшло
Вольфганг Фаль
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.