Java Swing, SwingWorker, панель процессов не обновляется
Мой работник не будет перекрашивать мой индикатор выполнения (у меня есть 2 класса).
Это мой код загрузчика файлов. Это помещает процент загрузки в индикатор выполнения.
public class Downloader extends SwingWorker<String, Integer> {
private String fileURL, destinationDirectory;
private int fileTotalSize;
public void DownloaderF(String file, String dir) {
this.fileURL = file;
this.destinationDirectory = dir;
}
@Override
protected String doInBackground() throws Exception {
try {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
String downloadedFileName = fileURL.substring(fileURL.lastIndexOf("/")+1);
int filesize = httpConn.getContentLength();
int responseCode = httpConn.getResponseCode();
byte[] buffer = new byte[4096];
int bytesRead = 0;
int i = 0;
int total = 0;
BufferedInputStream in = new BufferedInputStream(httpConn.getInputStream());
FileOutputStream fos = new FileOutputStream(destinationDirectory + File.separator + downloadedFileName);
BufferedOutputStream bout = new BufferedOutputStream(fos,4096);
while ((i=in.read(buffer,0,4096))>=0) {
total = total + i;
bout.write(buffer,0,i);
fileTotalSize = (total * 100) / filesize;
publish(fileTotalSize);
}
bout.close();
in.close();
} catch(FileNotFoundException FNFE) {
System.out.print("HTTP: 404!");
} catch (IOException ex) {
Logger.getLogger(Downloader.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
try {
Skin barValue = new Skin();
barValue.setBar(fileTotalSize);
//System.out.print("PROCESS:" + fileTotalSize + "\n");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Это мой код кнопки и метод изменения значения индикатора выполнения:
private void LoginButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
// Дебаг
Downloader downloadFile = new Downloader();
downloadFile.DownloaderF("http://ipv4.download.thinkbroadband.com/100MB.zip", ".");
downloadFile.execute();
}
public void setBar(int Value) {
DownloadBar.setValue(Value);
DownloadBar.repaint();
System.out.print("1\n");
}
"1 \ n" будет напечатан, но индикатор выполнения не будет двигаться.
Извините за мой плохой английский.
2 ответа
Скорее всего, ваша проблема исходит из этой строки:
Skin barValue = new Skin();
Вы воссоздаете новый экземпляр себя Skin
класс вместо ссылки на тот, который уже существует. Следовательно, вы, скорее всего, указываете на то, что, вероятно, даже не отображается, и, следовательно, вы ничего не видите.
Правильный путь - предоставить вашему классу Downloader
ссылка на оригинал Skin
содержащий отображаемую "индикатор выполнения".
FYI:
- Нет необходимости вызывать repaint() на
JProgressBar
когда вы измените его значение (индикатор прогресса сделает это за вас) - Пожалуйста, следуйте соглашениям об именах Java (т. Е. Имена методов и переменные должны начинаться со строчной буквы): ваш код намного сложнее читать опытным пользователям.
Вот пример кода, полученного из вашего (хотя я сделал несколько ярлыков), который на самом деле работает правильно, как и ожидалось:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class Skin {
private JProgressBar DownloadBar;
public static class Downloader extends SwingWorker<String, Integer> {
private final String fileURL, destinationDirectory;
private int fileTotalSize;
private final Skin barValue;
public Downloader(Skin skin, String file, String dir) {
this.barValue = skin;
this.fileURL = file;
this.destinationDirectory = dir;
}
@Override
protected String doInBackground() throws Exception {
try {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url
.openConnection();
String downloadedFileName = fileURL.substring(fileURL
.lastIndexOf("/") + 1);
int filesize = httpConn.getContentLength();
int responseCode = httpConn.getResponseCode();
byte[] buffer = new byte[4096];
int bytesRead = 0;
int i = 0;
int total = 0;
BufferedInputStream in = new BufferedInputStream(
httpConn.getInputStream());
FileOutputStream fos = new FileOutputStream(
destinationDirectory + File.separator
+ downloadedFileName);
BufferedOutputStream bout = new BufferedOutputStream(fos, 4096);
while ((i = in.read(buffer, 0, 4096)) >= 0) {
total = total + i;
bout.write(buffer, 0, i);
fileTotalSize = total * 100 / filesize;
publish(fileTotalSize);
}
bout.close();
in.close();
} catch (FileNotFoundException FNFE) {
System.out.print("HTTP: 404!");
} catch (IOException ex) {
Logger.getLogger(Downloader.class.getName()).log(Level.SEVERE,
null, ex);
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
barValue.setBar(fileTotalSize);
}
}
private void loginButtonActionPerformed(java.awt.event.ActionEvent evt) {
Downloader downloadFile = new Downloader(this,
"http://ipv4.download.thinkbroadband.com/100MB.zip", ".");
downloadFile.execute();
}
protected void initUI() throws MalformedURLException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton login = new JButton("Login");
login.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loginButtonActionPerformed(e);
}
});
DownloadBar = new JProgressBar();
frame.add(login, BorderLayout.NORTH);
frame.add(new JLabel(new ImageIcon(new URL(
"http://home.scarlet.be/belperret/images/image1.jpg"))));
frame.add(DownloadBar, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public void setBar(int Value) {
DownloadBar.setValue(Value);
DownloadBar.repaint();
System.out.println("1");
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
new Skin().initUI();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
});
}
}
Вы делаете publish(fileTotalSize)
правильно, поэтому я думаю, что это может быть ваш код процесса. Попробуйте это изменение:
protected void process(List<Integer> chunks) {
try {
Skin barValue = new Skin();
barValue.setBar( chunks.get(0) );
//System.out.print("PROCESS:" + fileTotalSize + "\n");
} catch (Exception ex) {
ex.printStackTrace();
}
}
У меня нет вашего полного кода, поэтому я не могу его проверить.