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