简体   繁体   English

Java swing并发,多个propertychangelisteners?

[英]Java swing concurrency, multiple propertychangelisteners?

I have a panel called DataPanel which extends JPanel, and a worker called DataPanelWorker which extends SwingWorker. 我有一个名为DataPanel的面板,它扩展了JPanel,还有一个名为DataPanelWorker的工人,它扩展了SwingWorker。

Currently when I create the DataPanel, I start the DataPanelWorker which does some calculations and fires property changes after each calculation. 当前,当我创建DataPanel时,我会启动DataPanelWorker,它执行一些计算并在每次计算后触发属性更改。

The DataPanel listens for these property changes and displays a message each time. DataPanel侦听这些属性更改,并每次显示一条消息。 eg "Calculation 1 complete" "Calculation 2 complete" 例如,“计算1完成”“计算2完成”

This works fine! 这样很好!

What I now want to do now is create a second instance of DataPanel (let's call this DataPanel2) but I want to use the original DataPanelWorker to save computation. 现在,我想做的是创建DataPanel的第二个实例(我们称之为DataPanel2),但是我想使用原始的DataPanelWorker来保存计算。 I register DataPanel2 as another propertyChangeListener on DataPanelWorker. 我将DataPanel2注册为DataPanelWorker上的另一个propertyChangeListener。

My problem is I might register DataPanel2 after calculation 1 has been completed and the first propertyChangeEvent has been fired. 我的问题是,在计算1完成并且第一个propertyChangeEvent被触发之后,我可能会注册DataPanel2。 How can I know how far through the worker is so that I can get DataPanel2 to be displaying the same messages as DataPanel1? 我如何知道工作人员的距离,以便使DataPanel2显示与DataPanel1相同的消息?

What I would like ideally is to keep a queue of propertyChangeEvents and when registering a new component, fire them all on just that component. 我理想的情况是保留一个propertyChangeEvents队列,并在注册新组件时将它们全部触发该组件。 Is there a standard way of doing this? 有这样做的标准方法吗? Or am I looking at it from the wrong view? 还是我从错误的角度看待它?

Thanks 谢谢

Conceptually, your SwingWorker should publish() interim instances of Calculation so that process() can update your DataModel and notify any listeners. 从概念上讲,您的SwingWorker应该publish() Calculation临时实例,以便process()可以更新您的DataModel并通知任何侦听器。

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

Your implementation of process() can then update your DataModel on the event dispatch thread . 然后,您的process()可以在事件分发线程上更新您的DataModel In this way, your DataModel always has the complete state of the calculation. 这样,您的DataModel始终具有计算的完整状态。 Any listening DataPanel can ask the DataModel for the current List<Calculation> to display. 任何侦听的DataPanel都可以要求DataModel显示当前的List<Calculation> Your DataModel can notify listeners of the arrival of new data using any of the approaches shown here . 您的DataModel可以使用此处显示的任何方法,将新数据的到达通知给侦听器。 This example updates a JLabel ; 这个例子更新了一个JLabel ; this example also updates a chart; 示例还更新了图表; this example updates the TableModel of a listening JTable . 示例更新了侦听JTableTableModel

DataPanelWorker …does some calculations and fires property changes after each calculation. DataPanelWorker …进行一些计算,并在每次计算后触发属性更改。

Avoid firing property change events in your implementation of doInBackground() , as access to any shared data will need to be synchronized independently of the worker. 避免在doInBackground()实现中触发属性更改事件,因为对任何共享数据的访问都需要独立于worker进行同步。 Instead, update your DataModel in your implementation of process() , which synchronizes access for you. 而是在process()实现中更新DataModel ,它为您同步访问。 The DataModel can then fire events for registered listeners, knowing that updates will happen on the event dispatch thread . 然后, DataModel可以知道已在事件调度线程上发生更新,从而为注册的侦听器触发事件​​。

Is there a way to pause the doInBackground() thread? 有没有办法暂停doInBackground()线程?

It's permitted, but you should't have to do so in this context. 这是允许的,但是在这种情况下您不必这样做。 If necessary, multiple workers can cooperate as shown here . 如有必要,多个工人可以按此处所示进行合作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM