2014-09-23 25 views
1

我想添加一個JProgressBar到一個簡單的程序來學習。到目前爲止,我可以顯示它,但它增加了多個實例,而我只需要顯示一個實例。 enter image description hereJProgressBar自我多次實例化它

下面的代碼:

package package1; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 

import javax.swing.JPanel; 
import javax.swing.JProgressBar; 

public class Opening extends JPanel { 
    private JProgressBar loadingBar; 
    private Thread t; 

public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g);  
    //Loading bar 
    bar(); 
} 

private void bar() 
{ 
    loadingBar = new JProgressBar(); 
    t = new Thread(new LoadMyBar()); 

    this.add(loadingBar).setLocation(25, 600); 
    loadingBar.setSize(625, 25); 
    loadingBar.setStringPainted(true); 
    loadingBar.setValue(0); 
    loadingBar.setMinimum(0); 
    loadingBar.setMaximum(100); 
    t.start(); 
} 

class LoadMyBar implements Runnable 
{ 
    public void run(){ 
     for(int i = loadingBar.getMinimum(); i <= loadingBar.getMaximum(); i++) 
     { 
      loadingBar.setValue(i); 
      try 
      { 
       t.sleep(1000); 
      }catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

}

任何想法是什麼我做錯了嗎?

回答

5

您在paintComponent(Graphics g)方法中調用bar()。此方法負責繪製組件,可能被多次調用,但不在您的控制之中。不要這樣做,而是在構造函數或其他可以只調用一次的位置調用它。

您還將JProgressBar的值設置爲擺脫Swing事件線程,這可能會有些危險。改爲使用Swing Timer,或者將SwingWorker的progress屬性與PropertyChangeListener一起使用。

例如,

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JProgressBar; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

@SuppressWarnings("serial") 
public class Opening extends JPanel { 
    private static final int TIMER_DELAY = 1000; 
    private JProgressBar loadingBar; 
    private Timer t = new Timer(TIMER_DELAY, new TimerListener()); 

    public Opening() { 
     bar(); 
    } 

    private void bar() { 
     loadingBar = new JProgressBar(); 
     this.add(loadingBar); 
     loadingBar.setStringPainted(true); 
     loadingBar.setValue(0); 
     loadingBar.setMinimum(0); 
     loadingBar.setMaximum(100); 
     t.start(); 
    } 

    private class TimerListener implements ActionListener { 
     int value = 0; 

     @Override 
     public void actionPerformed(ActionEvent e) { 
     if (value <= 100) { 
      loadingBar.setValue(value); 
      value++; 
     } else { 
      // value > 100 
      ((Timer) e.getSource()).stop(); // stop timer 
     } 
     } 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("Opening"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(new Opening()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
+0

如果我要來構造JProgressBar添加到JPanel我應該怎麼然後繼續?我需要JPanel,因爲它顯示了一些圖形內容(不會因爲這種方式使代碼更易讀)。 – Chax 2014-09-23 21:44:19

+0

@Chax:例如,見上面的例子。並且不要設置任何尺寸。相反,使用佈局管理器。 – 2014-09-23 21:44:50

1

您所創建的的JProgressBar並將其添加到方法的paintComponent()類開幕。 每次調用paintComponent()時,組件都需要繪製自己。

這可能是在重新調整窗口(JFrame)或某個其他應用程序重疊的應用程序的大小後。

您應該將初始化移動到Opening的構造函數。

http://docs.oracle.com/javase/tutorial/uiswing/painting/closer.html