2013-11-28 47 views
9

我想要獲得一個進度條來準確地反映我的SwingWorker。但我真的不知道該怎麼做。我得到了酒吧,只是做一個靜態動畫,直到操作完成,但我想要一個真正的活動酒吧。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

不要忘記所接受,以紀念您選擇的答案。 – Stephan

回答

28

幾件事情:

  1. 有四個規則遵循SwingWorker。你可以參考這個圖表:enter image description here

所以,此代碼:

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

違反了規則。您的label.setText()應該移到構造函數中。

  • 發送「更新」到Swing組件(如您的進度條),你要使用的process()方法,它調用使用publish()doInBackground()內。您的SwingWorker參數反映您想要傳遞的值的類型。我附上了兩個SSCCE。一個通過Integerprocess()方法,另一個通過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<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

    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

    優秀的答案,不僅僅是一個例子,而且有可以理解和正確的解釋。比我見過的所有教程更好。 – Gangnus

    +0

    這很有幫助謝謝。我怎麼去報告doInBackground()的進度呢?此外,它不斷抱怨@Override存在process()函數。但是當我刪除它時,它會抱怨那裏的功能。 – Kyle

    +0

    @Kyle,檢查以確保您的流程方法的類型參數與'SwingWorker'類型匹配。例如,如果你擴展'SwingWorker ',那麼你的處理方法必須接受'List '作爲參數。 – ryvantage