在World Wind中单击时禁用地球移动

时间:2015-07-14 19:00:28

标签: java swing worldwind

我正试图在World Wind中禁用鼠标点击地球的移动。我希望能够做到:

void disableGlobeDrag(WorldWindowGLCanvas ww) {
    ww.addMouseMotionListener(new MyMouseMotionListener());
}

其中MyMouseMotionListener消耗所有鼠标事件。这不行,所以我必须这样做:

void disableGlobeDrag(WorldWindowGLCanvas ww) {
    for(MouseMotionListener l : ww.getMouseMotionListeners()) {
        if(l.getClass().toString().equals("class gov.nasa.worldwind.awt.AWTInputHandler")) {
            ww.removeMouseMotionListener(l);
        }
    }
}

预计消耗的鼠标事件是否仍应达到gov.nasa.worldwind.awt.AWTInputHandler监听器?

更新: WorldWindowGLCanvas只是在addMouseMotionListener()上拨打java.awt.Component,所以显然我不明白消费事件是如何运作的。

更新2:尽管与Swing共享接口,但使用WorldWindowGLCanvas.removeMouseMotionListener()作为参数调用AWTInputHandler将阻止所有其他MouseMotionListener接收事件。应该使用AWTInputHandler上的添加和删除方法。

3 个答案:

答案 0 :(得分:3)

不幸的是,将MouseMotionListener删除为@trashgod建议不起作用,因为发生了一些World Wind特定行为:删除gov.nasa.worldwind.awt.AWTInputHandler会导致其他MouseMotionListener停止接收事件通知。

要禁用全局拖动并仍然在另一个MouseMotionListener中接收事件,则必须执行以下步骤:

获取对World Wind的AWTInputHandler

的引用
AWTInputHandler wwHandler = null;
// get World Wind's AWTInputHandler class:
for (MouseMotionListener l : ww.getMouseMotionListeners()) {
    if(l instanceof AWTInputHandler) {
        wwHandler = (AWTInputHandler)l;
        break;
    }
}

创建一个消耗事件的MouseMotionListener

public class MyMouseMotionListener implements MouseMotionListener {
    @Override
    public void mouseDragged(MouseEvent e) {
        // consume the event so the globe position does not change
        e.consume();
        if (e.getSource() instanceof WorldWindowGLCanvas) {
            // get the position of the mouse
            final WorldWindowGLCanvas canvas = ((WorldWindowGLCanvas) e.getSource());
            final Position p = canvas.getCurrentPosition();
            // do something with the position here
        }
    }
    @Override
    public void mouseMoved(MouseEvent e) {
        e.consume();
    }
}

将鼠标移动侦听器添加到AWTInputHandler

if(wwHandler != null) {
    wwHandler.addMouseMotionListener(new MyMouseMotionListener());
} else {
    // I don't think this should happen unless the AWTInputHandler
    // is explicitly removed by client code
    logger.error("Couldn't find AWTInputHandler");
}

那就是说,我不知道为什么WorldWindowGLCanvas使用的是Component.addMouseMotionListener()而不是AWTInputHandler.addMouseMotionListener()

答案 1 :(得分:2)

为什么不能正常工作

正如所讨论的here,许多事件来源都维持EventListenerList。规定的方案允许添加或删除任意数量的侦听器。此相关example列出了DocumentListener注册到文本组件Document的所有实例。没有一个听众会抢先一个。

您可能会做什么:

给定WorldWindowGLCanvas的实例,您可以查看getMouseMotionListeners()返回的数组,并根据保证调用removeMouseMotionListener()

答案 2 :(得分:0)

在努力实现这一目标并绊倒这个解决方案之后,我相信我已经提出了“正确”的解决方案。完全删除鼠标移动侦听器在技术上是有效的,但它会破坏可能有用的其他功能(KML树节点选择,在屏幕视图控件上)。

创建子类输入处理程序以删除“移至”功能

public class MyOrbitViewInputHandler extends OrbitViewInputHandler
{
  public MyOrbitViewInputHandler()
  {
    // Disable single click to pan functionality
    ViewInputAttributes.ActionAttributes actionAttrs =
      this.getAttributes().getActionMap(ViewInputAttributes.DEVICE_MOUSE).getActionAttributes(ViewInputAttributes.VIEW_MOVE_TO);
    actionAttrs.setMouseActionListener(null);
  }
}

在worldwind.xml配置文件中指定新的输入处理程序

<Property name="gov.nasa.worldwind.avkey.ViewInputHandlerClassName"
          value="mil.dtra.nucs.coe.ui.map.MyOrbitViewInputHandler"/>

使用此方法,在画布上发生的所有其他鼠标交互仍然可以正常工作,但“单击以平移”功能将被删除。

如果您对可能覆盖的其他指定行为感到好奇,可以查看gov.nasa.worldwind.awt.BasicViewInputHandler