Я знаю его, вероятно, плохая форму, чтобы ответить на мой собственный вопрос, но я пришел к выводу, что один должен очереди обработчики событий после события в Swing. Причина в том, что каждый компонент может иметь более одного слушателя данного типа. Вы не знаете, какие слушатели прослушивают какой-либо данный компонент (сам свинг может добавить слушателей, о которых вы не знаете), и вы не знаете, какие предположения они делают о дереве компонентов и состоянии дерева, когда они обрабатывают мероприятие.
Теперь, поскольку каждый компонент может иметь несколько обработчиков событий для определенного типа события, мы не знаем, какой обработчик будет вызван первым. Если обработчик события модифицирует дерево компонентов, последующий обработчик событий для одного и того же типа события не увидит дерево компонентов, как это было во время события. Вместо этого он увидит дерево компонентов, как это было после моих изменений. Та же проблема существует для другого состояния приложения, которое может быть проверено и изменено двумя отдельными слушателями того же типа на одном и том же компоненте. Это, безусловно, не так.
Во-вторых, существует концепция событий, отправляемых EDT в последовательном порядке. то есть. Если событие х происходило до событий у в режиме реального времени, то обработчики событий для х должны выполняться до обработчиков событий для у. Теперь, если мой компонент, позвоните ему c1, имеет 2 обработчика событий для события actionPerformed()
- eh1 и eh2.Когда actionPerformed()
уволен на c1, eh1 вызывается для обработки события. Затем он модифицирует компонент c2 и вызывает событие itemStateChanged()
, которое должно быть запущено на c2. Поскольку это изменение было поставлено в очередь после завершения первого события actionPerformed()
(позже EDT), а потому, что c2 не ставит в очередь событие itemStateChanged()
, которое будет запущено позже на EDT, событие itemStateChanged()
обрабатывается всеми его слушателями. Только после этого второй прослушиватель actionPerformed()
(eh2) получает обработку оригинального события actionPerformed()
.
Если EH2 также слушатель itemStateChanged()
событий на компоненте c2, то, казалось бы, EH2 что itemStateChanged()
события действительно произошло до actionPerformed()
события. Это тоже неуместно.
Так что ответ на вопрос 1. Да, обработка событий код, который изменяет состояние приложения или компонента дерева должно быть запланировано на выполнение после событие обрабатывается. Обработчики событий должны проверять любое состояние, которое им нужно проверять во время события, но реагировать на событие (вносить изменения) позже на EDT, вызывая EventQueue.invokeLater()
.
Вторая часть моего вопроса касается того, чья ответственность заключается в обеспечении того, чтобы обработка событий происходила после самого события. Оглядываясь назад, это глупый вопрос. Та же проблема существует, если обработчики событий выполняются немедленно, когда происходит событие, или если они выполняются позже при вызове компонента EventQueue.invokeLater()
.
Кстати, пока я изучал это, я увидел, что не все компоненты Swing делают это равномерно. Например, JCheckBox
запускает события itemStateChanged()
сразу же, когда происходит событие, а JComponent
срабатывает componentResized()
(через супер класс java.awt.Component
) позже на EDT.
Так что кажется, что самый надежный способ обработки событий - сначала проверить свое состояние, чтобы принимать решения о том, какие действия вы предпримете, а затем выполнить эти действия позже на EDT. Есть предположения? Мне бы хотелось услышать про чужие мысли об этом.
Да, но вопрос о ГДЕ на EDT. Компоненты могут иметь несколько прослушивателей для каждого типа события. Первый обработчик событий может изменить какое-либо состояние в компоненте gui или в другом месте, прежде чем последующие обработчики смогут проверять состояние во время запуска события. – Jesse
Я вспоминаю, что нет возможности предсказать, какой из слушателей будет срабатывать первым, и этот код должен быть написан с учетом этого. –