Многопоточность Java Swing и зависание пользовательского интерфейса

Не могу понять это. При использовании worker или invokeLater пользовательский интерфейс по-прежнему зависает. После загрузки каждого файла я хочу, чтобы 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]);
      }
   }

}

Любой пример поможет.


person marcb    schedule 25.01.2012    source источник


Ответы (3)


Загрузите файл в фоновом потоке и оберните только updateJlist() в файл Runnable.

SwingWorker будет более надежным.

Приложение: как отмечает @mre, SwingWorker также упрощает отчет о промежуточных результатах, как показано здесь.

person trashgod    schedule 25.01.2012
comment
Запуск загрузки в фоновом режиме работает нормально, и мне не нужно обертывать updateJlist(). Что касается SwingWorker, мне нужно будет прочитать об этом немного больше и выполнить тест. Я не совсем понимаю это. Спасибо! - person marcb; 26.01.2012
comment
Я рад, что это работает, но я по-прежнему осторожно обновлять графический интерфейс из потока, отличного от EDT. Не стесняйтесь задать вопрос, если вам нужна помощь с SwingWorker. - person trashgod; 26.01.2012
comment
@marcb просто неправильно обновлять список вне EDT, даже если кажется, что он работает прямо сейчас. Вы должны получить доступ ко всем свойствам компонента Swing (тривиально включая любые модели) в EDT, без исключений из этого правила. - person kleopatra; 26.01.2012
comment
Я удалил свой комментарий. Окончательный код: теперь я понимаю, что даже если он работал идеально, это была большая ошибка и плохой код. Я продолжу читать о SwingWorker, почищу свой код, а затем сообщу о своей проблеме и беспокойстве. Спасибо за поддержку. - person marcb; 27.01.2012

invokeLater делает прямо противоположное тому, что вы от него ожидаете — он запускает операции с EDT, что объясняет поведение.

person Hauke Ingmar Schmidt    schedule 26.01.2012

Я создал класс WorkerThread, который заботится о потоках и текущем/основном потоке GUI. Я поместил свое приложение с графическим интерфейсом в метод build () WorkerThread, когда событие срабатывает для запуска XXXServer, тогда все потоки активируются, и графический интерфейс работает плавно, без зависания. Взгляни.

/** * Событие действия * * @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());
}

}

person mkumar0304    schedule 23.12.2014