这个问题可能重复,因为我发现了很多类似的问题,但并没有解决我的问题:我需要从其他SwingWorker更新SWING应用程序的视图。
我有一个带有JTextArea和JTable的View类,在执行线程期间需要更新它。该视图还具有启动所有线程的“开始”按钮。
控制器侦听要单击的按钮,然后启动线程:
public class MonitorPageController {
private MonitorPage monitorPage;
private List<Mission> missions;
class StartButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < missions.size(); i++) {
MyWorker worker = new MyWorker(missions.get(i));
worker.execute();
}
}
}
}
然后,我有MyWorker类来管理模型:
public class MyWorker extends SwingWorker<Integer, String> {
private Mission m;
//<dec>
Block block1 = new Block();
Block block2 = new block();
Block block3 = new Block();
Block block4 = new Block();
public MyWorker(Mission mission) {
this.m = mission;
}
@Override
protected Integer doInBackground() throws Exception {
//<exe>
block1.addObserver(block2);
block2.addObserver(block3);
block3.addObserver(block4);
block4.addObserver(block2);
block1.update(null, m);
return 4;
}
}
最后,我有了Block类,我需要在其中更新GUI(JTable和JTextArea):
public class Block extends Node implements Observer {
public Mission run(Mission m) {
m.setStatus(Mission.UNEXECUTED);
// HERE I WANT TO NOTIGY THE VIEW OF THE CHANGE OF STATUS OF THE MISSION
return m;
}
@Override
public void update(Observable o, Object arg) {
Mission m = this.run((Mission) arg);
setChanged();
notifyObservers(m);
}
}
编辑:使命是具有属性的简单类:整数状态
我已经尝试了另一种观察者模式:我将任务设置为可观察,并将MonitorPageController设置为观察者。然后,在Mission类的状态的setter方法中,添加了setChanged()和notifyObservers()方法。最后,在Observer(MonitoPageController)中,我实现了update()方法来调用视图并更新gui。
我喜欢这种方式,因为它很干净并且易于实现,但是我现在不为什么为什么在调用notifyObserver()之后什么也没有发生,所以我放弃了这种解决方案,即使它似乎是正确的解决方案
最佳答案
更新UI调用SwingUtilities.invokeLater():
public class Block extends Node implements Observer {
public Mission run(Mission m) {
m.setStatus(Mission.UNEXECUTED);
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
//UPDATE UI HERE
}
});
return m;
}
@Override
public void update(Observable o, Object arg) {
Mission m = this.run((Mission) arg);
setChanged();
notifyObservers(m);
}
}