2017-01-19 64 views
0

我需要一些幫助,我正在製作一個像文件管理器一樣的程序。在我的程序中,我需要同時創建文件副本。對於我使用SwingWorker看到一個JProgressbar副本的進展,但我需要知道如何添加多個文件,在任務中複製具有相同目的。在SwingWorker中更新參數

這是我的課,從Swingworker擴展了我的主要程序I'll選擇一些文件或文件夾在一個目的地複製。我需要的是Copytask正在工作,我可以將更多文件添加到Copyitem Arraylist

請幫忙我的英語很抱歉。

import java.awt.Dimension; 
import java.awt.Toolkit; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JDialog; 
import javax.swing.JOptionPane; 
import javax.swing.JProgressBar; 
import javax.swing.SwingWorker; 
import xray.XRAYView; 


public class CopyTask extends SwingWorker<Void, Integer> 
    { 

     ArrayList<CopyItem>copia; 
     private long totalBytes = 0L; 
     private long copiedBytes = 0L; 
     JProgressBar progressAll; 
     JProgressBar progressCurrent; 
     boolean override=true; 
     boolean overrideall=false; 


     public CopyTask(ArrayList<CopyItem>copia,JProgressBar progressAll,JProgressBar progressCurrent) 
     { 

      this.copia=copia; 
      this.progressAll=progressAll; 
      this.progressCurrent=progressCurrent; 


      progressAll.setValue(0); 
      progressCurrent.setValue(0); 
      totalBytes=retrieveTotalBytes(copia); 

     } 

     public void AgregarCopia(ArrayList<CopyItem>addcopia)throws Exception{ 

      copia.addAll(copia.size(), addcopia); 
      totalBytes=retrieveTotalBytes(addcopia)+totalBytes; 
      System.out.println("AL AGREGAR: "+copia.size()+" Tamaño"+totalBytes); 



     } 

     public File getDriveDest(){ 
     File dest=new File(copia.get(0).getOrigen().getPath().split("\\")[0]); 
     return dest; 
     } 


     @Override 
     public Void doInBackground() throws Exception 
     { 


      for(CopyItem cop:copia){ 

      File ori=cop.getOrigen(); 
      File des=new File(cop.getDestino().getPath()); 
      if(!des.exists()){ 
       des.mkdirs(); 
      } 
      if(!overrideall){ 
      override =true; 
      } 
      File para=new File(cop.getDestino().getPath()+"\\"+ori.getName()); 
      copyFiles(ori, para); 

      } 
      return null; 
     } 

     @Override 
     public void process(List<Integer> chunks) 
     { 
      for(int i : chunks) 
      { 
       progressCurrent.setValue(i); 


      } 
     } 

     @Override 
     public void done() 
     { 
      setProgress(100); 

     } 

     private long retrieveTotalBytes(ArrayList<CopyItem>fich) 
     { 
      long size=0; 
      for(CopyItem cop: fich) 
      { 
       size += cop.getOrigen().length(); 

      } 

      return size; 
     } 






private void copyFiles(File sourceFile, File targetFile) throws IOException 

     { 
        if(overrideall==false){ 
         if(targetFile.exists() && !targetFile.isDirectory()){ 

          String []options={"Si a Todos","Si","No a Ninguno","No"}; 
          int seleccion=JOptionPane.showOptionDialog(null, "El fichero \n"+targetFile+" \n se encuentra en el equipo, \n¿Desea sobreescribirlo?", "Colisión de ficheros", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, null); 

          switch(seleccion){ 
           case 0: 
           override=true; 
           overrideall=true; 
           break; 
           case 1: 
           override=true; 
           overrideall=false; 
           break; 
           case 2: 
           override =false; 
           overrideall=true; 
           break; 
           case 3: 
           override =false; 
           overrideall=false; 
           break; 

          } 

         } 

        } 

        if(override || !targetFile.exists()){ 
        FileInputStream LeeOrigen= new FileInputStream(sourceFile); 

        OutputStream Salida = new FileOutputStream(targetFile); 

        byte[] buffer = new byte[1024]; 
        int tamaño; 

        long fileBytes = sourceFile.length(); 

        long totalBytesCopied = 0; 

        while ((tamaño = LeeOrigen.read(buffer)) > 0) { 

        Salida.write(buffer, 0, tamaño); 

        totalBytesCopied += tamaño; 
        copiedBytes+= tamaño; 

        setProgress((int)Math.round(((double)copiedBytes++/(double)totalBytes) * 100)); 

        int progress = (int)Math.round(((double)totalBytesCopied/(double)fileBytes) * 100); 

        publish(progress); 



        } 


        Salida.close(); 
        LeeOrigen.close(); 



       publish(100); 
       } 


      } 
     } 

這裏是CopyItem類

import java.io.File; 


public class CopyItem { 
    File origen; 
    File destino; 
    String root; 

    public CopyItem(File origen, File destino) { 
     this.origen = origen; 
     this.destino = destino; 
    } 

    public CopyItem(File origen, File destino, String root) { 
     this.origen = origen; 
     this.destino = destino; 
     this.root = root; 
    } 

    public String getRoot() { 
     return root; 
    } 

    public void setRoot(String root) { 
     this.root = root; 
    } 


    public File getOrigen() { 
     return origen; 
    } 

    public void setOrigen(File origen) { 
     this.origen = origen; 
    } 

    public File getDestino() { 
     return destino; 
    } 

    public void setDestino(File destino) { 
     this.destino = destino; 
    } 

    @Override 
    public String toString() { 
     return super.toString(); //To change body of generated methods, choose Tools | Templates. 
    } 


} 
+0

我可以想象這段代碼的95%是不相關的問題。請創建一個[**最小**,完整且可驗證的示例](http://stackoverflow.com/help/mcve),以說明您的問題。 –

回答

0

是的,你可以將文件直接添加到源列表(列表中包含要複製的文件),但你需要,因爲添加更多的文件將同步代碼在不同的線程(UI線程),另一種方式是實現使用BlockingQueue

消費類運行在單獨的線程或SwingWorker的複製文件過程中(生產/消費)。 生產者類運行UI線程(選擇更多文件)。

都應該有機會獲得的BlockingQueue(包含要複製的文件)(當然BlockingQueue實現是線程安全的,基於文檔的,它的優勢在於阻止執行並等待文件添加,這是如果你不知道什麼時候被添加的文件)

我更喜歡使用線程池來管理線程執行(可選)是非常有用的。

+0

非常感謝阿姆賈德,我已經聽說了(生產/消費),但我不知道如何實現,在這種情況下,我認爲這個想法是在一個威脅監聽其發送給其他威脅到新複製的文件就將此,但我不知道如何發送副本,並等待ultil副本結束髮送其他,提前致謝。 –