Java swing并发性,多个propertychangelisteners?

Java swing并发性,多个propertychangelisteners?

问题描述:

我有一个名为DataPanel的面板,它扩展了JPanel,还有一个名为DataPanelWorker的工作器,它扩展了SwingWorker。Java swing并发性,多个propertychangelisteners?

当前,当我创建DataPanel时,我启动DataPanelWorker,它执行一些计算并在每次计算后触发属性更改。

DataPanel监听这些属性更改并每次显示一条消息。 例如 “计算1完成” “计算2完成”

这工作正常!我现在想要做的是创建DataPanel的第二个实例(我们称之为DataPanel2),但我想使用原始的DataPanelWorker来保存计算。我将DataPanel2注册为DataPanelWorker上的另一个propertyChangeListener。

我的问题是我可能注册DataPanel2后计算1已完成,并已触发第一个propertyChangeEvent。 我如何知道工作人员有多远,以便我可以让DataPanel2显示与DataPanel1相同的消息?

我最希望的是保留一个propertyChangeEvents队列,并在注册一个新组件时,将它们全部放在该组件上。有没有这样做的标准方式?或者我从错误的角度看待它?

感谢

+1

为什么不让工作人员持有状态更改列表,并简单地查询此列表的状态? –

+0

我很担心在完成查看这个列表和注册新的监听者之间的纳秒级中被触发的事件。大概你会在注视事件后注册听众,如果我们之前做过,我们可能会事件两次。 –

+0

有没有一种方法可以暂停doInBackground()线程以从此列表中构建第二个面板,确保我们不会错过任何属性更改? –

概念,您应该SwingWorkerCalculationpublish()临时实例,以便process()可以更新您的DataModel并通知所有侦听器。

class DataPanelWorker extends SwingWorker<List<Calculation>, Calculation> {…} 
class DataModel { 
    private List<Calculation> list = new ArrayList<>(); 
    … 
} 

然后你实现process()可以更新您的DataModel事件调度线程上。这样,您的DataModel总是具有完整的计算状态。任何收听DataPanel都可以要求DataModel显示当前的List<Calculation>。您的DataModel可以使用here所示的任何方法通知听众新数据的到达。 example更新了JLabel;这example也更新图表;此example更新了收听JTableTableModel

DataPanelWorker ...做了一些计算并在每次计算后触发属性更改。

避免在执行doInBackground()时触发属性更改事件,因为访问任何共享数据需要独立于工作人员进行同步。相反,在您的实施process()中更新您的DataModel,这会为您同步访问权限。然后,DataModel可以为已注册的侦听器触发事件​​,并知道更新将在事件分派线程上发生。

有没有办法暂停doInBackground()线程?

这是允许的,但在这种情况下你不应该这样做。如有必要,多位工作人员可以合作,如图所示here

+1

我喜欢这个想法。这种方式只能在一个线程上操作,读取或写入列表。 –

+0

是的,这更有意义。我没有想过要有一个DataModel。好多了 - 谢谢! –

+1

@DuaneAllman:在Swing [体系结构](http://www.oracle.com/technetwork/java/architecture-142923.html)中很常见。你会想通过一些例子,但是你可以在'DataModel'中重用你的属性改变事件。 – trashgod