Объединение SWT и AWT/Swing: какой поток GUI взять?
Работая над крупномасштабным SWT-приложением, я наткнулся на некоторый код, используя мост AWT/Swing, который полностью смутил меня и заставил задуматься о последствиях использования двух потоков GUI.
public void createContent(final String html) {
// Bridge to AWT
frame = SWT_AWT.new_Frame(this);
rootPane = new JPanel();
rootPane.setLayout(new GridBagLayout());
JRootPane rp = new JRootPane();
rp.getContentPane().add(rootPane);
rp.validate();
frame.add(rp);
frame.validate();
// Create components in AWT user interface thread (deadlock prevention)
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
initializeLookAndFeel();
initializeToolbar();
initializeHTMLEditor();
setHTML(html, false);
}
});
rootPane.repaint();
rootPane.validate();
}
Не вдаваясь в детали, как вы уже догадались, многие элементы Swing добавляются в "фрейм моста" внутри методов инициализации.
В этом случае меня смущает вызов потока диспетчера событий AWT (EDT) для создания компонентов Swing. Я бы просто добавил все элементы GUI внутри потока пользовательского интерфейса SWT. Я не уверен, почему предпочтительнее разделить создание GUI между двумя потоками.
Возможно, кто-то может рассказать о том, что происходит за кулисами. Особенно на взаимодействие обоих потоков с помощью моста. Почему или когда имеет смысл отправлять создание материалов AWT в EDT, как в примере кода?
1 ответ
В SWT каждый элемент пользовательского интерфейса должен быть создан / обработан / доступен в потоке пользовательского интерфейса, поскольку существует checkWidget
вызов метода перед отправкой системных сигналов. Этот метод проверяет, является ли текущий поток потоком пользовательского интерфейса или нет, и выдает ошибку. Причиной такого выбора является то, что доступ к графическому контексту является однопоточным, и это относится и к размаху. Таким образом, вы должны вызывать каждый виджет, обрабатывающий в своем собственном потоке, SWT с Display.syncExec(....)
или же Display.asyncExec(....)
и качели в EventQueue
нить