我正在尝试让进度条准确反射(reflect)我的 SwingWorker。但我真的不知道该怎么做。在操作完成之前,我得到了只做静态动画的栏,但我想要一个真正的 Activity 栏。
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package frglauncher;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
/**
*
* @author KYLE-LAPTOP
*/
class DownloadWorker extends SwingWorker<String, Object> {
private String game;
private JProgressBar bar;
private JLabel label;
public DownloadWorker(JProgressBar bar, String game, JLabel label) {
this.game = game;
this.bar = bar;
this.label = label;
}
@Override
public String doInBackground() {
// Download here
label.setText("test");
try {
// ProgressBar/Install
System.out.println("FILELOCATION:\n----------");
String URL_LOCATION = "http://www.futureretrogaming.tk/gamefiles/ProfessorPhys.jar";
String LOCAL_FILE = ("\\" + game + "\\");
File localfile = new File(LOCAL_FILE);
if (localfile.exists()) {
System.out.println("Directory exists!");
}
else {
System.out.println("Directory doesn't exist! Creating...");
localfile.mkdir();
if (localfile.exists()) {
System.out.println("Directory created!");
}
}
System.out.println("LOCALFILE:\n-------");
System.out.println(LOCAL_FILE);
URL website = new URL(URL_LOCATION);
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(LOCAL_FILE + "\\ProfessorPhys.jar\\");
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
System.out.println("--------\nDone Downloading\n---------");
RandomAccessFile randomAccessFile = null;
File file = new File(LOCAL_FILE + "ProfessorPhys.jar\\");
JarFile jar = new JarFile(file);
Enumeration enum1 = jar.entries();
while (enum1.hasMoreElements()) {
JarEntry file1 = (JarEntry) enum1.nextElement();
System.out.println("Directory to extract: " + LOCAL_FILE);
System.out.println("\n" + file1.getName() + "\n");
File f = new File(file1.getName());
if (file1.isDirectory()) { // If it's a directory, create it
f.mkdir();
continue;
}
try (InputStream is1 = jar.getInputStream(file1)) {
FileOutputStream fos1 = new FileOutputStream(f);
while (is1.available() > 0) { // Write contents of 'is' to 'fos'
fos1.write(is1.read());
}
fos1.close();
}
}
}
catch (FileNotFoundException ex) {
Logger.getLogger(DownloadWorker.class.getName()).log(Level.SEVERE, null, ex);
}
catch (MalformedURLException ex) {
Logger.getLogger(DownloadWorker.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex) {
Logger.getLogger(DownloadWorker.class.getName()).log(Level.SEVERE, null, ex);
}
return "done";
}
@Override
protected void done() {
// Done
label.setText("Download of " + game + "is done.");
System.exit(0);
}
}
最佳答案
几件事:
SwingWorker
有四个规则要遵循。可以引用这张图: .
所以,这段代码:
@Override
public String doInBackground() {
//download here
label.setText("test");
违反了这条规则。您的 label.setText()
应该移至构造函数。
- 要向 Swing 组件(如进度条)发送“更新”,您需要使用
process()
方法,您可以使用publish()
从内部调用该方法你的doInBackground()
。您的第二个SwingWorker
参数反射(reflect)了您要传递的值的类型。我附上了两个 SSCCE。一个将Integer
传递给process()
方法,另一个传递一个String
。应该让您了解正在发生的事情。
使用 Integer
的 SSCCE:
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
/**
*
* @author Ryan
*/
public class Test {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
go();
}
});
}
public static void go() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JLabel label = new JLabel("Loading...");
JProgressBar jpb = new JProgressBar();
jpb.setIndeterminate(false);
int max = 1000;
jpb.setMaximum(max);
panel.add(label);
panel.add(jpb);
frame.add(panel);
frame.pack();
frame.setSize(200,90);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
new Task_IntegerUpdate(jpb, max, label).execute();
}
static class Task_IntegerUpdate extends SwingWorker<Void, Integer> {
JProgressBar jpb;
int max;
JLabel label;
public Task_IntegerUpdate(JProgressBar jpb, int max, JLabel label) {
this.jpb = jpb;
this.max = max;
this.label = label;
}
@Override
protected void process(List<Integer> chunks) {
int i = chunks.get(chunks.size()-1);
jpb.setValue(i); // The last value in this array is all we care about.
System.out.println(i);
label.setText("Loading " + i + " of " + max);
}
@Override
protected Void doInBackground() throws Exception {
for(int i = 0; i < max; i++) {
Thread.sleep(10); // Illustrating long-running code.
publish(i);
}
return null;
}
@Override
protected void done() {
try {
get();
JOptionPane.showMessageDialog(jpb.getParent(), "Success", "Success", JOptionPane.INFORMATION_MESSAGE);
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
}
}
使用 String
的 SSCCE:
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
/**
*
* @author Ryan
*/
public class Test2 {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
go();
}
});
}
public static void go() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JLabel label = new JLabel("Loading...");
JProgressBar jpb = new JProgressBar();
jpb.setIndeterminate(true);
panel.add(label);
panel.add(jpb);
frame.add(panel);
frame.pack();
frame.setSize(200,90);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
new Task_StringUpdate(label).execute();
}
static class Task_StringUpdate extends SwingWorker<Void, String> {
JLabel jlabel;
public Task_StringUpdate(JLabel jlabel) {
this.jlabel = jlabel;
}
@Override
protected void process(List<String> chunks) {
jlabel.setText(chunks.get(chunks.size()-1)); // The last value in this array is all we care about.
System.out.println(chunks.get(chunks.size()-1));
}
@Override
protected Void doInBackground() throws Exception {
publish("Loading Step 1...");
Thread.sleep(1000);
publish("Loading Step 2...");
Thread.sleep(1000);
publish("Loading Step 3...");
Thread.sleep(1000);
publish("Loading Step 4...");
Thread.sleep(1000);
return null;
}
@Override
protected void done() {
try {
get();
JOptionPane.showMessageDialog(jlabel.getParent(), "Success", "Success", JOptionPane.INFORMATION_MESSAGE);
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
}
}
关于java - SwingWorker 进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20260372/