JavaFX не запускает GIF в отдельном потоке

 
 
 
Сообщения:1
Салют.

Заранее извиняюсь за много букв, но возвращаюсь к этой проблеме уже второй день и перепробовал несколько решений, плюс ни на нашем, ни на общем stackoverflow работающего ответа не получил. Так что - надеюсь на помощь здесь.

Суть: на GUI (JavaFX) есть кнопка, которая должна запускать два процесса: основной код программы (прим. 2 секунды) и гифку ожидания, которая крутится поверх GUI. Соответственно, код выполнился - гифка завершилась.

Что я сделал сейчас:
На метод действия кнопки забиндил флаг isStarted, который получает true при нажатии на кнопку и false - после завершения основного кода. В main'е перед запуском GUI я создал Task, который проверяет флаг в бесконечном цикле и как только получает true - запускает мою гифку отдельным методом showGif(). Использовать Task мне порекомендовали, как аналог Platform.runLater() (который ранее не сработал корректно), чтобы избежать исключения "IllegalStateException: not on FX application thread".

Что получилось:
Цикл запускается, но метод showGif() останавливается на строке pane.setCenter(hb). GIF вообще не открывается.

Main:
    

public static void main(String[] args) {
 
        task = new Task<Object>() {
            @Override protected Object call() throws Exception {
 
                out:
                while (true) {
                    System.out.println("в цикле");
                    if (isStarted){
                        System.out.println("запускаю метод");
 
//                        Platform.runLater(() ->
                          showGif();
 
                          // этот комментарий не выводится в консоль
                        System.out.println("метод запущен");
                        break out;
                    }
                }
 
                return null;
            }
        };
 
        new Thread(task).start();
 
        Application.launch(args);
 
    }



Кнопка:

     btn_find.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent event) {
                // отправляет введенную пользователем ссылку в обработку, показывает гифку ожидания
 
                isStarted = true;
 
                String line = fieldUrls.getText();
                List<String> urls = Arrays.asList(line.split("\n"));
 
                for (String str : urls) {
                    controller.startParse(str);
                    System.out.println(str);
                }
 
                isStarted = false;
            }
        });


Метод showGif():

    protected static void showGif() {
 
        System.out.println("opening GIF...");
 
        File file = new File("/Users/user/Desktop/cat-preloader.gif");
 
        String localUrl = null;
        try {
            localUrl = file.toURI().toURL().toString();
 
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        Image image = new Image(localUrl, 200,200, false, true);
        ImageView imageView = new ImageView(image);
 
        hb = new HBox();
 
        hb.setStyle("-fx-background-color: lightgrey");
        hb.setOpacity(0.7);
        hb.getChildren().add(imageView);
        HBox.setMargin(imageView, new Insets(300, 100, 60, 200));
        BorderPane.setMargin(hb, new Insets(0, 0,600, 0));
 
        System.out.println("setting the pane");
        pane.setCenter(hb); // метод останавливается здесь
        System.out.println("GIF started");
 
    }


Вот вывод в консоль:



Результат: поток запускается перед основным кодом, цикл крутится, GIF не открывается.
Я добавил Platform.runLater() перед вызовом метода showGif() в Task'е:

    public static void main(String[] args) {
 
        task = new Task<Object>() {
            @Override protected Object call() throws Exception {
 
                out:
                while (true) {
                    System.out.println("в цикле");
                    if (isStarted){
                        System.out.println("запускаю метод");
 
                        Platform.runLater(() ->
                          showGif());
 
                          // этот комментарий теперь успешно выводится в консоль
                        System.out.println("метод запущен");
                        break out;
                    }
                }
 
                return null;
            }
        };
 
        new Thread(task).start();
 
        Application.launch(args);
 
    }


Теперь цикл отрабатывает полностью, показывает комментарий "метод запущен" (раньше не выводил), но метод showGif() исполняется только после всего основного когда. GIF открывается, но уже не нужна. Консоль:

Перед выолнением основного кода:


После выполнения основного кода:


Я так же использовал вызов метода showGif()) через Platform.runLater() сразу в методе кнопки, безо всяких циклов, флагов и Task'ов - результат был тот же (GIF запускается, но уже в конце работы программы.) Кроме того, я добавлял три секунды задержки в основной код, полагая, что гифке не хватило времени - результат тот же.

Подскажите, что я делаю не так? Сам я уже не вижу вариантов.
Изменен:09 янв 2019 09:06
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет