Я объединяю Swing и Java3D вместе. Манипуляции с компонентами Swing должны выполняться с использованием потока диспетчера событий, а манипуляции с компонентами Java3D - в BehaviourSchedulerThread.
Java3D отображает сцену, а затем выполняет все действия, связанные с этой сценой.
У меня включен MouseListener на Canvas3D. События публикуются в очереди событий AWT. Затем я хочу изменить среду Java3D на основе этих событий, поэтому я использую специальное поведение, где я могу публиковать в Runnable. Это гарантирует, что Runnable выполняются во время цикла поведения Java3D (и не изменяют ничего во время цикла рендеринга).
Предположим, что некоторые операции в поведении хотят изменить модель Swing. Затем я должен опубликовать новый Runnable для EDT.
Это правильный способ сделать это?
Используя эту технику, я испытываю много проблем со слушателем мыши. Я обновляю точку в своей модели Java3D и одновременно обновляю графический интерфейс Swing.
Обновление :
Проблема может быть более четко определена следующим образом:
У меня есть «спин-куб» JButton, в котором есть ActionListener. После запуска ActionListener он помещает AWTEvent в поведение Java3D. После того как Behavior сработает, он изменяет граф сцены, а затем изменяет actionBistener и текст JButton, превращая его в «Stop spinning».
- Нажмите JButton дважды.
- Первое событие AWTEvent отправляется в SpinActionListener. Куб начинает вращаться, и actionListener JButton изменяется на
StopSpinningActionListener
.
- Второе событие AWTEvent отправляется в StopSpinningActionListener. Куб перестает вращаться, и действие ActionListener JButton изменяется на
SpinActionListener
.
На самом деле происходит следующее:
- Дважды нажмите на кнопку JButton. Оба
AWTEvent
отправляются на SpinActionListener
. Это создает Runnable для выполнения внутри J3D Behavior.
- Первый AWTEvent запускает таймер для вращения куба. Затем он публикует Runnable в EDT для изменения кнопки.
- Второй AWTEvent запускает таймер для вращения куба. Куб теперь будет вращаться в два раза быстрее. Затем он публикует Runnable в EDT для изменения кнопки.
Очевидно, я не должен зависеть от последовательной обработки AWTEvent. Я не могу ждать в EDT, чтобы поведение сработало, потому что любой SwingUtilities.invokeAndWait () будет вызывать взаимоблокировку.