我有一个 Swing 树,由于后台线程以流方式接收树的更新,该树正在发生变化。更新可能会非常快,而且可能很复杂。而且它们的速度可能足够快,以至于之前的更新尚未呈现。我希望在应用树模型更新时,GUI 中显示的树能够尽可能快地进行可视化更新。
目前我的代码抽象如下:
public void ReceiveStreamDocument(final Document d) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
ComplexChangeToTree(d);
TreeReload();
}
});
}
现在复杂的改变很耗时,我想要的是:
public void ReceiveStreamDocument(final Document d) {
ComplexChangeToTree(d);
SwingUtilities.invokeLater(new Runnable(){
public void run(){
TreeReload();
}
});
}
但是问题似乎是对树结构的修改现在位于 swing 线程之外,并且当树实际重新渲染时可能会引发异常。拥有这样的东西似乎没有帮助:
public void ReceiveStreamDocument(final Document d) {
synchronized(root){
ComplexChangeToTree(d);
}
SwingUtilities.invokeLater(new Runnable(){
public void run(){
synchronized(root){
TreeReload();
}
}
});
}
TreeReload() 实际上并没有更新显示,而只是发出应该更新显示的信号。我相信我需要在某处覆盖绘画操作并同步根,但我不确定在哪里、如何、或者实际上什么是最佳实践。
最佳答案
关键是在后台执行尽可能多的操作,并向监听树触发尽可能少的树模型事件。使用SwingWorker
,在 doInBackground()
的实现中收集更新,您还可以在其中执行任何不会触发来自 TreeModel
的事件的解析和重新排列。 。当结果可用时,调用 publish()
来获取结果。累积结果的 List
将被合并并传递给 event dispatch thread 上的 process()
实现。以可持续的方式rate ,您还有另一个机会来优化触发更新事件。检查相关问题here .
关于具有流式更新的 Java Swing 树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37903726/