代码之家  ›  专栏  ›  技术社区  ›  brienna

为什么当我使用SwingWorker时,我的图像不下载,而当我不使用SwingWorker时,我的图像下载?

  •  0
  • brienna  · 技术社区  · 8 年前

    我正在创建一个进度条来监视图像下载。图像下载不起作用,它生成一个大小为0字节的文件。如果我将代码移动到一个没有SwingWorker的独立类,那么图像下载就可以了。我已经玩了一段时间了,我仍然不知道我做错了什么。这两个代码块是相同的。任何提示都将不胜感激!

    SwingWorker doInBackground ):

    package download_progress_bar;
    
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.beans.*;
    import java.net.*;
    import java.io.*;
    
    public class ProgressBar implements ActionListener, PropertyChangeListener {
        private JFrame frame;
        private JPanel gui;
        private JButton button;
        private JProgressBar progressBar;
        private SwingWorker<Void, Void> worker;
        private boolean done;
    
        public ProgressBar() {
            done = false;
            customizeFrame();
            createMainPanel();
            createProgressBar();
            createButton();
            addComponentsToFrame();
        }
    
        private void customizeFrame() {
            frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    
        private void createMainPanel() {
            gui = new JPanel();
            gui.setLayout(new BorderLayout());
        }
    
        private void createProgressBar() {
            progressBar = new JProgressBar(0, 100);
            progressBar.setStringPainted(true);  // renders a progress string
        }
    
        private void createButton()  {
            button = new JButton("Start download");
            button.addActionListener(this);
        }
    
        /**
         * Invoked when user clicks the button.
         */
        public void actionPerformed(ActionEvent evt) {
            button.setEnabled(false);
            // NOTE: Instances of javax.swing.SwingWorker are not reusable, 
            // so we create new instances as needed
            worker = new Worker();
            worker.addPropertyChangeListener(this);
            worker.execute();
        }
    
        class Worker extends SwingWorker<Void, Void> {
            /* 
             * Main task. Executed in worker thread.
             */
            @Override
            protected Void doInBackground() throws MalformedURLException {
                // Create a URL object for a given URL
                String src = "https://lh3.googleusercontent.com/l6JAkhvfxbP61_FWN92j4ulDMXJNH3HT1DR6xrE7MtwW-2AxpZl_WLnBzTpWhCuYkbHihgBQ=s640-h400-e365";
                URL url = new URL(src);
                // Open connection on the URL object
    
                try {
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    
                    // Always check response code first
                    int responseCode = connection.getResponseCode();
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        System.out.println(responseCode);
    
                        // Open input stream from connection
                        BufferedInputStream in = new BufferedInputStream(connection.getInputStream());
                        // Open output stream for file writing
                        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("cat.jpg"));
    
                        int bytesRead = - 1;
                        int totalBytesRead = 0;
                        int percentCompleted = 0;
    
                        while ((bytesRead = in.read()) != -1) {
                            out.write(bytesRead);
                            totalBytesRead += bytesRead;
                            percentCompleted = totalBytesRead * 100 / connection.getContentLength();
    
                            System.out.println("..." + percentCompleted);
                            this.setProgress(percentCompleted);
                        }
    
                        // Close streams
                        out.close();
                        in.close();
                    }
                } catch (IOException ex) {
                    System.out.println(ex);
                    this.setProgress(0);
                    cancel(true);
                }
    
                return null;
            }
    
            /*
             * Executed in event dispatching thread
             */
            @Override
            protected void done() {
                button.setEnabled(true);
                if (!isCancelled()) {
                    System.out.println("File has been downloaded successfully!");
                } else {
                    System.out.println("There was an error in downloading the file.");
                }
            }
        }
    
        /**
         * Invoked when task's progress property changes.
         */
        public void propertyChange(PropertyChangeEvent evt) {
            System.out.println(evt);
            // NOTE: By default two property states exist: "state" and "progress"
            if (evt.getPropertyName().equals("progress")) {
                int progress = (Integer) evt.getNewValue();
                progressBar.setValue(progress);
                System.out.println(String.format(
                        "Completed %d%% of task.\n", progress));
            }
        }
    
        private void addComponentsToFrame() {
            gui.add(progressBar, BorderLayout.CENTER);
            gui.add(button, BorderLayout.SOUTH);
            frame.add(gui);
            frame.pack();
        }
    
        public void activate() {
            frame.setVisible(true);
        }
    }
    

    使用单机版下载图像 Downloader 课堂(注意 download

    package download_progress_bar;
    
    import java.net.*;
    import java.io.*;
    
    public class Downloader {
        public static void main(String[] args) throws IOException {
            download();
        }
    
        public static void download() throws IOException {
            // Create a URL object for a given URL
            String src = "https://lh3.googleusercontent.com/l6JAkhvfxbP61_FWN92j4ulDMXJNH3HT1DR6xrE7MtwW-2AxpZl_WLnBzTpWhCuYkbHihgBQ=s640-h400-e365";
            URL url = new URL(src);
            // Open connection on the URL object
    
            try {
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    
                // Always check response code first
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    System.out.println(responseCode);
    
                    // Open input stream from connection
                    BufferedInputStream in = new BufferedInputStream(connection.getInputStream());
                    // Open output stream for file writing
                    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("test.jpg"));
    
                    int bytesRead = - 1;
                    int totalBytesRead = 0;
                    int percentCompleted = 0;
    
                    while ((bytesRead = in.read()) != -1) {
                        out.write(bytesRead);
                        totalBytesRead += bytesRead;
                        percentCompleted = totalBytesRead * 100 / connection.getContentLength();
    
                        System.out.println("..." + percentCompleted);
                    }
    
                    // Close streams
                    out.close();
                    in.close();
                }
            } catch (IOException ex) {
                System.out.println(ex);
            }
        }
    }
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   Radiodef    8 年前

    你应该打电话 get() 在里面 done() doInBackground 抛出异常,然后 get() 将抛出一个 ExecutionException 谁的原因是 Doin背景 .

    类似这样:

    @Override
    protected void done() {
        button.setEnabled(true);
        try {
            if (!isCancelled()) {
                get();
                System.out.println("File has been downloaded successfully!");
                return;
            }
        } catch (InterruptedException x) {
            x.printStackTrace();
        } catch (ExecutionException x) {
            // This should print an IllegalArgumentException
            // if me theory (explained below) is correct.
            x.getCause().printStackTrace();
        }
        System.out.println("There was an error in downloading the file.");
    }
    

    totalBytesRead += bytesRead;
    

    自从 bytesRead 是的返回值 InputStream.read() percentCompleted 。这最终会将大于100的值传递给 setProgress 这会引发异常。线路应为 totalBytesRead++;

    你可以用上面提到的修改来验证我的理论 .