Есть фрагмент кода:
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);
Надеюсь это привнесет ясность, так как приведенные ниже советы к сожалению не помогли.
Почти все 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);
}
}
Почитать можно здесь.
Откорректировал пример под Ваш случай (с 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();
}
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Доброго времени сутокМо;но ли как-то в Selenium Webdriver реализовать метод поиска по jquery локаторам? Может быть есть подключаемая библиотека, или...
Делаю JavaFX GUIНа windows работает, но на Linix'е выдаёт:
Почему цикл останавливается после первого слова? удалить буквы из каждого слова,которые такие же как первая!
Недавно начал изучать Java & AndroidПоявился спортивный интерес разобрать код javascript Вконтакте, который дешифрует ссылку на аудиозапись и переписать...