2012-08-13 59 views
3

我正在製作一個備份程序,而且我希望所有的程序備份都顯示在JTextArea上。好吧,它的工作,但只有在程序完成備份後。我該如何解決?我已經運行該代碼是在這裏:JTextArea附加問題

備份方法

public void startBackup() throws Exception { 
    // txtarea is the JTextArea 
    Panel.txtArea.append("Starting Backup...\n"); 

    for (int i = 0; i < al.size(); i++) { 
     //al is an ArrayList that holds all of the backup assignments selected 
     // from the JFileChooser 

     File file = new File((String) al.get(i)); 
     File directory = new File(dir); 

     CopyFolder.copyFolder(file, directory); 
      } 
    } 

複製文件夾類:

public class CopyFolder { 
public static void copyFolder(File src, File dest) throws IOException { 

    if (src.isDirectory()) { 

     // if directory not exists, create it 
     if (!dest.exists()) { 
      dest.mkdir(); 
      Panel.txtArea.append("Folder " + src.getName() 
        + " was created\n"); 
     } 

     // list all the directory contents 
     String files[] = src.list(); 

     for (String file : files) { 
      // construct the src and dest file structure 
      File srcFile = new File(src, file); 
      File destFile = new File(dest, file); 
      // recursive copy 
      copyFolder(srcFile, destFile); 
     } 

    } else { 
     try { 
      CopyFile.copyFile(src, dest); 
     } catch (Exception e) { 
     } 
    } 
} 
    } 

的CopyFile類

public class CopyFile { 

public static void copyFile(File src, File dest) throws Exception { 
    // if file, then copy it 
    // Use bytes stream to support all file types 
    InputStream in = new FileInputStream(src); 
    OutputStream out = new FileOutputStream(dest); 

    byte[] buffer = new byte[1024]; 

    int length; 
    // copy the file content in bytes 
    while ((length = in.read(buffer)) > 0) { 
     out.write(buffer, 0, length); 
    } 

    in.close(); 
    out.close(); 
    // System.out.println("File copied from " + src + " to " + dest); 
    Panel.txtArea.append("File copied " + src.getName() + "\n"); 
} 
    } 

感謝提前的幫助下,讓我知道我可以給予的任何幫助。我做了一個谷歌搜索,這似乎是一個大問題,但我不能想到如何解決它。噢,請不要因爲它不適用於你而使其失望,因爲它非常讓人加重。再次感謝您!

編輯: 這就是我得到:

public class test extends SwingWorker<Void, String> { 
String txt; 
JTextArea txtArea = null; 

public test(JTextArea txtArea, String str) { 
    txt = str; 
    this.txtArea = txtArea; 
} 

protected Void doInBackground() throws Exception { 

    return null; 
} 

protected void process(String str) { 
    txtArea.append(str); 
} 

protected void getString() { 
    publish(txt); 
} 
    } 
+0

您試圖從SwingWorker的'doInBackground()'方法內進行Swing調用,這與您想要做的完全相反。請閱讀教程以瞭解如何使用此工具。 – 2012-08-13 02:50:01

+0

哦對不起,我忘記刪除,當我重新編輯。對不起 – PulsePanda 2012-08-13 02:52:08

+0

它可能是一個良好的夜間睡眠將有所幫助。現在去睡覺。所以只是我不回答。 – PulsePanda 2012-08-13 03:01:04

回答

5

您遇到的主要問題是你想執行的Event Dispatching Thread阻擋動作。這將防止UI被更新,因爲重繪請求沒有到達重繪管理器,直到完成後。

爲了解決這個問題,您需要將阻塞工作(即備份過程)卸載到單獨的線程。

爲此,我建議您閱讀Concurrency in Swing Trail這將爲您提供一些有用的策略來解決您的特定問題。特別是,你可能會從使用SwingWorker

採取在doInBackground密切關注benifit和process方法

更新了例

好了,所以這是一個非常簡單的例子。這基本上走你C:\盤3點的目錄深,轉儲內容所提供的JTextArea

public class BackgroundWorker extends SwingWorker<Object, File> { 

    private JTextArea textArea; 

    public BackgroundWorker(JTextArea textArea) { 

     this.textArea = textArea; 

    } 

    @Override 
    protected Object doInBackground() throws Exception { 

     list(new File("C:\\"), 0); 

     return null; 

    } 

    @Override 
    protected void process(List<File> chunks) { 

     for (File file : chunks) { 

      textArea.append(file.getPath() + "\n"); 

     } 

     textArea.setCaretPosition(textArea.getText().length() - 1); 

    } 

    protected void list(File path, int level) { 

     if (level < 4) { 

      System.out.println(level + " - Listing " + path); 

      File[] files = path.listFiles(new FileFilter() { 

       @Override 
       public boolean accept(File pathname) { 

        return pathname.isFile(); 

       } 
      }); 

      publish(path); 
      for (File file : files) { 

       System.out.println(file); 
       publish(file); 

      } 

      files = path.listFiles(new FileFilter() { 

       @Override 
       public boolean accept(File pathname) { 

        return pathname.isDirectory() && !pathname.isHidden(); 

       } 
      }); 

      for (File folder : files) { 

       list(folder, level + 1); 

      } 

     } 

    } 

} 

只需將調用new BackgroundWorker(textField).execute()走開:d

具有明顯的例子已更新

public class BackgroundWorker extends SwingWorker<Object, String> { 

    private JTextArea textArea; 
    private File sourceDir; 
    private File destDir; 

    public BackgroundWorker(JTextArea textArea, File sourceDir, File destDir) { 

     this.textArea = textArea; 
     this.sourceDir = sourceDir; 
     this.destDir = destDirl 

    } 

    @Override 
    protected Object doInBackground() throws Exception { 

     if (sourceDir.isDirectory()) { 

      // if directory not exists, create it 
      if (!destDir.exists()) { 
       destDir.mkdir(); 
       publish("Folder " + sourceDir.getName() + " was created"); 
      } 

      // list all the directory contents 
      String files[] = sourceDir.list(); 

      for (String file : files) { 
       // construct the src and dest file structure 
       File srcFile = new File(sourceDir, file); 
       File destFile = new File(destDir, file); 
       // recursive copy 
       copyFolder(srcFile, destFile); 
      } 

     } else { 
      try { 
       copyFile(sourceDir, destDir); 
      } catch (Exception e) { 
      } 
     } 

     return null; 

    } 

    public void copyFolder(File src, File dest) throws IOException { 

     if (src.isDirectory()) { 

      // if directory not exists, create it 
      if (!dest.exists()) { 

       publish("Folder " + src.getName() + " was created"); 
      } 

      // list all the directory contents 
      String files[] = src.list(); 

      for (String file : files) { 
       // construct the src and dest file structure 
       File srcFile = new File(src, file); 
       File destFile = new File(dest, file); 
       // recursive copy 
       copyFolder(srcFile, destFile); 
      } 

     } else { 
      try { 
       copyFile(src, dest); 
      } catch (Exception e) { 
      } 
     } 
    } 

    public void copyFile(File src, File dest) throws Exception { 
     // if file, then copy it 
     // Use bytes stream to support all file types 
     InputStream in = new FileInputStream(src); 
     OutputStream out = new FileOutputStream(dest); 

     byte[] buffer = new byte[1024]; 

     int length; 
     // copy the file content in bytes 
     while ((length = in.read(buffer)) > 0) { 
      out.write(buffer, 0, length); 
     } 

     in.close(); 
     out.close(); 
     publish("File copied " + src.getName()); 

    } 

    @Override 
    protected void process(List<String> chunks) { 

     for (String msg : chunks) { 

      textArea.append(msg + "\n"); 

     } 

     textArea.setCaretPosition(textArea.getText().length() - 1); 

    } 
} 

現在運行...

new BackgroundWorker(textArea, sourceDir, destDir).execute(); 
+0

它會工作,如果我只是有一個'Thread.sleep(100);'? – PulsePanda 2012-08-13 01:22:50

+2

不,因爲你只是讓'Event Dispatching Thread'進入睡眠狀態。您需要在'EDT'外執行備份工作,並將更新請求重新同步到'EDT'中(SwingUtilities.invokeLater對此很有用,但坦率地說,您的問題適合SwingWorker API ) – MadProgrammer 2012-08-13 01:29:04

+0

請參閱編輯請 – PulsePanda 2012-08-13 01:31:55