我将Swing和Java3D结合在一起。挥杆组件的操纵应使用事件分配器线程完成,而Java3D组件的操纵应在BehaviourSchedulerThread中完成。

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

我在Canvas3D上启用了MouseListener。事件被发布到AWT事件队列中。然后,我想基于这些事件来修改Java3D环境,因此我使用了一种特殊的Behavior,可以将Runnable的行为发布到该行为。这样可以确保在Java3D的“行为”周期中执行Runnable(并且在“渲染”周期中不要修改任何内容)。

假设“行为”中的某些操作想要修改Swing模型。然后,我必须将新的Runnable发布到EDT。

这是正确的方法吗?

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

更新:
可以更清楚地定义问题,如下所示:

我有一个具有ActionListener的JButton“旋转多维数据集”。触发ActionListener之后,它将AWTEvent推送到Java3D Behavior中。行为触发后,它将修改“场景”图,然后将JButton actionListener和文本修改为“停止旋转”。

  • 单击JButton两次。
  • 第一个AWTEvent被调度到SpinActionListener。多维数据集开始旋转,并将JButton actionListener修改为StopSpinningActionListener
  • 第二个AWTEvent被调度到StopSpinningActionListener。多维数据集停止旋转,并将JButton actionListener修改为SpinActionListener

  • 实际发生的情况如下:
  • 单击JButton两次。这两个AWTEvent都被调度到SpinActionListener。这将创建一个Runnable以便在J3D Behavior中执行。
  • 第一个AWTEvent启动计时器以旋转多维数据集。然后,它将Runnable发布到EDT以修改按钮。
  • 第二个AWTEvent启动计时器以旋转多维数据集。多维数据集现在将以两倍快的速度旋转。然后,它将Runnable发布到EDT以修改按钮。

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

    最佳答案

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

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

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

    监听Canvas3D的AWTEvents。可以选择以下两种方法之一:

    MouseListener或的
  • WakeupOnBehaviorPost
  • WakeupOnAWTEvent

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

    通过Behavior.processStimulusSwingUtilities.invokeLater方法内部启动Swing组件更新不会造成任何问题。

    10-07 22:54