结合 Java Swing 和 Java3D:并发性的性能问题
我将 Swing 和 Java3D 结合在一起。 swing 组件的操作应使用事件调度程序线程来完成,而 Java3D 组件的操作应在 BehaviourSchedulerThread 中完成。
Java3D 渲染场景,然后执行与场景关联的所有行为。
我在 Canvas3D 上启用了 MouseListener。事件被发布到 AWT 事件队列中。然后我想根据这些事件修改 Java3D 环境,因此我使用一个特殊的行为,我可以将 Runnable 发布到其中。这确保了 Runnable 在 Java3D 的行为周期期间执行(并且在渲染周期期间不修改任何内容)。
假设Behavior中的一些操作想要修改Swing模型。然后我必须将新的 Runnable 发布到 EDT。
这是正确的方法吗?
使用这种技术,我在鼠标侦听器上遇到了很多问题。我在行为中更新了 Java3D 模型中的一个点,同时更新了 swing GUI。
更新: 这个问题可以更清楚地定义如下:
我有一个 JButton“旋转立方体”,它有一个 ActionListener。一旦 ActionListener 被触发,它就会将 AWTEvent 推送到 Java3D 行为中。一旦行为触发,它就会修改场景图,然后修改 JButton actionListener 和文本以变为“停止旋转”。
- 单击 JButton 两次。
- 第一个 AWTEvent 被分派到 SpinActionListener。立方体开始旋转,并且 JButton actionListener 被修改为
StopSpinningActionListener
。 - 第二个 AWTEvent 被分派到 StopSpinningActionListener。立方体停止旋转,并且 JButton actionListener 被修改为
SpinActionListener
。
实际发生的情况如下:
- 单击 JButton 两次。两个
AWTEvent
都被分派给SpinActionListener
。这将创建一个在 J3D 行为内执行的 Runnable。 - 第一个 AWTEvent 启动一个计时器来旋转多维数据集。然后,它将 Runnable 发送到 EDT 以修改按钮。
- 第二个 AWTEvent 启动一个计时器来旋转多维数据集。立方体现在的旋转速度是原来的两倍。然后,它将 Runnable 发送到 EDT 以修改按钮。
显然,我不应该依赖 AWTEvent 的顺序处理。我无法在 EDT 中等待行为触发,因为任何 SwingUtilities.invokeAndWait() 都会导致死锁。
I am combining Swing and Java3D together. Manipulations of swing components should be done using the Event Dispatcher Thread, while manipulations of Java3D components should be done in the BehaviourSchedulerThread.
Java3D renders the scene and then executes all of the behavior associated to the scene.
I have a MouseListener enabled on the Canvas3D. Events are posted into the AWT Event queue. I then want to modify the Java3D environment based on these events, so I use a special Behavior where I can post Runnable's to. This makes sure the Runnable's are executed during the Behavior cycle of Java3D (and do not modify anyting during the Render cycle).
Suppose some operations in the Behavior want to modify the Swing model. I then have to post a new Runnable to the EDT.
Is this the correct way to do it?
Using this technique, I experience a lot of problems on a mouse listener. I update a point in my Java3D model in the behaviour, and I update the swing GUI at the same time.
Update:
The problem can be more clearly defined as follows:
I have a JButton "spin cube" which has an ActionListener. Once the ActionListener is fired, it pushes the AWTEvent into a Java3D Behavior. Once the Behavior fires, it modifies the Scene graph and then modifies the JButton actionListener and text to become "Stop spinning".
- Click on the JButton twice.
- The first AWTEvent gets dispatched to SpinActionListener. The cube starts spinning and the JButton actionListener is modified to
StopSpinningActionListener
. - The second AWTEvent gets dispatched to StopSpinningActionListener. The cube stops spinning and the JButton actionListener is modified to
SpinActionListener
.
What actually happens is the following:
- Click on a JButton twice. Both
AWTEvent
s get dispatched toSpinActionListener
. This creates a Runnable to execute inside the J3D Behavior. - The first AWTEvent starts a timer to spin the cube. It then posts a Runnable to the EDT to modify the button.
- The second AWTEvent starts a timer to spin the cube. The cube will now spin twice as fast. It then posts a Runnable to the EDT to modify the button.
Obviously, I should not be depending on AWTEvent's getting processed sequentially. I cannot wait in the EDT for the behavior to fire, because any SwingUtilities.invokeAndWait() will then cause a deadlock.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
哪个
WakeupCriterion
用于唤醒您的特殊Behavior对象?Java 3D 的源代码包括
监听 Canvas3D 的 AWTEvents 的实用程序类。可以选择以下两种替代方案之一:
MouseListener
与WakeupOnBehaviorPost
或WakeupOnAWTEvent
。此代码示例可能会有所帮助。
通过
SwingUtilities.invokeLater
在Behavior.processStimulus
方法中启动 Swing 组件更新不会导致任何问题。Which
WakeupCriterion
is used to wake-up your special Behavior object?Java 3D's source code includes the utility classes
which listens to Canvas3D's
AWTEvents
. One of two alternatives can be chosen:MouseListener
withWakeupOnBehaviorPost
orWakeupOnAWTEvent
.This code sample might be helpful.
Initiating a Swing component update from within the
Behavior.processStimulus
method viaSwingUtilities.invokeLater
shouldn't cause any problems.