有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java线程未更新GlassPane上的进度条

在下面的应用程序中,我放置了一个按钮,点击该按钮可以看到GlassPane,并启动一个线程来更新进度条的值。代码如下:-

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;


public class GlassPaneDownload extends JFrame implements Runnable{
Thread t;
CustomGlassPane jp;

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

public GlassPaneDownload(){
super("Glass Pane Download Simulation");
setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());    

jp=new CustomGlassPane();

jp.setOpaque(false);
setGlassPane(jp);


JButton btn=new JButton("Click Here");
btn.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){
    //Make Glass Pane visible
    jp.setVisible(true);
    //Start Thread to update Progress Bar
    t=new Thread();
    t.start();
}});
add(btn);
setVisible(true);
}
public void run(){
for(int i=1;i<=100;i++)
{
    jp.setProgress(i);
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
t=null;
}
}

class CustomGlassPane extends JComponent
{


    private final float pattern[]=new float[]{0.0f,0.499f,0.50f,1.0f};
    private final Color color[]=new Color[]{Color.WHITE,Color.GRAY,Color.BLACK,Color.LIGHT_GRAY};
    private int progress,oldProgress;


    public void paintComponent(Graphics g1)
    {
        super.paintComponent(g1);
        g1.setColor(new Color(1.0f,1.0f,1.0f,0.7f));
        g1.fillRect(0, 0, getWidth(), getHeight());
        g1.setColor(new Color(200,200,255));
        g1.drawRect(100,100,200,20);

        LinearGradientPaint p=new LinearGradientPaint(100,100,200,20,pattern,color);
        Graphics2D g2=(Graphics2D)g1;
        g2.setPaint(p);
        g2.fillRect(100, 100,progress*2, 20);
    }
    public void setProgress(int prog)
    {
        progress=prog;
        repaint(100,100,200,20);
        //repaint();
    }

}

但是,尽管GlassPane变得可见,但ProgressBar没有更新。 需要帮助的朋友


共 (1) 个答案

  1. # 1 楼答案

    这是一个典型的错误:您正在使用Thread.sleep()上的循环来阻止EDT(事件调度线程)。EDT发送所有GUI事件:绘制事件、鼠标事件、按键事件、动作事件等。。。由于您正在EDT中循环和睡眠(在ActionEvent期间),它会阻止显示刷新(我敢打赌,您的GUI在单击按钮后会变得无响应)。所以

    • 规则#1:不要阻止EDT
    • 规则#2:不要阻止EDT,这会直接导致
    • 规则#3:不要在EDT中sleep(),以及
    • 规则#4:不要在EDT中执行任何长时间的操作

    要解决此问题,请使用SwingWorkerjavax.swing.Timer。这也适用于传统的ThreadExecutors(线程池),但必须确保所有修改GUI的尝试都在EDT中执行

    你可能想看看this example,它展示了如何将JProgressBar和SwingWorker结合起来