2014-09-03 74 views
0

這裏是一個小一例子:進度條與線程(的Java Swing)

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           
     int x = 0; 
     while (jProgressBar1.getValue() < 100) { 
      try { 
       Thread.sleep(50); 
       x++; 
       jProgressBar1.setValue(x); 
       jProgressBar1.repaint(); 
      } catch (InterruptedException ex) { 
       Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex); 
      } 
      System.out.println(jProgressBar1.getValue()); 
     } 
    } 

System.out.println(jProgressBar1.getValue());回到位數IDE輸出,但jProgressBar1不畫這個值。這段代碼有什麼問題?請幫忙。

+0

試圖尋找到使用'SwingWorker' – EpicPandaForce 2014-09-03 14:07:55

+0

http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html – 2014-09-03 14:08:21

+0

我提供了一個例子,如何它應該被執行。 – 2014-09-03 14:15:38

回答

1

在Swing線程中不要使用Thread.sleep()方法。改爲使用javax.swing.Timer。

例子:

private void jButton1ActionPerformed(ActionEvent evt) {           
    final Timer t = new Timer(50, new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      jProgressBar1.setValue(jProgressBar1.getValue() + 1); 
      if (jProgressBar1.getValue() == 100) { 
       ((Timer) e.getSource()).stop(); 
      } 
     } 
    }); 
    t.start(); 
} 
+0

't.stop();'是錯誤的參數 - 「變量t可能未被初始化」... – obohovyk 2014-09-03 14:23:46

+0

@alexkowalski我已更正了示例。 – 2014-09-03 14:45:25

+0

是的,它可以工作,但它非常快速地填充進度條。我怎樣才能改變一個達賴? – obohovyk 2014-09-03 15:02:43

-1

問題是,你正在調用.repaint()在你正在做「工作」(Thread.sleep)的同一線程中。 "repaint() does not invoke paint() directly. It schedules a call to an intermediate method, update(). Finally, update() calls paint()..."。這意味着你正在安排一堆repaint()調用,但它們沒有被處理。我還會打賭,一旦數值達到100,進度條就跳到滿了,這是因爲主線程已經結束,所有的repaint()調用終於被處理了。

爲了使jProgressBars的工作,你必須讓他們的重新繪製發生在一個不同的線程比你在做的工作(其中值得注意的也應該是在不同的線程 - 這對大多數Swing更新也是如此)。嘗試在一個新的線程開始此Runnable接口調用代碼之前:

public class ProgressBarPainter implements Runnable{ 
    public JProgressBar jProgressBar1; 
    public void run(){ 
     while(true){ 
      try { 
       Thread.sleep(50); 
       jProgressBar1.repaint(); 
      } catch (InterruptedException ex) { 
       break; 
      } 
     } 
    } 
} 

功能代碼使用上述:

public class Frame extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private JProgressBar bar; 

    public Frame(){ 
     JPanel contentPanel = (JPanel) getContentPane(); 

     JButton b = new JButton("Do Process"); 
     b.addActionListener(new ActionListener(){ 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       ProgressBarPainter p = new ProgressBarPainter(); 
       p.jProgressBar1 = bar; //Fill in with the bar you want painted 
       Thread t = new Thread(p); 
       t.start(); 

       Worker w = new Worker(); 
       w.jProgressBar1 = bar; 
       Thread t2 = new Thread(w); 
       t2.start(); 
      } 

     }); 
     contentPanel.add(b, BorderLayout.SOUTH); 

     bar = new JProgressBar(); 
     contentPanel.add(bar, BorderLayout.CENTER); 

     pack(); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     new Frame(); 
    } 

} 

class Worker implements Runnable{ 
    public JProgressBar jProgressBar1; 
    public void run(){ 
     int x = 0; 
     while(jProgressBar1.getValue() != jProgressBar1.getMaximum()){ 
      try { 
       //Do some work 
       Thread.sleep(50); 
       //Update bar 
       jProgressBar1.setValue(x++); 
      } catch (InterruptedException ex) { 
       break; 
      } 
     } 
    } 
} 

class ProgressBarPainter implements Runnable{ 
    public JProgressBar jProgressBar1; 
    public void run(){ 
     while(true){ 
      try { 
       Thread.sleep(50); 
       jProgressBar1.repaint(); 
      } catch (InterruptedException ex) { 
       break; 
      } 
     } 
    } 
} 
+0

沒有它,它不工作...... 我認爲線程有問題。我用另一個代碼對其進行了測試: 'int values [] = {1,5,9,20,22,25,45,50,55,70,80,90,99,100};' for(int value :值){ 嘗試Thread.sleep(50); }' jProgressBar1.setValue(value);} } catch(InterruptedException ex){ Logger.getLogger(MainWindow.class.getName()).... } } – obohovyk 2014-09-03 14:06:52

+0

這永遠不會工作。 – 2014-09-03 14:14:29

+0

不要**使用Thread.sleep(),因爲它會凍結你的Swing應用程序。 相反,您應該使用'javax.swing.Timer'。 – DavidPostill 2014-09-03 14:34:52