JProgressBar 不会更新 [英] JProgressBar won't update

查看:38
本文介绍了JProgressBar 不会更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在这个问题的投票答案中找到的代码:下载文件使用java apache commons?

I'm trying the code I found on the voted answer from this question: Download file using java apache commons?

是一个下载应用,稍微看一下,(我对JFrames和ActionEvents不太熟悉)

It's a download application, take a little look, (I'm not much familiar with JFrames and ActionEvents)

下载.java

package main;

public class Download extends JFrame implements Runnable{

    public static int total;
    public static int done;

    private static class ProgressListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {

            done = (int)((DownloadCountingOutputStream) e.getSource()).getByteCount();
            jbar.repaint();
            DownloadCountingOutputStream.parent.draw((int)((DownloadCountingOutputStream) e.getSource()).getByteCount());//redraw
            DownloadCountingOutputStream.parent.repaint();
        }
    }

    public static JProgressBar jbar = new JProgressBar(); 



    public void draw(int downloaded){System.out.println("downloaded: "+downloaded+ " Total: "+total);

        if (downloaded== 0){

        Container cont = new Container();       
        setDefaultCloseOperation(3);
        setSize(600, 450);
        setResizable(false);
        setVisible(true);

        cont.add(jbar);     
        jbar.setBounds(40, 50, 500, 50);                
        jbar.setMaximum(total);//The total value of bytes to download
        //jbar.setValue(50);
        add(cont);

        jbar.setVisible(true);  
        }

        jbar.setValue(downloaded);      
            //This should update the value of the progress Bar
    }

    public void run() {


        URL dl = null;
        File fl = null;
        OutputStream os = null;
        InputStream is = null;
        ProgressListener progressListener = new ProgressListener();

        draw(done);

        try {
            fl = new File(System.getProperty("user.home").replace("\", "/") + "/Desktop/afile.rar");
            dl = new URL("https://dl.dropbox.com/u/48076798/afile.rar");
            os = new FileOutputStream(fl);
            is = dl.openStream();

            total = Integer.parseInt(dl.openConnection().getHeaderField("Content-Length"));

            String total = dl.openConnection().getHeaderField("Content-Length");

            DownloadCountingOutputStream dcount = new DownloadCountingOutputStream(os);
            dcount.setListener(progressListener);
            dcount.setParent(this);

            IOUtils.copy(is, dcount);

        } catch (Exception e) {
            System.out.println(e);
        } finally {
            if (os != null) { 
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } 
            }
            if (is != null) { 
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } 
            }
        }
    }

}

下载CountingOutputStream.java

DownloadCountingOutputStream.java

package main;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.io.output.CountingOutputStream;

public class DownloadCountingOutputStream extends CountingOutputStream {

    private ActionListener listener = null;
    public static Download parent;

    public DownloadCountingOutputStream(OutputStream out) {
        super(out);
    }

    public void setListener(ActionListener listener) {
        this.listener = listener;
    }

    public void setParent(Download o){

        parent = o;
    }

    @Override
    protected void afterWrite(int n) throws IOException {
        super.afterWrite(n);
        if (listener != null) {
            listener.actionPerformed(new ActionEvent(this, 0, null));
        }
    }

}

推荐答案

从您提供的代码示例中很难判断...

It's difficult to tell from the code sample you've provide...

此问题的主要原因是在阻止事件调度线程 (EDT) 时尝试更新 UI.

The main cause of this problem is trying to update the UI while blocking from the Event Dispatching Thread (EDT).

切勿在 EDT 中执行任何长时间运行或阻塞的操作,这很重要,因为这会阻止重绘请求被执行.

It's important to NEVER do any long running or blocking operations within the EDT as this will prevent repaint requests from been acted upon.

有关更多信息,请阅读Swing 中的并发

下面的示例演示了 SwingWorker 的使用,它提供与 UI 重新同步的进度更新

The example below demonstrates the use of a SwingWorker that provides progress updates that are re-synced with the UI

public class TestProgress {

    public static void main(String[] args) {
        new TestProgress();
    }

    public TestProgress() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                ProgressPane progressPane = new ProgressPane();
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(progressPane);
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                progressPane.doWork();
            }
        });
    }

    public class ProgressPane extends JPanel {

        private JProgressBar progressBar;

        public ProgressPane() {

            setLayout(new GridBagLayout());
            progressBar = new JProgressBar();

            add(progressBar);

        }

        public void doWork() {

            Worker worker = new Worker();
            worker.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if ("progress".equals(evt.getPropertyName())) {
                        progressBar.setValue((Integer) evt.getNewValue());
                    }
                }
            });

            worker.execute();

        }
    }

    public class Worker extends SwingWorker<Object, Object> {

        @Override
        protected Object doInBackground() throws Exception {

            for (int index = 0; index < 1000; index++) {
                int progress = Math.round(((float) index / 1000f) * 100f);
                setProgress(progress);

                Thread.sleep(10);
            }

            return null;
        }
    }
}

这篇关于JProgressBar 不会更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆