我的JProgressBar没有更新,直到它是100%(My JProgressBar is not

2019-09-17 00:24发布

好吧,我有下面的代码。

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 );
                    }
                }
            });
        }

    }



}

正如你所看到的,我创建了我想有一类显示进度。 会发生什么事是我实例化类。 我的加载XML文件,然后为我解析数据,我打电话来更新我看时,我让我的DBUG消息出来myvalue的。 不过,酒吧本身甚至不显示,直到它是100%完成。 我看了一下线程并按照别人的例子,如果我把它作为自己的例子,它的工作。 如果我做了一些调整(改变了线圈填充进度条的setValue方法读取值),甚至不显示,直到它是100。

我做错了什么?

谢谢!

Answer 1:

你线程执行SwingUtilities.invokeLater 。 你有效地对Swing的运行Event Dispatch Thread 。 不知道什么是你想要的目的。 但它看起来像你的封锁EDT和你while作为不更新循环MySetValue不执行。

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

请确保您拨打setValue从方法Event Dispatch Thread 。 您可以使用SwingUtilities.invokeLater了点。 了解更多关于线程和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();
}


Answer 2:

问题是,你在更新的进展EDT使用循环。 在此之前,退出循环,在美国东部时间无法调度事件(如重新粉刷,重新验证,invokeLater的,鼠标事件,键盘事件,等...),防止它刷新进度条。

你应该尝试找到一种方法,让EDT调度进度条的每次更新之间的事件。 理想情况下,你用你的移动在EDT以外的“工作” 的SwingWorker ,同时进度条打通的EDT属性更改侦听更新。

为了您的信息,在Java中,方法和变量开始用小写字母。 您的代码是真的很难读别人。



Answer 3:

所以,我试图按照教程,这里是我在哪里。

好吧,我曾尝试以下教程,但我不断收到地方丢失了。 我需要的是创建并显示进度条(不确定JProgressBar),我可以设置为我遍历从文件和地点到数据库内存加载的数据值的一类。 我的问题来了,我发现每个实例有某种计数器,填补了进度条和从“主”函数执行。 每次我改变这个教程是我可以随意调用指示条一类,我不明白了吧显示(即框架出现但酒吧甚至没有像它被添加到该帧,直到后在迭代完成)。 我一直在使用SwingUtilities.invokeLater和SwingWorker类(低于类最新的尝试)都具有相同的问题尝试。 更糟糕的是,我可以做一个dbug.myMessage(基本上发送到System.out),并看到一条消息,表明该酒吧是在内存中改变只是没有显示。 我显然失去了一些东西可能简单,但我想不出它是什么。

哦,一两件事,如果我离开这个教程为是( http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/实例/组件/ ProgressBarDemo2Project / src目录/组件/ ProgressBarDemo2.java ),只是改变主要为createAndShow方法,它的工作原理,但当然它不会做什么,我需要做的。

我没有张贴关于这一个问题,但改变了类这么多,我想最好还是发布新问题。

所以,这里是我的代码改变,似乎不工作:

public class MyProgressBar extends JPanel implements PropertyChangeListener, 
                                                     MyData, 
                                                     Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -1632492668549544408L;

    private MyDebug         dbug               = new MyDebug( MyData.MYDEBUGCHECK.MYPROGRESSBAR.getOn() );

    public static final int MAX                = 100;
    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();

    public  Task            task;


    class Task extends SwingWorker<Void, Void> {

        public int myValue = 0;

        @Override
        public Void doInBackground() {
            //Initialize progress property.
            setProgress(0);
            while (myValue < 100) {
                //Make random progress.
                //myValue += random.nextInt(10);
                setProgress( Math.min( myValue, 100 ) );
                dbug.myMessage( "MYPROGRESSBAR", "doInBackground", "Value is %3.2f %d", myBar.getPercentComplete(), myValue );
                myBar.repaint();
            }
            return null;
        }

        public void done() {
        }

        public void mySetValue( int percent ) {
            myValue = (int)( MAX * ( (double)percent / 100.0 ) );
            dbug.myMessage( "MYPROGRESSBAR", "mySetValue", "Value is %3.2f %d percent was %d", myBar.getPercentComplete(), myValue, percent );
        }

    }



    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);
        myFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

        myBar.setStringPainted( true );
        myBar.setBorderPainted( true );
        myBar.setValue( 0 );
        myBar.setBounds( 0, 0, WIDTH, HEIGHT );
        myBar.addPropertyChangeListener( this );

        myFrame.add( myBar );

        //Create and set up the content pane.
        //JComponent newContentPane = new MyProgressBar();
        JComponent newContentPane = myBar;
        newContentPane.setOpaque(true);                     //content panes must be opaque

        myFrame.setContentPane(newContentPane);
        myFrame.pack();

    }

    public void createAndShow () {

        //Display the window.
        myFrame.setVisible(true);
        myFrame.repaint();

    }

    public void hideAndClear () {
        //myFrame.setVisible(false);
    }


    @Override
    public void propertyChange(PropertyChangeEvent args) {
        dbug.myMessage( "MYPROGRESSBAR", "propertyChange", "Value is %s", args.getPropertyName() );
        if ( "progress" == args.getPropertyName() ) {
            int progress = (Integer) args.getNewValue();
            //myBar.setValue(progress);
        }
    }

    public void start () {
        //Instances of javax.swing.SwingWorker are not reusuable, so
        //we create new instances as needed.
        task = new Task();
        task.addPropertyChangeListener(this);
        task.execute();
    }

}


Answer 4:

以下代码段更新进度条,而在进步

    SwingUtilities.invokeLater(new Runnable() {
           public void run() {
           progressBar.setValue((int)percentage);
           //below code to update progress bar while running on thread
           progressBar.update(progressBar.getGraphics());}
         });   


文章来源: My JProgressBar is not Updating Until it is 100%