Swing проверяет код Потока Отправки События во времени выполнения

Есть ли какие-либо библиотеки, которыми инструментальный код, чтобы проверить, что методы обратились к компонентам Swing, называют на Потоке Отправки События? Вероятно, не было бы слишком трудно написать некоторый абсолютный код для того, чтобы сделать это, но я уверен, что существуют пограничные случаи и этажерка, которую обработали другие люди. Я ищу это во времени выполнения хотя, не для модульных тестов.

10
задан Lii 26 September 2015 в 10:05
поделиться

3 ответа

В инфраструктуре FEST есть инструмент для обнаружения использования Swing вне EDT. По сути, вы устанавливаете RepaintManager. Фреймворк ориентирован на тестирование, но RepaintManager можно использовать во время развертывания.

В качестве альтернативы, чтобы проверить все методы, такие как геттеры и сеттеры, для доступа только к EDT, вы можете использовать AspectJ и ткачество во время загрузки, чтобы добавить SwingUtilities.isDisaptchThread () советует каждому методу в ваших компонентах Swing (и компонентах JDK Swing)

@Aspect
public class EDTCheck {

    @Pointcut("call (* javax.swing..*+.*(..)) || " +
              "call (javax.swing..*+.new(..))")
    public void swingMethods() {}

    @Pointcut("call (* com.mystuff.swing..*+.*(..)) || " +
              "call (com.mystuff.swing..*+.new(..))")
    public void mySwingMethods() {}


    @Pointcut("call (* javax.swing..*+.add*Listener(..)) || " +
              "call (* javax.swing..*+.remove*Listener(..)) || " +
              "call (void javax.swing.JComponent+.setText(java.lang.String))")
    public void safeMethods() {}

    @Before("(swingMethods() || mySwingMethods()) && !safeMethods()")
    public void checkCallingThread(JoinPoint.StaticPart thisJoinPointStatic) {
        if(!SwingUtilities.isDispatchThread()) {
            System.out.println(
                    "Swing single thread rule violation: " 
                    + thisJoinPointStatic);
            Thread.dumpStack();
            // or you might throw an unchecked exception
        }
    }

}

(Немного изменено из статьи - добавлен mySwingMethods pointcut и используется SwingUtiliites.isDispatchThread (). На практике это то же самое, что и EventQueue. isDispatchThread (), но абстракция чище.)

11
ответ дан 3 December 2019 в 21:58
поделиться

Все, что вам нужно, это следующий код:

void method() {
    if (!SwingUtilities.isEventDispatchThread()) {
       SwingUtilities.invokeAndWait(new Runnable() { public void run() { method(); } );
       return;
    }

    // do method code here, guaranteed to be in EDT
}

Кроме того, использование Substance в качестве вашего LAF поможет вам определить, где не выполняются вещи, связанные с Swing. на EDT. У него есть проверки, чтобы убедиться, что все Swing-файлы выполняются в правильном потоке, в противном случае он не работает с исключением.

1
ответ дан 3 December 2019 в 21:58
поделиться

С точки зрения кодирования, четко отделите код EDT от кода не-EDT. Избегайте SwingWorker как чумы.

Чтобы подтвердить, что вы находитесь в EDT (вставьте ! для выключенного), добавьте строку:

assert java.awt.EventQueue.isDispatchThread();

Вам понадобится -ea / -enableassertions ], чтобы сделать что-нибудь. Однако в основном он работает как исполняемый комментарий.

2
ответ дан 3 December 2019 в 21:58
поделиться
Другие вопросы по тегам:

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