Я работаю над Java приложение Swing с Google Guice как контейнер МОК. Вещи работают вполне прилично. Существуют некоторые проблемы UI. Когда стандартный L&F заменяется Продвижением пиксельного Вещества, приложение L&F не работает из-за создания компонентов Swing Guice за пределами потока UI.
Существует ли способ сказать Guice создавать компоненты Swing в потоке UI?
Возможно, я должен создать пользовательских поставщиков, которые возвратят компоненты Swing после SwingUtilities.invokeAndWait(Runnable)
создает их.
Мне не нравится идея запустить целое приложение в потоке UI, но возможно это - просто идеальное решение.
ИМО, вам следует создавать не компоненты с помощью Guice, а службы, которые, в свою очередь, будут создавать ваши компоненты. После внедрения службы можно легко убедиться, что создание компонента происходит в EDT (используя invokeAndWait
)
На самом деле, Swing не является многопоточным и требует запуска в EDT. Как следствие, да, ваши компоненты должны быть подготовлены в EDT путем вызова invokeAndWait
.
Возможно, вы захотите ознакомиться с моим проектом Guts-GUI (фреймворк приложений Swing, созданный на основе Guice). Guts-GUI гарантирует, что ваши компоненты, даже если они созданы Guice, созданы в EDT.
Сам Guice не предоставляет никаких стандартных возможностей для объявления компонента, который будет создан в EDT. Я не уверен, можно ли для этого использовать Guice Scopes (думаю, да), однако я не уверен, что какое-либо решение на основе Scope будет стоящим, особенно в отношении производительности.
Первым шагом к решению этой проблемы является создание Guice Injector изнутри EDT (с помощью SwingUtilities.invokeAndWait или invokeLater). Это в первую очередь то, что делает Guts-GUI. Следовательно, если некоторые компоненты создаются Guice на раннем этапе, они будут созданы в EDT.
Затем вы должны убедиться, что все экземпляры, внедренные Guice и требующие создания внедренных компонентов Swing, получены (например, через Injector.getInstance (...)
) из EDT.