gpt4 book ai didi

java - 为什么当我使用 SwingWorker 时我的图像无法下载,但当我不使用 SwingWorker 时却可以下载?

转载 作者:行者123 更新时间:2023-12-02 02:42:21 28 4
gpt4 key购买 nike

我正在创建一个进度条来监控图像下载。图像下载不起作用 - 它会生成一个大小为 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);
}
}
}

最佳答案

您应该调用get()done()中。如果doInBackground抛出异常,则get()将抛出ExecutionException,其原因是来自doInBackground的异常。

类似这样的事情:

@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;

因为bytesReadInputStream.read()的返回值,它实际上是一个字节的数据,而不是读取的字节数。这对 I/O 没有明显影响,但会破坏 percentCompleted 的值。最终将一个大于 100 的值传递给 setProgress这会引发异常。该行应该改为 totalBytesRead++;

您可以通过上述对 done() 的修改来验证我的理论。

关于java - 为什么当我使用 SwingWorker 时我的图像无法下载,但当我不使用 SwingWorker 时却可以下载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45228012/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com