Проверьте, необходим ли поток EDT? - PullRequest
4 голосов
/ 21 апреля 2010

У меня есть интерфейс, реализованный с помощью Swing. Один компонент выполняет некоторую работу, которая может занять некоторое время, поэтому я использую SwingUtilities.invokeLater. Тем не менее, я читал старый код и нашел его в ActionListener:

if (!SwingUtilities.isEventDispatchThread()) {
    SwingUtilities.invokeLater(new Runnable() {
         public void run() {
             // code X
         }
    });
} else {
   // code X
}

Я подумал, что это имеет смысл, поскольку он отделяет code X от EDT. Тем не менее, я обнаружил, что он подвержен ошибкам, поскольку использовал его пару раз, и оба раза я забывал о else части.

Вопрос: необходима ли проверка SwingUtilities.isEventDispatchThread()? Или я могу предположить, что я не в EDT и всегда использую invokeLater?

Большое спасибо.

Ответы [ 4 ]

14 голосов
/ 21 апреля 2010

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

public static void invokeInDispatchThreadIfNeeded(Runnable runnable) {
    if (EventQueue.isDispatchThread()) {
        runnable.run();
    } else {
        SwingUtilities.invokeLater(runnable);
    }
}

Таким образом, вы никогда не забудете else.

Кроме того, вВообще в вашем idom повторение code x - очень плохая идея, так как позже вы можете обнаружить, что вам нужно исправить или улучшить этот код, и вы будете делать это только в одном месте, оставляя ошибку в другом.

2 голосов
/ 21 апреля 2010

I считаю для вашего конкретного случая использования, проверка isEventDispatchThread() не требуется. Прямой вызов invokeLater() не создаст новый поток, поэтому это не приведет к снижению производительности.

0 голосов
/ 06 ноября 2017

Просто, если в вашем коде есть поток (A), запускаемый EDT, и в этом потоке (A) у вас есть другой поток (B), который должен изменить ваш графический интерфейс, в этом случае вы должны использовать invokeLater резьбы (В). Однако, если модификация вашего GUI выполняется первым потоком (A), нет необходимости использовать invokeLater.

0 голосов
/ 21 апреля 2010

Код действительно должен знать, находится ли он на EDT или нет (если это актуально). Поэтому java.awt.EventQueue.isDispatchThread следует оставить для утверждений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...