我已经在这个主题上阅读了有关Stackoverflow的其他文章。但它们都没有完全符合我的问题。
我想在TextArea中记录算法。在算法的每次迭代中,应通过appendText()扩展此TextArea中的文本。
我的第一个问题是:我应该在哪里创建新线程以及两个线程如何相互通信(GUI和算法)?
在我的实际设计中,我有三个重要的类:视图,它包含TextArea,控制器,它调用算法和算法,需要多次迭代和TextArea(调用appendText() - 方法在代码中的代表性地点。)
在此设计中,控制器调用算法,算法使用for循环迭代n次,在终止后,GUI显示更改。但是当算法调用appendText() - 方法时,我希望GUI同时显示更改。
我的第二个问题是TextArea的自动滚动。在每次appendText调用之后,TextArea应该完全向下滚动。但我认为这个问题的解决方案是我第一个问题的解决方案。
我会非常感谢你的帮助。
答案 0 :(得分:0)
在没有(很多)更多信息的情况下完全回答你的问题几乎是不可能的,但我会使用的一般方法是让算法有一个回调来处理消息,可以通过算法的每一步。从控制器,在FX应用程序线程上传递回调的实现,该回调用消息更新文本区域。
类似的东西:
public class Algorithm {
private Consumer<String> statusCallback ;
public Algorithm(Consumer<String> statusCallback) {
this.statusCallback = statusCallback ;
}
public Algorithm() {
// by default, callback does nothing:
this(s -> {});
}
public void performAlgorithm() {
while (! finished() ) {
doNextStep();
String statusMessage = getStatus();
statusCallback.accept(statusMessage);
}
}
}
然后
public class Controller {
private View view = ... ;
public void startAlgorithm() {
Algorithm algorithm = new Algorithm(s -> Platform.runLater(view.appendStatus(s)));
Thread t = new Thread(algorithm::performAlgorithm);
t.setDaemon(true);
t.start();
}
}
对于View
,您可以执行以下操作(请注意,您可以使用textArea.setScrollTop(Double.MAX_VALUE);
向下滚动):
public class View {
private TextArea textArea ;
public View() {
textArea = new TextArea();
// ...
}
public void appendStatus(String status) {
if (!textArea.getText().isEmpty()) {
textArea.appendText("\n");
}
textArea.appendText(status);
textArea.setScrollTop(Double.MAX_VALUE);
}
}
只要您的算法没有太快地创建太多的状态更新(这样它们会使FX应用程序线程泛滥并阻止它正常工作),这应该可以正常工作。