JProgressBar不会更新

时间:2012-10-26 21:26:49

标签: java swing jprogressbar

我正在尝试在此问题的投票答案中找到的代码:Download file using java apache commons?

这是一个下载应用程序,看一看,(我对JFrames和ActionEvents不是很熟悉)

Download.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();
                } 
            }
        }
    }

}

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

}

1 个答案:

答案 0 :(得分:3)

从您提供的代码示例中很难说明......

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

重要的是不要在EDT中进行任何长时间运行或阻止操作,因为这样可以防止重绘请求被执行。

有关详细信息,请阅读Concurrency in Swing

以下示例演示如何使用SwingWorker提供与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;
        }
    }
}