我的JProgressBar没有更新直到100%

Pat*_*one 4 java swing swingworker jprogressbar runnable

好的,我有以下代码.

public class MyProgressBar extends JPanel implements MyData, Serializable {

    /**
     * 
     */

    public static final int MAX                = 10000;
    public static final int WIDTH              = 400;
    public static final int HEIGHT             = 75;

    private JProgressBar    MyBar              = new JProgressBar( SwingConstants.HORIZONTAL, 0, MAX );
    private JFrame          MyFrame            = new JFrame();

    private int             MyValue            = 0;

    private Thread          MyThread           = new Thread( new ProgressThread() );



    public MyProgressBar() {
        add(MyBar);

        int x = ( MyData.SCREEN.width  / 2 ) - ( WIDTH  / 2);
        int y = ( MyData.SCREEN.height / 2 ) - ( HEIGHT / 2);

        this.setBounds( x, y, WIDTH, HEIGHT );

        MyFrame.setBounds( x, y, WIDTH, HEIGHT );
        MyFrame.setUndecorated(true);
        MyFrame.getContentPane().setSize( new Dimension( WIDTH, HEIGHT ) );
        MyFrame.setMinimumSize( new Dimension( WIDTH, HEIGHT ) );
        MyFrame.setPreferredSize( new Dimension( WIDTH, HEIGHT ) );
        MyFrame.setSize( new Dimension( WIDTH, HEIGHT ) );
        MyFrame.setVisible(false);
        MyFrame.getContentPane().setLayout(null);

        MyBar.setStringPainted( true );
        MyBar.setBorderPainted( true );
        MyBar.setValue( 0 );
        MyBar.setBounds( 0, 0, WIDTH, HEIGHT );

        MyFrame.add( MyBar );
        MyFrame.pack();
        MyFrame.repaint();

    }

    public void MyUpdateBar() {
        MyBar.setValue( MyValue );
        MyBar.repaint();
        MyFrame.repaint();
        this.repaint();
        //dbug.Message( "MYPROGRESSBAR", "MyUpdateBar", "Value is %3.2f %d", MyBar.getPercentComplete(), MyValue );
    }

    public void MySetValue( int percent ) {
        MyValue = (int)( MAX * ( (double)percent / 100.0 ) );
        MyUpdateBar();
        //dbug.Message( "MYPROGRESSBAR", "MySetValue", "Value is %3.2f %d percent was %d", MyBar.getPercentComplete(), MyValue, percent );
    }

    public void CreateAndShow () {
        MyFrame.setVisible(true);
        MyThread.start();
    }

    public void HideAndClear () {
        MyThread.stop();
        //frame.setVisible(false);
    }

    class ProgressThread implements Runnable {
        public void run() {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    while( MyValue < MyBar.getMaximum() ) {
                        MyBar.setValue( MyValue );
                        MyBar.repaint();
                        MyFrame.repaint();
                        dbug.Message( "MYPROGRESSBAR", "THREAD", "Value is %3.2f %d", MyBar.getPercentComplete(), MyValue );
                    }
                }
            });
        }

    }



}
Run Code Online (Sandbox Code Playgroud)

如您所见,我创建了一个我希望显示进度的类.发生的事情是我实例化该类.加载我的XML文件,然后当我解析数据时,我正在调用更新MyValue,当我让我的dbug消息出来时,我会看到它.然而,酒吧本身甚至在100%完成之前都不显示.我已经阅读了关于线程和跟随别人的例子的内容,如果我把它作为他的例子就可以了.如果我做了一些调整(更改线程中的循环以填充进度条的setvalue以读取值),它甚至不显示直到它为100.

我做错了什么?

谢谢!

ten*_*ica 14

你执行线程SwingUtilities.invokeLater.你实际上是在Swing上运行的Event Dispatch Thread.不确定你想要达到什么目的.但看起来你是阻塞的EDT,你的while循环没有更新,因为MySetValue没有执行.

考虑使用SwingWorker冗长的操作.如何使用进度条演示使用的SwingWorkerJProgressBar.

确保setValue从中调用方法Event Dispatch Thread.你可以用SwingUtilities.invokeLater它.阅读有关Threads和Swing的更多信息.

考虑这个简化的示例:

public static void main(String[] arguments) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);

    final JProgressBar bar = new JProgressBar(0, 100);

    Thread t = new Thread(){
        public void run(){
            for(int i = 0 ; i < 100 ; i++){
                final int percent = i;
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        bar.setValue(percent);
                    }
                  });

                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {}
            }
        }
    };
    frame.add(bar);
    frame.pack();
    frame.setVisible(true);
    t.start();
}
Run Code Online (Sandbox Code Playgroud)


Gui*_*let 5

问题是您在EDT中使用循环来更新进度.在该循环退出之前,EDT无法调度事件(如重绘,重新验证,invokeLater,鼠标事件,键事件等等),从而无法刷新进度条.

您应该尝试找到一种方法让EDT在每次更新进度条之间调度其事件.理想情况下,您使用SwingWorker将您的"工作"移到EDT之外,同时通过EDT中的属性更改侦听器更新进度条.

对于您的信息,在Java中,方法和变量以小写字母开头.你的代码真的很难为别人阅读.