简体   繁体   English

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

[英]Combine Java Swing and Java3D: performance problems with concurrency

I am combining Swing and Java3D together. 我将Swing和Java3D结合在一起。 Manipulations of swing components should be done using the Event Dispatcher Thread, while manipulations of Java3D components should be done in the BehaviourSchedulerThread. 应使用Event Dispatcher Thread完成swing组件的操作,而Java3D组件的操作应在BehaviourSchedulerThread中完成。

Java3D renders the scene and then executes all of the behavior associated to the scene. Java3D渲染场景,然后执行与场景关联的所有行为。

I have a MouseListener enabled on the Canvas3D. 我在Canvas3D上启用了MouseListener。 Events are posted into the AWT Event queue. 事件将发布到AWT事件队列中。 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. 然后我想基于这些事件修改Java3D环境,所以我使用了一个特殊的行为,我可以将Runnable发布到。 This makes sure the Runnable's are executed during the Behavior cycle of Java3D (and do not modify anyting during the Render cycle). 这确保Runnable在Java3D的行为周期中执行(并且在渲染周期期间不要修改任何内容)。

Suppose some operations in the Behavior want to modify the Swing model. 假设行为中的某些操作想要修改Swing模型。 I then have to post a new Runnable to the EDT. 然后我必须向EDT发布一个新的Runnable。

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. 我在行为中更新了Java3D模型中的一个点,同时更新了swing GUI。

Update : The problem can be more clearly defined as follows: 更新 :问题可以更明确地定义如下:

I have a JButton "spin cube" which has an ActionListener. 我有一个JButton“旋转立方体”,它有一个ActionListener。 Once the ActionListener is fired, it pushes the AWTEvent into a Java3D Behavior. 一旦触发了ActionListener,它就会将AWTEvent推送到Java3D行为中。 Once the Behavior fires, it modifies the Scene graph and then modifies the JButton actionListener and text to become "Stop spinning". 一旦行为触发,它会修改场景图,然后修改JButton actionListener和文本以变为“停止旋转”。

  1. Click on the JButton twice. 点击两次JButton。
  2. The first AWTEvent gets dispatched to SpinActionListener. 第一个AWTEvent被调度到SpinActionListener。 The cube starts spinning and the JButton actionListener is modified to StopSpinningActionListener . 多维数据集开始旋转,JButton actionListener被修改为StopSpinningActionListener
  3. The second AWTEvent gets dispatched to StopSpinningActionListener. 第二个AWTEvent被调度到StopSpinningActionListener。 The cube stops spinning and the JButton actionListener is modified to SpinActionListener . 立方体停止旋转,JButton actionListener被修改为SpinActionListener

What actually happens is the following: 实际发生的是以下内容:

  1. Click on a JButton twice. 单击JButton两次。 Both AWTEvent s get dispatched to SpinActionListener . 两个AWTEvent被调度到SpinActionListener This creates a Runnable to execute inside the J3D Behavior. 这将创建一个在J3D行为内执行的Runnable。
  2. The first AWTEvent starts a timer to spin the cube. 第一个AWTEvent启动一个计时器来旋转立方体。 It then posts a Runnable to the EDT to modify the button. 然后它将Runnable发布到EDT以修改按钮。
  3. The second AWTEvent starts a timer to spin the cube. 第二个AWTEvent启动一个计时器来旋转立方体。 The cube will now spin twice as fast. 立方体现在旋转速度快两倍。 It then posts a Runnable to the EDT to modify the button. 然后它将Runnable发布到EDT以修改按钮。

Obviously, I should not be depending on AWTEvent's getting processed sequentially. 显然,我不应该依赖于AWTEvent的顺序处理。 I cannot wait in the EDT for the behavior to fire, because any SwingUtilities.invokeAndWait() will then cause a deadlock. 我不能在EDT中等待触发行为,因为任何SwingUtilities.invokeAndWait()都会导致死锁。

Which WakeupCriterion is used to wake-up your special Behavior object? 哪个WakeupCriterion用于唤醒您的特殊行为对象?

Java 3D's source code includes the utility classes Java 3D的源代码包括实用程序类

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

which listens to Canvas3D's AWTEvents . 它监听Canvas3D的AWTEvents One of two alternatives can be chosen: 可以选择以下两种选择之一:

  1. MouseListener with WakeupOnBehaviorPost or 带有WakeupOnBehaviorPost或的MouseListener
  2. WakeupOnAWTEvent . WakeupOnAWTEvent

This code sample might be helpful. 此代码示例可能会有所帮助。

Initiating a Swing component update from within the Behavior.processStimulus method via SwingUtilities.invokeLater shouldn't cause any problems. 通过SwingUtilities.invokeLaterBehavior.processStimulus方法中启动Swing组件更新不应该导致任何问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM