Объедините Java Swing и Java3D: проблемы производительности с параллелизмом - PullRequest
10 голосов
/ 13 января 2012

Я объединяю 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».

  1. Нажмите JButton дважды.
  2. Первое событие AWTEvent отправляется в SpinActionListener. Куб начинает вращаться, и actionListener JButton изменяется на StopSpinningActionListener.
  3. Второе событие AWTEvent отправляется в StopSpinningActionListener. Куб перестает вращаться, и действие ActionListener JButton изменяется на SpinActionListener.

На самом деле происходит следующее:

  1. Дважды нажмите на кнопку JButton. Оба AWTEvent отправляются на SpinActionListener. Это создает Runnable для выполнения внутри J3D Behavior.
  2. Первый AWTEvent запускает таймер для вращения куба. Затем он публикует Runnable в EDT для изменения кнопки.
  3. Второй AWTEvent запускает таймер для вращения куба. Куб теперь будет вращаться в два раза быстрее. Затем он публикует Runnable в EDT для изменения кнопки.

Очевидно, я не должен зависеть от последовательной обработки AWTEvent. Я не могу ждать в EDT, чтобы поведение сработало, потому что любой SwingUtilities.invokeAndWait () будет вызывать взаимоблокировку.

1 Ответ

4 голосов
/ 13 января 2012

Какой WakeupCriterion используется для пробуждения вашего специального объекта Behavior?

Исходный код Java 3D включает в себя служебные классы

com.sun.j3d.utils.behaviors.mouse.MouseBehavior/MouseRotate 

, которые слушают Canvas3D AWTEvents.Можно выбрать одну из двух альтернатив:

  1. MouseListener с WakeupOnBehaviorPost или
  2. WakeupOnAWTEvent.

Этот пример кода может быть полезен.

Инициирование обновления компонента Swing из метода Behavior.processStimulus с помощью SwingUtilities.invokeLater не должно вызывать никаких проблем.

...