好像较新的资料里,Swing常用到invokeLater:SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        createAndShowGUI();
    }
});对此偶很不习惯,有谁能帮偶把以下使用AWT的代码改用Swing?谢谢!import java.util.Observable;public class Loader extends Observable implements Runnable
 {int counter=-1;   public String getMessage() {return ""+counter;}  public void run()
   {while(true)
     {counter++; setChanged(); notifyObservers();
      try {Thread.sleep(1000);}
      catch(Exception e)   { return;}     
     }
   }
 } import java.util.Observer;
import java.util.Observable;
import java.awt.*;
import java.awt.event.*;public class LoaderFrame implements Observer
 {Loader model; Label label; Frame frame;
  public LoaderFrame(Loader m)
   {model=m; 
    frame=new Frame("Welcome"); 
    label=new Label(model.getMessage(),Label.CENTER);
    frame.add("Center",label); frame.pack();   
    frame.setLocationRelativeTo(null);
    frame.pack(); frame.setVisible(true);
    model.addObserver(this); 
   }
  public void update(Observable t,Object o)
   {String s=model.getMessage();    
    label.setText(s); 
    frame.invalidate();frame.pack();   
   }
  public static void main(String args[]) 
   {Loader loader=new Loader();    new Thread(loader).start();
    new LoaderFrame(loader);
   } 
 }
 

解决方案 »

  1.   

    SwingUtilities.invokeLater方法是使事件派发线程上的可运行对象排队。当可运行对象排在事件派发队列的队首时,就调用其run方法。其效果是允许事件派发线程调用另一个线程中的任意一个代码块。下面那个是观察者模式的实现例子。实在要改的话,那就不用观察者模式,将LoaderFrame传入Loader,用SwingUtilities.invokeLater方法来更新LoaderFrame。跟Swing和AWT差异没有关系,两种事件机制方式而已。
      

  2.   


    偶是想把AWT组件换成Swing组件http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html
    以上链接是英文的,讲了Swing同步问题,您似乎并不了解这方面内容使用Swing后,以下代码似乎应避免:public static void main(String args[]) 
      {...
       new JFrame("test");
       ...
      }  应改用invokeLater
    偶不太熟悉,感觉很麻烦
    看来知道的人也不多
      

  3.   

    不就是因为Swing基于单线程模型,建议在入口类main方法中初始化Swing界面用下面的方法嘛:
    …………
      SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    frame = new JFrame("Java 简易浏览器");
    ……………
    知道的人挺多的,这是用Swing的常识。你把下面的类改写成
    class LoaderFrame extends JFrame implements Observer
    还有,楼主,concurrency应该翻译成”并发“或者”并行“,“同步“的E文是synchronization。基于我对Swing同步问题的不了解,我就不详细给您讲了。
      

  4.   

    感谢您的指教!
    偶已作修改,可以运行
    但是update方法并不在事件发布线程上,仍有线程安全问题,怎么办?
    (好像AWT并这些乱七八糟的问题,Swing太麻烦)import java.util.Observer;
    import java.util.Observable;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;public class LoaderJFrame extends JFrame implements Observer
     {Loader model; JLabel label;   public LoaderJFrame()
       {super("Welcome"); 
        model=new Loader(); 
        new Thread(model).start();    label=new JLabel(model.getMessage());
        getContentPane().add("Center",label); pack();   
        setLocationRelativeTo(null);//    frame.pack();
        setVisible(true);
        model.addObserver(this); 
       }
      public void update(Observable t,Object o)
       {String s=model.getMessage();    
        System.out.println(""+javax.swing.SwingUtilities.isEventDispatchThread());
        label.setText(s); 
        invalidate();pack();   
       }
      public static void main(String args[]) 
       {
        javax.swing.SwingUtilities.invokeLater
         (new Runnable(){public void run(){new LoaderJFrame();}});
       } 
     }
    /* 
       public LoaderFrame()
       {model=m; 
        frame=new Frame("Welcome"); 
        label=new Label(model.getMessage(),Label.CENTER);
        frame.add("Center",label); frame.pack();   
        frame.setLocationRelativeTo(null);
        frame.pack(); frame.setVisible(true);
        model.addObserver(this); 
       }
    */
      

  5.   

    使用 Swing 编写多线程应用程序时,记住两个约束条件:
    1、不应该在事件指派线程 上运行耗时任务。否则应用程序将无响应。 
    2、只能在事件指派线程 上访问 Swing 组件。
    import java.util.Observable;
    import java.util.Observer;import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.SwingUtilities;public class LoaderJFrame extends JFrame {

    private static final long serialVersionUID = -9115479448342376622L;
    JLabel label; public LoaderJFrame() {
    super("Welcome");
    label = new JLabel(" ");
    getContentPane().add("Center", label);
    setLocationRelativeTo(null);// frame.pack();
    setSize(200, 100);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
    setVisible(true);

    new Thread(){
    public void run() {
    new ObserverImpl();
    }
    }.start();
    } private class ObserverImpl implements Observer{
    Loader model;

    ObserverImpl(){
    model = new Loader();
    model.addObserver(this);
    new Thread(model).start();
    }

    public void update(Observable t, Object o) {
    final String message = model.getMessage();
    SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
    System.out.println(javax.swing.SwingUtilities.isEventDispatchThread());
    label.setText(message);
    }
    });
    }
    } public static void main(String args[]) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    new LoaderJFrame();
    }
    });
    }
    }class Loader extends Observable implements Runnable {
    int counter = -1; public synchronized String getMessage() {
    return "" + counter;
    } public void run() {
    while (true) {
    counter++;
    setChanged();
    notifyObservers();
    try {
    Thread.sleep(1000);
    } catch (Exception e) {
    e.printStackTrace();
    return;
    }
    }
    }
    }
      

  6.   

    感谢lxbccsu!
    没想到改用Swing后这么复杂
    看看一楼用AWT的代码多简单,也没什么问题吧!?
    偶还是用AWT算了
    其实偶的软件中也就一两个功能非用Swing不可
      

  7.   

    以下代码是不是可以了?
    太复杂的代码偶无法忍受import java.util.Observer;
    import java.util.Observable;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;public class LoaderJFrame extends JFrame implements Observer
     {Loader model; JLabel label;   public LoaderJFrame()
       {super("Welcome"); 
        model=new Loader(); 
        new Thread(model).start();    label=new JLabel(model.getMessage());
        getContentPane().add("Center",label); pack();   
        setLocationRelativeTo(null);
        setVisible(true);
        model.addObserver(this); 
       }
      public void update(Observable t,Object o)
       {javax.swing.SwingUtilities.invokeLater(new Runnable(){public void run()
         {System.out.println(""+javax.swing.SwingUtilities.isEventDispatchThread());
          label.setText(model.getMessage()); invalidate();pack();
         }});
       }
      public static void main(String args[]) 
       {
        javax.swing.SwingUtilities.invokeLater
         (new Runnable(){public void run(){new LoaderJFrame();}});
       } 
     }