2012-01-25 51 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()); 
} 

}