SwingWorker ProgressBar

我正在尝试获得一个进度条以准确反映我的SwingWorker。 但我真的无法弄清楚该怎么做。 我得到了一个静态动画,直到操作完成,但我想要一个真正的活动栏。

/* * 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 { 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); } } 

几件事:

  1. SwingWorker遵循四条规则。 你可以参考这个图: 在此处输入图像描述

那么,这段代码:

 @Override public String doInBackground() { //download here label.setText("test"); 

违反了这条规则。 您的label.setText()应该移动到构造函数。

  1. 要向Swing组件(如进度条)发送“更新”,您要使用process()方法,该方法使用doInBackground()内部的publish()调用。 您的第二个 SwingWorker参数反映了您要传递的值的类型。 我附上了两个SSCCE。 一个将Integer传递给process()方法,另一个传递一个String 。 应该让你知道发生了什么。

SSCCE使用Integer

 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 { 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 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(); } } } } 

SSCCE使用String

 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 { JLabel jlabel; public Task_StringUpdate(JLabel jlabel) { this.jlabel = jlabel; } @Override protected void process(List 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(); } } } }