2012-07-21 202 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