Java Swing 多线程和 ui 冻结

发布于 2024-12-28 18:49:49 字数 978 浏览 2 评论 0原文

这个想不通啊使用worker或invokeLater,UI仍然冻结。下载每个文件后,我想要更新 JList。但 JList 仅在踏步返回后才会更新。

这是代码:

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]);
      }
   }

}

任何示例都会有帮助。

Can't figure this one out. Using worker or invokeLater, the UI still freeze. After each file is downloaded, I want a JList to be updated. But the JList will only update after the tread returns.

Here is the code:

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]);
      }
   }

}

Any example would help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

メ斷腸人バ 2025-01-04 18:49:49

invokeLater 的作用与您期望的完全相反 - 它在 EDT 上运行操作,这解释了该行为。

invokeLater does exactly the opposite of what you expect it to do - it runs operations on the EDT, which explains the behaviour.

番薯 2025-01-04 18:49:49

在后台线程上下载文件并将 updateJlist() 包装在 Runnable 中。

SwingWorker会更可靠。

附录:正如 @mre 所说,SwingWorker 还可以轻松报告中期结果,如此处。

Download the file on a background thread and wrap just updateJlist() in a Runnable.

SwingWorker would be more reliable.

Addendum: As @mre notes, SwingWorker also makes it easy to report interim results, as shown here.

╰つ倒转 2025-01-04 18:49:49

我创建了一个 WorkerThread 类来处理线程和 GUI 当前/主线程。当事件触发启动 XXXServer 时,我已将 GUI 应用程序放入 WorkerThread 的 construct() 方法中,然后所有线程都被激活,并且 GUI 可以顺利工作而不会冻结。看看吧。

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

public void actionPerformed(ActionEvent ae) {
log.info("actionPerformed 开始..." + 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());
}

}

I have create a WorkerThread class which take care of Threads and GUI current/main thread . i have put my GUI application in construct() method of WorkerThread when an event fire to start XXXServer then all threads are activate and GUI work smoothlly wihout freeze. have a look.

/** * Action Event * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */

public void 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());
}

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文