Обновление компонента Swing от другого потока с invokeLater или SwingWorker

Я разрабатываю небольшое приложение, которое имело бы Swing GUI. Приложение делает задачу IO в другом потоке, когда тот поток заканчивается, GUI должен быть обновлен соответственно для отражения операционного результата потока. Класс, работающий в (рабочий, не-GUI), имеет объект, переданный ему в конструкторе, который будет использоваться для обновления GUI, таким образом, я не должен буду помещать материал GUI в класс не-GUI, а скорее объект передачи для обновления GUI к тому классу. Поскольку я понимаю форму, читающую здесь, (поток/колебание) безопасные опции для обновления (изменяющегося) Swing, GUI должен был бы использовать javax.swing.SwingUtilities.invokeLater(), javax.swing.SwingUtilities.invokeLaterWait() и/или javax.swing.SwingWorker() которые в основном делают то же самое.

Эта вся проблема поточной обработки с Swing немного сбивает с толку меня, и все же я должен использовать потоки, чтобы сделать что-либо значимое в приложениях для GUI и не подвесил GUI при обработке в EDT, поэтому что интересует меня, на данный момент это:

  1. invokeLater и invokeLaterWait как передающее сообщение к EDT и ожидающий его делают это, когда это заканчивает обрабатывать сообщения, которые были перед тем вызовом?

  2. это корректный от аспекта потокобезопасности Swing, чтобы сделать что-то вроде этого:

    interface IUPDATEGUI {  
      public void update();  
    }  
    
    // in EDT/where I can access components directly    
    class UpdateJList implements IUPDATEGUI {    
      public void update() {    
        // update JList...    
        someJList.revalidate();    
        someJList.repain();    
      }    
    }    
    
    class FileOperations implements Runnable {  
      private IUPDATEGUI upObj;  
      List<File> result = new ArrayList<File>; // upObject is accessing this  
    
      public void FileOperations(IUPDATEGUI upObj) {
        this.upObj = upObj;
      }
    
      private void someIOTask() {
        // ...
        // IO processing finished, result is in "result"
      }
    
      public void run() {
        someIOTask();
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            upObj.update();  // access result and update JList
          }
        }; );
      }
    }
    

В случае, если это не корректно затем, как это должно быть сделано?

Если бы я мог, я предпочесть использовать invokeLater вместо SwingWorker бы, если это возможно, потому что я не должен был бы изменять свой целый класс и это так или иначе более аккуратно/отлично меня (как отправка сообщения в приложениях Win32).

Заранее спасибо.

7
задан Peter Lang 11 February 2010 в 21:11
поделиться

3 ответа

попробуйте это для sql server

CREATE TRIGGER yourNewTrigger ON yourSourcetable
FOR INSERT
AS

INSERT INTO yourDestinationTable
        (col1, col2    , col3, user_id, user_name)
    SELECT
        'a'  , default , null, user_id, user_name
        FROM inserted

go
-121--1347686-

invokeLater . Это помещает вызов в очередь событий AWT, так что он будет выполнен в EDT в надлежащее время. Программа продолжит работу и не ждет вызова вызываемого абонента.

-121--3977920-

Использование invokeLater () и invokeAndWait () передает параметр Runnable в очередь, ожидающую выполнения в EDT. Таким образом, вызов invokeLater () вызовет выполнение Runnable в EDT, когда EDT сможет обработать запрос. invokeAndWait () просто ожидает (в вызывающем потоке) этого выполнения.

Использование SwingWorker идеально подходит для выполнения фоновых задач, которые уведомляют EDT либо в конце выполнения, либо в промежуточных состояниях. Примером может служить передача текущего хода процесса в JProgressBar.

Для вашего примера кажется, что SwingWorker является лучшим выбором, но если вы не хотите менять код слишком сильно, тогда вызов invokeLater () , когда процесс будет выполнен, будет просто хорошо.

5
ответ дан 7 December 2019 в 05:22
поделиться

Я бы рекомендовал не использовать invokeAndWait до java 7. Я обнаружил ложное пробуждение в этом методе, которое может вызвать действительно болезненные ошибки. Для меня это привело к очень редким и трудно отлаживаемым исключениям нулевого указателя.

http://bugs.sun.com/view_bug.do?bug_id=6852111

Это исправлено в java 7 b77.

3
ответ дан 7 December 2019 в 05:22
поделиться

Я считаю, что это должно работать:

myObject = (MyAbstractClass)Activator.CreateInstance(null, childClassString);

null в первом параметре по умолчанию соответствует текущей исполняемой сборке. Для получения дополнительной информации: MSDN

edit: забыли привести к MyAbstractClass

-121--934617-

Да два способа сделать это; встроить заголовок в панель и показать/скрыть панель в зависимости от состояния входа в систему (которое происходит в коде). Кроме того, можно использовать две страницы-шаблона и выполнить эту проверку в методе OnPreInit (или обработчике событий PreInit) и переключиться, чтобы показать, какую страницу-шаблон необходимо использовать (в этом обработчике событий можно изменять только программные страницы-шаблоны).

Проблема, связанная со вторым параметром, заключается в том, что в PreInit может быть недоступно [...]

HTH.

-121--4950510-

invokeLater - нормально. Это помещает вызов в очередь событий AWT, так что он будет выполнен в EDT в надлежащее время. Программа продолжит работу и не ждет вызова вызываемого абонента.

0
ответ дан 7 December 2019 в 05:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: