这个问题可能会重复,因为我发现了很多类似的问题,但不是我的问题的答案:我需要从不同的SwingWorker更新我的SWING应用程序的视图。 我有一个带有JTextArea和JTable的View类,我需要在执行Threads期间更新它。视图还有一个启动按钮,可以启动所有线程。 控制器监听要单击的按钮,然后启动线程:
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);
}
}
编辑:Mission是一个简单的类,其属性为:int status
我已经尝试过另一个观察者模式:我将任务设置为observable,将MonitorPageController设置为观察者。然后在类Mission的状态的setter方法中添加了setChanged()和notifyObservers()方法。最后在Observer(MonitoPageController)中我实现了update()方法来调用视图并更新gui。 我喜欢这种方式,因为它干净且易于实现,但我现在不知道为什么在调用notifyObserver()后没有发生任何事情,所以我放弃了这个解决方案,即使它似乎是正确的
答案 0 :(得分:1)
更新调用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);
}
}
答案 1 :(得分:0)
我找到了一个可能的解决方案,也许有更好的想法,但现在可以使用: 在MonitorPageController中创建SwingWorker我也改变了传递MonitorPageController的istance的构造函数。
MyWorker worker = new MyWorker(misssions.get(i), this);
然后在MyWorker类中创建Block1,Block2时,...我将它们传递给MyWorker:
Block block1 = new Block(this);
Block block2 = new Block(this);
....
在同一个类(MyWorker)中,我创建了一个方法:
public void log(Mission m, String s) {
controller.log(m, s);
}
Controller是创建worker的MonitorPageController的基础。
现在是内部块类,当我想通知状态变化时,我可以调用:
parentWorker.log(mission, "some string");
最后,MonitorPageController中的log()方法调用view方法来更新组件......到现在它似乎工作了......