2

この質問からの投票された回答で見つけたコードを試しています:java apache commonsを使用してファイルをダウンロードしますか?

これはダウンロードアプリケーションです。少し見てください(私はJFrameと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));
        }
    }

}
4

1 に答える 1

3

あなたが提供したコードサンプルから見分けるのは難しいです...

この問題の主な原因は、イベントディスパッチスレッド(EDT)からブロックしているときにUIを更新しようとしていることです。

EDT内で長時間実行またはブロック操作を実行しないことが重要です。これにより、再描画要求が実行されなくなります。

詳細については、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;
        }
    }
}
于 2012-10-27T00:11:29.163 に答える