2012-07-21 200 views
1

我的代码如下不工作,任何人都可以告诉我为什么?请更正我的代码,我对Java很新。除此之外,我正在寻找“加载面板组件”,类似ProgressMonitor,但可能更具吸引力并且动画效果更好。如果有人曾经使用过这种东西,请告诉我。Java ProgressMonitor不工作

public class Main extends JFrame { 

    private JPanel contentPane; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        Main frame = new Main(); 
        frame.setVisible(true); 

        ProgressMonitor pm = new ProgressMonitor(frame, "Loading...", 
          "waiting...", 
          0, 100000); 

        for (int i = 0 ; i < 100000 ; i ++){ 

         pm.setProgress(i); 
         pm.setNote("Testing"); 
         System.out.println(i); 

         Thread.sleep(1000); 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the frame. 
    */ 
    public Main() { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 450, 300); 
     contentPane = new JPanel(); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     contentPane.setLayout(new BorderLayout(0, 0)); 
     setContentPane(contentPane); 
    } 

} 

回答

8

正如@Mark Rotteveel已经指出的那样,您正在保留EDT(Event Dispatch Thread)。有关'How to show progress bars/monitors'的教程包含有价值的信息和代码示例。

但基本上归结为将计算移动到工作线程(例如使用SwingWorker),并在EDT上显示ProgressMonitor。由工作者线程向ProgressMonitor表明已经取得了哪些进展。

而且here是直接链接到该教程清楚地说明了如何在工作中SwingWorker扩展名(在这个例子中Task类)完成的示例代码和ProgressMonitor得到如何通过添加一个PropertyChangeListener的更新SwingWorker,听众将进度传递给ProgressMonitor

我还建议阅读Concurrency in Swing教程包含有关如何在组合处理Thread s的摇摆的更多信息,以及为什么你不能/不应该做的EDT

+0

你的答案是最好的!汗水,终于我设法经过长时间的努力才得以实现。 – GMsoF 2012-07-21 11:25:33

5

在Swing中,事件线程是修改和更新GUI的东西。你保持事件线程忙于该循环和睡眠,所以它不能更新GUI。你在事件线程上做的所有事情都应该是短暂的。其他一切都应该从事件线程中移除。

因此,您需要将该for-loop移出事件线程。

+0

请,能告诉我该怎么做?我一直在Google上搜索,这些例子非常复杂......请简单的工作代码就可以了。 – GMsoF 2012-07-21 08:18:56

+0

@GMsoF http://www.java2s.com/Code/Java/Swing-JFC/A进展演示Monitortoolbar.htm&http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html – dontcare 2012-07-21 08:59:39

4

1重计算。将此视为经验法则,UI工作在UI线程上,非UI工作在非UI线程上

2.事件发送器线程(EDT)是UI线程这里了,所以你应该保持对EDT的一个单独的线程OUT您非UI进程密集的工作。

您可以通过两种方式做到这一点.....

我。创建一个单独线程来执行此操作。

ii。使用SwingWorker来同步非UI和UI线程。

4.始终保持仅用于使JFrame的在EDT可见main()方法。

如:

public static void main(String[] args){ 

     EventQueue.invokeLater(new Runnable(){ 

     public void run(){ 

      myframe.setVisible(true); 

      } 
     } 
     } 

看看这个网站的SwingWorker的工作示例:

http://www.kodejava.org/examples/381.html