JavaFX-从另一个线程更新TextArea并缺少迭代
我正在用Java编写一个程序,它使用遗传算法将一组数字分成两组,使它们的和等于或尽可能接近等于。程序应该将每次迭代的结果附加到TextArea中。我不希望程序在进行计算时冻结,所以我将逻辑放在另一个线程中。更具体地说:JavaFX-从另一个线程更新TextArea并缺少迭代,java,multithreading,javafx,Java,Multithreading,Javafx,我正在用Java编写一个程序,它使用遗传算法将一组数字分成两组,使它们的和等于或尽可能接近等于。程序应该将每次迭代的结果附加到TextArea中。我不希望程序在进行计算时冻结,所以我将逻辑放在另一个线程中。更具体地说: 我创建了类Runner,它扩展了任务。BestSample是我的类,它在这里用于打印迭代编号和在此迭代中找到的最佳解决方案列表。它还更新了ProgressBas,但并不重要。我通过在我的控制器类中添加以下行来实现:runnerProgressPB.progressProperty
runner.valueProperty().addListener((可观察、旧值、新值)->{
resultsTA.appendText(newValue+“\n”);})代码>
while (!this.done) {
for (int i = 0; i < this.iterations; i++) {
current = this.population.get(i);
theBestOnes = current.getTheBestSpecimen();
bestCase = new BestSpecimen(i+1, theBestOnes);
this.updateValue(bestCase);
this.updateProgress(i, iterations);
next = Population.createParentPopulationFromExistingOne(current);
next.fillPopulation();
this.population.add(this.population.size(), next);
}
done = true;
}
return null;
while(!this.done){
for(int i=0;i
Task
中的updateXXX
方法完全按照它们说的做:它们更新属性的值。更新在FX应用程序线程上执行。由于目的是提供一个可以在UI中观察到的值,如果在帧渲染之间多次更改该值,则实际上只会使用帧每次渲染时的最新值。这在以下文件中明确说明:
更新“值”属性。对updateValue的调用被合并并运行
稍后在FX应用程序线程上,甚至从
FX应用程序线程不一定会导致立即
此属性的更新和中间值可以合并到
保存事件通知
最简单的解决方案如下(尽管由于以下原因,它可能无法很好地运行):
while (!this.done) {
for (int i = 0; i < this.iterations; i++) {
current = this.population.get(i);
theBestOnes = current.getTheBestSpecimen();
bestCase = new BestSpecimen(i+1, theBestOnes);
final String text = bestCase.toString()"+\n";
Platform.runLater(() -> resultsTA.appendText(text));
this.updateProgress(i, iterations);
next = Population.createParentPopulationFromExistingOne(current);
next.fillPopulation();
this.population.add(this.population.size(), next);
}
done = true;
}
return null;
现在你的任务是什么
for (int i = 0; i < this.iterations; i++) {
current = this.population.get(i);
theBestOnes = current.getTheBestSpecimen();
bestCase = new BestSpecimen(i+1, theBestOnes);
final String text = bestCase.toString()+"\n";
textQueue.put(text);
this.updateProgress(i, iterations);
next = Population.createParentPopulationFromExistingOne(current);
next.fillPopulation();
this.population.add(this.population.size(), next);
}
return null;
即使这样,它的性能也可能不太好,因为可能有大量的文本(以及大量的字符串连接来构建它)您可以考虑使用<代码> ListView < /C>而不是<代码> TeTaRea<代码>,在这种情况下,您可以将队列直接排到列表视图的项。 < P> <代码> UpDeXXXX < /Case>方法> <代码>任务>代码>按照它们所说的:它们更新属性的值。其目的是提供一个可以在UI中观察到的值,如果该值在帧渲染之间多次更改,则实际上只会使用帧每次渲染时的最新值。这在: 更新value属性。合并并运行对updateValue的调用 稍后在FX应用程序线程上,甚至从 FX应用程序线程不一定会导致立即 此属性的更新和中间值可以合并到 保存事件通知 最简单的解决方案如下(尽管由于以下原因,它可能无法很好地运行):
while (!this.done) {
for (int i = 0; i < this.iterations; i++) {
current = this.population.get(i);
theBestOnes = current.getTheBestSpecimen();
bestCase = new BestSpecimen(i+1, theBestOnes);
final String text = bestCase.toString()"+\n";
Platform.runLater(() -> resultsTA.appendText(text));
this.updateProgress(i, iterations);
next = Population.createParentPopulationFromExistingOne(current);
next.fillPopulation();
this.population.add(this.population.size(), next);
}
done = true;
}
return null;
现在你的任务是什么
for (int i = 0; i < this.iterations; i++) {
current = this.population.get(i);
theBestOnes = current.getTheBestSpecimen();
bestCase = new BestSpecimen(i+1, theBestOnes);
final String text = bestCase.toString()+"\n";
textQueue.put(text);
this.updateProgress(i, iterations);
next = Population.createParentPopulationFromExistingOne(current);
next.fillPopulation();
this.population.add(this.population.size(), next);
}
return null;
这可能不太好,因为可能有大量的文本(和大量的字符串连接来构建它)。您可以考虑使用<代码> ListView < /C> >而不是<代码> TetraRea<代码>,在这种情况下,您可以将队列直接排到列表视图的项。
所有<代码> UpDATEXXX(…)方法旨在设置属性的值,而不是提供值流。因此,它们可能会将多个调用合并为一个调用(特别是,如果在两个相邻帧渲染之间多次更新值,则可能会发生这种情况)。您需要显式附加到FX应用程序线程上的文本区域。(请注意,如果您的输出很大,则文本区域可能不是最佳选项。)我如何执行此操作?我运行我的计算