2015-12-02 38 views
1

我在我的代碼中有一個小錯誤,在google上搜索幾個小時後,我仍然沒有找到答案。問題在於進度條上方的文本不會更新。這裏是我的代碼:java swing下載吧

public class ProgressGlassPane extends JComponent { 

    private static final long serialVersionUID = -2488095988836592321L; 
    private static final int BAR_WIDTH = 200; 
    private static final int BAR_HEIGHT = 10; 
    private final Color TEXT_COLOR = new Color(0x333333); 
    @SuppressWarnings("unused") 
    private final Color BORDER_COLOR = new Color(0x333333); 
    private final float[] GRADIENT_FRACTIONS = new float[] { 0.0f, 0.499f, 
      0.5f, 1.0f }; 
    private final Color[] GRADIENT_COLORS = new Color[] { Color.GRAY, 
      Color.DARK_GRAY, Color.BLACK, Color.GRAY }; 
    private final Color GRADIENT_COLOR2 = Color.WHITE; 
    private final Color GRADIENT_COLOR1 = Color.GRAY; 

    private int progress; 
    private String message = "Downloading file(s): "; 

    public ProgressGlassPane() { 
     setBackground(Color.WHITE); 
     setFont(new Font("Default", Font.BOLD, 16)); 
     this.progress = 0; 
    } 

    public int getProgress() { 
     return progress; 
    } 

    public void setNewProgress(int progress) { 
     this.progress = progress; 
    } 

    public void setProgress(int progress) { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       // set new progress 
       int oldProgress = getProgress(); 
       setNewProgress(progress); 

       // computes the damaged area 
       FontMetrics metrics = getGraphics().getFontMetrics(getFont()); 
       int w = (int) (BAR_WIDTH * ((float) oldProgress/100.0f)); 
       int x = w + (getWidth() - BAR_WIDTH)/2; 
       int y = (getHeight() - BAR_HEIGHT)/2; 
       y += metrics.getDescent()/2; 

       w = (int) (BAR_WIDTH * ((float) progress/100.0f)) - w; 
       int h = BAR_HEIGHT; 
       // repaint 
       repaint(x, y, w, h); 
      } 
     }).start(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     // enables anti-aliasing 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 

     // gets the current clipping area 
     Rectangle clip = g.getClipBounds(); 

     // sets a 65% translucent composite 
     AlphaComposite alpha = AlphaComposite.SrcOver.derive(0.65f); 
     Composite composite = g2.getComposite(); 
     g2.setComposite(alpha); 

     // fills the background 
     g2.setColor(getBackground()); 
     g2.fillRect(clip.x, clip.y, clip.width, clip.height); 

     // centers the progress bar on screen 
     FontMetrics metrics = g.getFontMetrics(); 
     int x = (getWidth() - BAR_WIDTH)/2; 
     int y = (getHeight() - BAR_HEIGHT - metrics.getDescent())/2; 

     // draws the text 
     g2.setColor(TEXT_COLOR); 
     System.out.println("drawed string: " + message + getProgress() + "%"); 
     g2.drawString(message + getProgress() + "%", x, y); 

     // goes to the position of the progress bar 
     y += metrics.getDescent(); 

     // computes the size of the progress indicator 
     int w = (int) (BAR_WIDTH * ((float) progress/100.0f)); 
     int h = BAR_HEIGHT; 

     // draws the content of the progress bar 
     Paint paint = g2.getPaint(); 

     // bar's background 
     Paint gradient = new GradientPaint(x, y, GRADIENT_COLOR1, x, y + h, 
       GRADIENT_COLOR2); 
     g2.setPaint(gradient); 
     g2.fillRect(x, y, BAR_WIDTH, BAR_HEIGHT); 

     // actual progress 
     gradient = new LinearGradientPaint(x, y, x, y + h, GRADIENT_FRACTIONS, 
       GRADIENT_COLORS); 
     g2.setPaint(gradient); 
     g2.fillRect(x, y, w, h); 

     g2.setPaint(paint); 

     // draws the progress bar border 
     g2.drawRect(x, y, BAR_WIDTH, BAR_HEIGHT); 

     g2.setComposite(composite); 
    } 
} 

然後主:

public class Test extends JFrame { 

    private ProgressGlassPane glass; 
    private int progess = 0; 

    public Test() { 
     this.setSize(new Dimension(500, 500)); 
     this.setVisible(true); 
     this.setDefaultCloseOperation(HIDE_ON_CLOSE); 
     this.setLocation(0, 0); 

     setGlassPane(glass = new ProgressGlassPane()); 
     glass.setVisible(true); 
    } 

    public void calculateProgress() { 
     Timer timer = new Timer(); 
     timer.scheduleAtFixedRate(new TimerTask() { 
      @Override 
      public void run() { 
       System.out.println("progress: " + progess); 
       glass.setProgress(progess); 
       progess += 10; 
       if (progess > 100) { 
        timer.cancel(); 
        System.out.println("download finish"); 
       } 
      } 
     }, 0, 300); 

    } 

    public static void main(String[] args) { 
     Test test = new Test(); 
     test.calculateProgress(); 

    } 
} 

感謝您的幫助快速回答

+0

1. setProgress類中的ProgressGlassPane不應該包含new Thread(new Runnable(){,這是非生產性的,只是爲了設置一個值並調用repaint,2. Timer中public void calculateProgress(){should是Swing Timer,而不是java.util.Timer。3.(甚至這個代碼在Swing中爲Conconncy打破了所有良好習慣)它的工作在Java6,7和8中也在Win10_64b中正確地工作,4.參見關於Initilial Thread的描述too – mKorbel

+0

standard JProgressBar放置在玻璃面板比這更好的代碼,只是在UIManager的 – mKorbel

+0

的顏色設置這樣可以解決你的問題\t \t'公共無效setNewProgress(INT進展){ \t \t \t this.progress =進度; \t \t \t repaint(); \t \t}' – ashiquzzaman33

回答

1

首先感謝。 @mKorbel,我必須把一個線程,因爲在我將顯示時,從服務器上下載文件,如果我不把油漆放在它不更新的線程。

@Ashiquzzaman,非常感謝你!有效。