简体   繁体   中英

Java swing concurrency, multiple propertychangelisteners?

I have a panel called DataPanel which extends JPanel, and a worker called DataPanelWorker which extends SwingWorker.

Currently when I create the DataPanel, I start the DataPanelWorker which does some calculations and fires property changes after each calculation.

The DataPanel listens for these property changes and displays a message each time. eg "Calculation 1 complete" "Calculation 2 complete"

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. I register DataPanel2 as another propertyChangeListener on DataPanelWorker.

My problem is I might register DataPanel2 after calculation 1 has been completed and the first propertyChangeEvent has been fired. How can I know how far through the worker is so that I can get DataPanel2 to be displaying the same messages as 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. 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.

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 . In this way, your DataModel always has the complete state of the calculation. Any listening DataPanel can ask the DataModel for the current List<Calculation> to display. Your DataModel can notify listeners of the arrival of new data using any of the approaches shown here . This example updates a JLabel ; this example also updates a chart; this example updates the TableModel of a listening JTable .

DataPanelWorker …does some calculations and fires property changes after each calculation.

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. Instead, update your DataModel in your implementation of process() , which synchronizes access for you. The DataModel can then fire events for registered listeners, knowing that updates will happen on the event dispatch thread .

Is there a way to pause the doInBackground() thread?

It's permitted, but you should't have to do so in this context. If necessary, multiple workers can cooperate as shown here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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