2012-01-25 85 views
3

無法弄清楚這一點。使用worker或invokeLater,UI仍然凍結。在每個文件下載後,我想要更新JList。但JList只會在胎面返回後更新。Java Swing多線程和用戶界面凍結

下面是代碼:

public class MyUi extends javax.swing.JFrame{ 
    ... 

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt){ 

     SwingUtilities.invokeLater(new Runnable() { 
     //To get out of the event tread 
     public void run() { 
      dl(); 
     } 
     }); 
    } 

    private void dl(){ 
     ... 
     //ini and run the download class 
     Download myDownload = new Download(); 
     myDownload.doDownload(myDlList); 
    } 

    public void updateJlist(String myString){ 

     myModel.addElement(myString); 
     jList1.repaint(); 
    } 

} 

public class Download{ 
... 

    public void doDownload(String[] fileName){ 
     for(int i=0; i<fileName.length; i++){ 
     ...//download action... 
     //for my jList1 to be updated after each file. 
     MyUi.updateJlist(fileName[i]); 
     } 
    } 

} 

任何例子會有所幫助。

回答

3

在後臺線程下載該文件並在Runnable中僅包裹updateJlist()

SwingWorker會更可靠。

附錄:作爲@mre筆記,SwingWorker也可以很容易地報告中期業績,如here所示。

+1

+1的SwingWorker與中期業績。 – mre

+0

在後臺運行下載工作正常,我不需要換行updateJlist()。對於SwingWorker,我將需要閱讀更多內容並執行測試。我不完全理解它。謝謝! – marcb

+0

我很高興它正在工作,但我仍然[很警惕](http://stackoverflow.com/a/7158505/230513)從非EDT線程更新GUI。如果你需要'SwingWorker'的幫助,請不要猶豫,發佈一個問題。 – trashgod

4

invokeLater與您期望的完全相反 - 它在EDT上運行操作,這解釋了行爲。

0

我已經創建了一個WorkerThread類來照顧線程和GUI當前/主線程。當事件觸發啓動XXXServer時,我已將我的GUI應用程序放入WorkerThread的construct()方法中,然後所有線程都被激活,並且GUI平滑地工作,而不會凍結。看一看。

/** *操作事件* @see java.awt.event.ActionListener#的actionPerformed(java.awt.event.ActionEvent中)*/

公共無效的actionPerformed(ActionEvent的AE){ log.info (「actionPerformed begin ...」+ ae.getActionCommand());

try { 
    if (ae.getActionCommand().equals(btnStart.getText())) { 
     final int portNumber = 9990; 
     try { 

      WorkerThread workerThread = new WorkerThread(){ 
       public Object construct(){ 

        log.info("Initializing the Server GUI..."); 
        // initializing the Server 
        try { 
         xxxServer = new XXXServer(portNumber); 
         xxxServer.start(); 
         btnStart.setEnabled(false);        
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         log.info("actionPerformed() Start button ERROR IOEXCEPTION..." + e.getMessage()); 
         e.printStackTrace(); 
        } 
        return null; 
       } 
      };workerThread.start(); 
      } catch (Exception e) { 
       log.info("actionPerformed() Start button ERROR..." + e.getMessage()); 
       e.printStackTrace(); 
     } 


    } else if (ae.getActionCommand().equals(btnStop.getText())) { 
     log.info("Exit..." + btnStop.getText()); 
     closeWindow(); 
    } 

} catch (Exception e) { 
    log 
     .info("Error in ServerGUI actionPerformed===" 
      + e.getMessage()); 
} 

}