0

实际上有不止1个问题。

给定模型视图和控制器。(我的耦合很多 - View 知道它的 Controller,而 Controller 知道 View。)

控制器中的新线程是否可以以基本方式触发 -new Runnable(){ (...) run(){}}或者需要以某种“摆动方式”进行操作,才能正确执行?也许与Timeror invokeLater()

第二件事是 - 假设新线程已经启动 - 当它直接在视图上运行时,设置一些JTextFields (等等) -setThatTextFieldWithNewValue(msg)由于从需要线程调用而需要同步等方法吗?如果是这样 - 有没有更好的方法可以减少耦合并减少考虑所需同步的时间?

4

4 回答 4

2

Swing 不是线程安全的

1UI线程是Event Dispatcher Thread,负责GUI工作。

2.尝试在 UI 线程之外使用非 UI 线程。

3. 是的,当然你可以从 UI 线程中触发一个线程,但建议将其置于 UI 线程之外,否则 GUI 可能看起来没有响应。

(即负责UI工作的UI线程的非UI线程OUT上的非UI工作)

4.还有一种swing方式...使用SwingWorker,它处理UI和Non-UI线程之间的同步。

编辑部分:

// 请注意,直接在框架/JFRAME 上添加组件并不好,但我这样做只是为了说明我的意思。

public class MyClass extends JFrame{

private final JButton b;

 public MyClass(){

  this.setSize(300,300);
  this.setComponent();
  this.setHandler();
}

public void setComponent(){

  b = new JButton("Click");
  this.add(b);

}

public void setHandler(){

  b.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent arg0) {

            // Do whatever you want...      

    }
});

}

public static void main (String[] args) { 
      EventQueue.invokeLater(new Runnable(){    // UI THREAD
        public void run(){

         MyClass s = new MyClass();   
         s.setVisible(true);
        }

      });
   }
}

Main 方法在 Swing 中是短暂的,main method() 将 GUI 的构建调度到事件调度线程 (EDT),然后退出。所以它的 EDT 有责任处理 GUI。因此,始终建议让非 UI 线程上的非 UI 工作远离 EDT。

于 2012-07-12T07:09:51.477 回答
2
  1. 有几种方法可以创建、管理和通知 MVC,以便更快地发布SSCCE以获得更好的帮助

  2. Runnable#Thread是一种非常舒适、稳定和清晰的方式,但我建议将所有输出到 Swing GUIinvokeLater中,包括线程安全方法setTextappend例如 ..

  3. 正如 Kumar Vivek Mitra (+1) 提到的,有SwingWorker,但需要最深入的了解,如何从 SwingWorker 获得异常Java essential classes存在一些问题exceptions recycle

  4. 关于 MVC 也许会帮助你我的类似问题

于 2012-07-12T07:43:17.073 回答
1

任何正在发生的事情都必须在 EventQueue 上运行如果你有一个从 swing 调用的方法,它将已经在那里运行(如在 Action 侦听器中)。如果您不知道您是否在事件队列中,EventQueue.isDispatchThread()会告诉您。当您知道自己不是时,请使用EventQueue.invokeLater()或者invokeAndWait如果您需要查看结果,请引用一个摇摆类或方法。(这必须从main方法中完成。)

对此要非常小心;你必须检查你的代码。如果不是这样,我的经验是摇摆 UI 会有点不稳定,偶尔会出现无法重现的奇怪现象。观察每一行代码没有简单的方法。

实际上,有。在 EventQueue 上做所有事情,你就不用担心了。无论如何,你可能不会在挥杆之外做很多工作。如果是这样,那么为了避免多线程问题而损失速度可能是值得的。如果您的非摇摆工作广泛但简单,请使用 SwingWorker 类。它在高度受控的条件下为您提供了额外的线索,并且应该为您节省很多悲伤。

您的类(视图和控制器)独立于线程,并且在一个线程中运行时应该可以正常工作。不要混淆类和线程。(我承认,我很想让控制器在各个方向触发线程,但你必须准备好非常小心,并且知道所有关于多线程的知识。)

If you do multithread, the EventQueue can be a bit handy because you don't have to protect fields referenced only there--it's an island of single threading in a dangerous sea. On the other hand, don't do any synchronization there; you'll block your UI. You can launch threads from there and you may have to just to avoid blocking. (Once you start multithreading, it's hard to stop.)

于 2012-07-12T19:55:42.037 回答
0

最简单的方法是:

        SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {

            // Run your code here.

        }
    });

对于更复杂的任务(将进程块发送到 ui 线程,响应 jobFinished):

    new SwingWorker<String, String>() {


        @Override
        protected void done() {

        }

        @Override
        protected void process(List<String> arg0) {


        }

        @Override
        protected String doInBackground() throws Exception {


        }


    }.execute();
于 2012-07-12T07:58:11.700 回答