JProgressBar не будет обновляться

Я пытаюсь найти код, который я нашел в ответе на этот вопрос с вопросом: Загрузить файл с помощью 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 ответ

Решение

Сложно сказать по примеру кода, который вы предоставили...

Основной причиной этой проблемы является попытка обновить пользовательский интерфейс при блокировке из потока диспетчеризации событий (EDT).

Важно НИКОГДА не выполнять никаких длительных или блокирующих операций в EDT, так как это предотвратит обработку запросов на перерисовку.

Для получения дополнительной информации прочитайте параллелизм в Swing

Пример ниже демонстрирует использование SwingWorker который предоставляет обновления прогресса, которые синхронизируются с пользовательским интерфейсом

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;
        }
    }
}
Другие вопросы по тегам