2013-09-29 112 views
0

我正在創建一個將從URL(我自己的FTP服務器)下載文件的應用程序。問題是,當我點擊「下載」按鈕時,我的應用程序將開始下載,但是我的應用程序在下載時沒有任何響應,但是在下載完成後一切正常。Java - 如何從URL下載文件

這裏是我的代碼

某些部分GUI.class

b_Download.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent ae) 
      { 
         String username = "Test"; 
         startDownloading(username); 
      } 
     }); 

private void startDownload(String username) 
    { 
     downloader.println("Welcome " + username); //println will show text in a textpane(GUI) and console 
     downloader.startDownloading(); 
    } 

Downloader.class

public void startDownloading() 
{  
       println("Download jobs started"); 


       download.downloadLIB();  
} 

DownloadJob.class

public void downloadLIB() 
    { 
     launcher.println("Start downloading files from server..."); 
     String libURL = "http://www.example.com/file.jar"; 
     File libFile = new File("C://file.jar"); 
     downloadFile(libURL, libFile, "file.jar"); 
    } 
public void downloadFile(String url, File path, String fileName) 
    { 
     InputStream in = null; 
     FileOutputStream fout = null; 
     try 
     { 
      in = URI.create(url).toURL().openStream(); 
      fout = new FileOutputStream(path); 

      byte data[] = new byte[1024]; 
      int count; 
      while ((count = in.read(data, 0, 1024)) != -1) 
      { 
       fout.write(data, 0, count); 
      } 
     } 
     catch(Exception e) 
     { 
      launcher.println("Cannot download file : " + fileName, e); 
     } 
     finally 
     { 
      if (in != null) 
       try 
       { 
        in.close(); 
       } 
       catch (IOException e) 
       { 
        e.printStackTrace(); 
       } 
      if(fout != null) 
       try 
       { 
        fout.close(); 
       } 
       catch (IOException e) 
       { 
        e.printStackTrace(); 
       } 
      launcher.println("File " + fileName + " downloaded successfully"); 
     } 
    } 

當我按下「下載'按鈕,m y textpane顯示單詞「歡迎用戶名」,那麼它沒有任何迴應。但是我的控制檯會顯示「歡迎用戶名」,「下載作業開始」以及「從服務器開始下載文件...」。幾分鐘後(文件下載完成時,我的應用程序將開始再次有反應...

+0

在[併發在Swing(HTTP看看://文檔.oracle.com/javase/tutorial/uiswing/concurrency /)並注意關於SwingWorker的部分 – MadProgrammer

回答

0

Swing是一個單線程框架。這就是所有的交互和修改預計將在事件分派線程的上下文中執行。

阻止此線程的任何內容都將阻止它處理新事件,包括繪製請求。

這給你一個綁定。執行下載並不「凍結」程序的唯一方法是在某種後臺線程中運行,但不能從此線程更新或修改,因爲這必須在EDT的上下文中完成。

雖然有很多方法可以解決這個問題,但最簡單的方法就是使用SwingWorker

它在後臺運行的能力(關閉EDT),方法重新同步更新到EDT(publishprocessdone)和在建的功能提供了對報告進展情況。

例如...

看看Concurrency in Swing瞭解更多詳情...

+0

所以你的意思是我必須使用SwingWorker並在後臺執行下載過程? – Jeremy

+0

是............ – MadProgrammer

+0

你能告訴我一個在Java中使用SwingWorker的例子嗎?因爲我不熟悉< , > – Jeremy

0

您需要生成一個新的Thread

當您發送到網絡的請求,你執行這段代碼會一直掛起,直到找到它正在尋找的服務器,這意味着你的應用程序主線程將不會響應系統消息,導致系統認爲它已停止響應。

解決方案是產生一個工作線程或運行一個服務來處理您的網絡請求。

線程將等待服務器時掛起,而主要活動線程可以繼續與用戶交互。

當工作線程完成其任務時,您需要回調主線程以提醒用戶下載進度/完成。

+0

是的,我之前嘗試過,但仍然不能... – Jeremy

+0

哈哈哈,我正在做一個Java桌面應用程序...不是機器人 – Jeremy

+0

OI!仍然相關!哈哈!真的需要注意標籤。 :D –