结合Java Swing和Java3D:并发性能问题

par*_*tje 10 java concurrency swing java-3d

我将Swing和Java3D结合在一起.应使用Event Dispatcher Thread完成swing组件的操作,而Java3D组件的操作应在BehaviourSchedulerThread中完成.

Java3D渲染场景,然后执行与场景关联的所有行为.

我在Canvas3D上启用了MouseListener.事件将发布到AWT事件队列中.然后我想基于这些事件修改Java3D环境,所以我使用了一个特殊的行为,我可以将Runnable发布到.这确保Runnable在Java3D的行为周期中执行(并且在渲染周期期间不要修改任何内容).

假设行为中的某些操作想要修改Swing模型.然后我必须向EDT发布一个新的Runnable.

这是正确的方法吗?

使用这种技术,我在鼠标监听器上遇到了很多问题.我在行为中更新了Java3D模型中的一个点,同时更新了swing GUI.

更新:问题可以更明确地定义如下:

我有一个JButton"旋转立方体",它有一个ActionListener.一旦触发了ActionListener,它就会将AWTEvent推送到Java3D行为中.一旦行为触发,它会修改场景图,然后修改JButton actionListener和文本以变为"停止旋转".

  1. 点击两次JButton.
  2. 第一个AWTEvent被调度到SpinActionListener.多维数据集开始旋转,JButton actionListener被修改为StopSpinningActionListener.
  3. 第二个AWTEvent被调度到StopSpinningActionListener.立方体停止旋转,JButton actionListener被修改为SpinActionListener.

实际发生的是以下内容:

  1. 单击JButton两次.两人都AWTEvent被派遣到了SpinActionListener.这将创建一个在J3D行为内执行的Runnable.
  2. 第一个AWTEvent启动一个计时器来旋转立方体.然后它将Runnable发布到EDT以修改按钮.
  3. 第二个AWTEvent启动一个计时器来旋转立方体.立方体现在旋转速度快两倍.然后它将Runnable发布到EDT以修改按钮.

显然,我不应该依赖于AWTEvent的顺序处理.我不能在EDT中等待触发行为,因为任何SwingUtilities.invokeAndWait()都会导致死锁.

小智 5

哪个WakeupCriterion用于唤醒您的特殊 Behavior 对象?

Java 3D 的源代码包括实用程序类

com.sun.j3d.utils.behaviors.mouse.MouseBehavior/MouseRotate 
Run Code Online (Sandbox Code Playgroud)

听 Canvas3D 的AWTEvents. 可以选择以下两种方案之一:

  1. MouseListenerWakeupOnBehaviorPost
  2. WakeupOnAWTEvent.

此代码示例可能会有所帮助。

Behavior.processStimulus方法中通过 via启动 Swing 组件更新SwingUtilities.invokeLater应该不会导致任何问题。