Потоки в JavaFX

421
07 марта 2018, 07:31

Есть фрагмент кода:

public class LyricNN extends Application {
    @Override
    public void start(Stage primaryStage) {
        VBox root = new VBox(5);
        HBox vhidDann = new HBox(5);
        root.getChildren().add(vhidDann);
        Label lbl = new Label("Total Error");
        NeuralNetwork nn1 = new NeuralNetwork(262, new int[]{262,262/*,262,262*/,262});
        nn1.setLabel(lbl);
        Button btn = new Button("Train");
        btn.setOnAction(act -> {
            trainNetwork(nn1);
        });
        root.getChildren().addAll(lbl,btn);
        Scene scene = new Scene(root, 450, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
    public static void trainNetwork(NeuralNetwork nn){
        new Thread(() -> {
            //obj.method1();
            double taskSet[][] = loadArrayFromFile("E:\\Users\\Den\\Desktop\\jar\\Task.txt", 4, 262);
            double answerSet[][] = loadArrayFromFile("E:\\Users\\Den\\Desktop\\jar\\Answer.txt", 4, 262);
            nn.trainNeuralNetwork(taskSet, answerSet, 0.5, 0.4);
        }).start();
    }
}

суть в том что метод trainNetwork заставляет интерфейс JavaFX подвисать, и я попробовал запустить его в отдельном потоке, но тот способ (new Thread(() -> {}).start();) запускать в отдельном потоке который известен мне не подходит, выдаёт ошибку

Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4

Подскажите как в интерфейсе JavaFX правильно запускать методы в отдельных потоках.

Upd. Проблема вот в чём: предоставленная программа - это интерфейс, а класс NeuralNetwork - выполняет логику, чтобы отображать ход выполнения логики, я передаю в класс NeuralNetwork метку (элемент интерфейса JavaFX - Label), и компилятор ругается на ошибку

Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4

именно в коде класса отвечающего за логику (NeuralNetwork) вот в этом участке кода:

if(label!=null)label.setText("total error - "+totalErr);

Надеюсь это привнесет ясность, так как приведенные ниже советы к сожалению не помогли.

Answer 1

Почти все GUI-библиотеки в мире не являются потокобезопасными. Поэтому каждая библиотека предлагает механизмы запуска фоновых задач и взаимодействия с ними. В JavaFX такими механизмами являются Service и Task:

import javafx.concurrent.Task;
import javafx.concurrent.Service;
public class LyricNN extends Application {
    ...
    btn.setOnAction(act -> {
        Service<Void> service = new Service<Void>() {
            @Override
            protected Task<Void> createTask() {
                return new Task<Void>() {
                    @Override
                    protected Void call() throws Exception {
                        trainNetwork(nn1);
                        return null;
                    }
                };
            }
        };
        service.start();
    });
    ...
    public static void trainNetwork(NeuralNetwork nn) {
        double taskSet[][] = loadArrayFromFile("E:\\Users\\Den\\Desktop\\jar\\Task.txt", 4, 262);
        double answerSet[][] = loadArrayFromFile("E:\\Users\\Den\\Desktop\\jar\\Answer.txt", 4, 262);
        nn.trainNeuralNetwork(taskSet, answerSet, 0.5, 0.4);
    }
}

Почитать можно здесь.

Answer 2

Откорректировал пример под Ваш случай (с Label) + для ознакомления:

    import javafx.application.Application;
    import javafx.concurrent.Task;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.control.ProgressBar;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    public class Test extends Application {
        public static void main(String[] args) {
            launch(args);
        }
        @Override
        public void start(Stage primaryStage) {
            VBox root = new VBox(5);
            HBox vhidDann = new HBox(5);
            root.getChildren().add(vhidDann);
            Label lbl = new Label("Total Error");
            Label lblOut = new Label("Out");
            ProgressBar bar = new ProgressBar();
            Button btn = new Button("Train");
            btn.setOnAction(act -> {
                trainNetwork(lblOut);
            });
            root.getChildren().addAll(lbl, btn, lblOut);
            Scene scene = new Scene(root, 450, 250);

            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
        public void trainNetwork(Label label) {
            Task task = new Task<Void>() {
                @Override
                public Void call() throws InterruptedException {
                    final int max = 1000;
                    for (int i = 1; i <= max; i++) {
                        if (isCancelled()) {
                            break;
                        }
                        Thread.sleep(5);

                        //updateProgress(i, max);
                        this.updateMessage(i + "");
                    }
                    return null;
                }
            };
            label.textProperty().bind(task.messageProperty());
            new Thread(task).start();
        }
    }
READ ALSO
Selenium Webdriver + jQuery локаторы

Selenium Webdriver + jQuery локаторы

Доброго времени сутокМо;но ли как-то в Selenium Webdriver реализовать метод поиска по jquery локаторам? Может быть есть подключаемая библиотека, или...

256
Почему Java на Ubuntu не может загрузить Main class?

Почему Java на Ubuntu не может загрузить Main class?

Делаю JavaFX GUIНа windows работает, но на Linix'е выдаёт:

231
Использовать только String в Java

Использовать только String в Java

Почему цикл останавливается после первого слова? удалить буквы из каждого слова,которые такие же как первая!

220
Разбор кода, из javascript в java

Разбор кода, из javascript в java

Недавно начал изучать Java & AndroidПоявился спортивный интерес разобрать код javascript Вконтакте, который дешифрует ссылку на аудиозапись и переписать...

276