2013-11-28 9 views
9

Ich versuche einen Fortschrittsbalken zu bekommen, der genau meinen SwingWorker widerspiegelt. Aber ich kann wirklich nicht herausfinden, wie es geht. Ich habe die Stange, um nur eine statische Animation zu machen, bis die Operation abgeschlossen ist, aber ich möchte einen echten aktiven Balken.SwingWorker ProgressBar

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

Sie als akzeptiert nicht vergessen, Ihre gewählte Antwort zu markieren. – Stephan

Antwort

28

Mehrere Dinge:

  1. Es gibt vier Regeln mit SwingWorker zu folgen. Sie können sich auf dieses Diagramm beziehen: enter image description here.

Also, dieser Code:

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

gegen diese Regel. Ihre label.setText() sollte in den Konstruktor verschoben werden.

  1. Senden Sie „Updates“ Komponenten Swing (wie Ihre Fortschrittsbalken) Sie wollen die process() Methode verwenden, die Sie publish() aus Ihrem doInBackground() mit aufrufen. Ihr zweiterSwingWorker Parameter gibt den Typ des Werts an, den Sie übergeben möchten. Ich habe zwei SSCCEs angeschlossen. Man übergibt eine Integer an die process() Methode, die andere übergibt eine String. Sollte dir eine Vorstellung davon geben, was vor sich geht.

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

SSCCE String mit:

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

Ausgezeichnete Antwort, nicht nur mit einem Beispiel, sondern mit verständlichen und korrekten Erklärungen. Ist besser, als alle Tutorials, die ich gesehen habe. – Gangnus

+0

Das war ziemlich hilfreich, danke. Wie gehe ich jedoch über den Fortschritt von doInBackground() vor? Außerdem beschwert es sich, dass der @Override für die Funktion process() da ist. Aber wenn ich es entferne, beschwert es sich über die Funktion dort. – Kyle

+0

@Kyle, überprüfen Sie, ob die Typparameter für Ihre Prozessmethode den 'SwingWorker'-Typen entsprechen. Wenn Sie zum Beispiel 'SwingWorker ' erweitern, muss Ihre Prozessmethode eine 'List ' als Argument akzeptieren. – ryvantage