这个问题可能重复,因为我发现了很多类似的问题,但并没有解决我的问题:我需要从其他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);
    }
}

07-24 09:37
查看更多