在World Wind显示中获取JPopupMenu

时间:2016-11-28 12:24:26

标签: java worldwind

我需要在World Wind显示中添加右键单击JPopupMenu。世界风显示在JPanel。我几乎只是从World Wind的示例ApplicationTemplate.AppPanel类中复制了ApplicationTemplate内部类的成员变量和方法,将其粘贴到我需要WW-display的GUI中,并且已将复制的代码中的this.add(component)引用更改为myJPanel.add(component)

除了缺少弹出式菜单外,它的效果很好;我的应用程序中嵌入了World Wind显示,并且可以通过我的应用程序对话框控制它。

在世界风力展示JPopupMenu中添加JPanel之后,它似乎根本无法显示。我右键单击,没有弹出任何内容。我不认为这是隐藏菜单的重量级和轻量级Java组件问题,因为我可以将菜单附加到World Wind显示上方的组件(WWD位于BorderLayout CENTER中,其他组件位于相反,菜单将很快进入World Wind显示器的空间,而不会被它隐藏。为了安全起见,我设置了JPopupMenu' s setLightWeightPopupEnabled(false)并在主要类的静态初始化程序顶部JPopupMenu.setDefaultLightWeightPopupEnabled(false)

我使用MouseListener附加到包含World Wind显示的JPanel进行了测试,并且没有MouseListener个事件正在触发。所以我最好的猜测是我不应该将JPopupMenu添加到JPanel,而应该将它添加到wwd对象的某个特定子组件中。 wwd对象本身似乎没有添加弹出菜单的方法,我也看不到像" getGLCanvas"在wwd的方法中。如果我在这里正确的轨道,应该添加菜单的哪个组件,以及如何访问该组件?

所以我的问题非常简单,或者看起来如此:如何在World Wind展示中获得JPopupMenu

其次,这个问题也与在显示屏上显示MouseListener的方法相同,但我认为答案将不在显示屏上获得JPopupMenu的答案。

下面是我插入的World Wind模板代码,以及我对它的修改。其他地方的其他类使用getComponent()将包含World Wind显示的JPanel添加到我的应用程序的用户界面。我留下了默认的World Wind的东西,我注释掉了,以防有些重要。通过图层名称的String []循环只是一种方式,我可以轻松地只显示地图和单位比例。 JPopupMenu代码是构造函数的一半。为凌乱的代码道歉,但我认为你应该把它视为最好的帮助。

class MyClass
{

protected JComponent component;
public JComponent getComponent() { return component; }

protected WorldWindow wwd;
protected StatusBar statusBar;
protected ToolTipController toolTipController;
protected HighlightController highlightController;

MyClass()
{
    boolean includeStatusBar = false;
    component = new JPanel(new BorderLayout());

    this.wwd = this.createWorldWindow();
    ((Component) this.wwd).setPreferredSize(new Dimension(200,200));//canvasSize);

    // Create the default model as described in the current worldwind properties.
    Model m = (Model) WorldWind.createConfigurationComponent(AVKey.MODEL_CLASS_NAME);
    this.wwd.setModel(m);

    // Setup a select listener for the worldmap click-and-go feature
//            this.wwd.addSelectListener(new ClickAndGoSelectListener(this.getWwd(), WorldMapLayer.class));

    component.add((Component) this.wwd, BorderLayout.CENTER);
    if (includeStatusBar)
    {
        this.statusBar = new StatusBar();
        component.add(statusBar, BorderLayout.PAGE_END);
        this.statusBar.setEventSource(wwd);
    }

    // Add controllers to manage highlighting and tool tips.
//            this.toolTipController = new ToolTipController(this.getWwd(), AVKey.DISPLAY_NAME, null);
//            this.highlightController = new HighlightController(this.getWwd(), SelectEvent.ROLLOVER);

    java.util.List<String> desiredLayers = Arrays.asList(
        new String[] { "Blue Marble May 2004", /*"i-cubed Landsat",*/ "Scale bar"
        });
    for(Layer layer : getWwd().getModel().getLayers())
    {
        if(desiredLayers.contains( layer.getName() ))
        {
            System.out.println("INCLUDE " + layer.getName());
            layer.setEnabled(true);
        }
        else
        {
            System.out.println("EXCLUDE " + layer.getName());
            layer.setEnabled(false);
        }
    }


    JMenu menuZoom = new JMenu("Zoom");
    JMenuItem menuZoom_1028 = new JMenuItem("1028");
    menuZoom.add(menuZoom_1028);
    JMenuItem menuZoom_512 = new JMenuItem("512");
    menuZoom.add(menuZoom_512);
    JMenuItem menuZoom_256 = new JMenuItem("256");
    menuZoom.add(menuZoom_256);
    JMenuItem menuZoom_128 = new JMenuItem("128");
    menuZoom.add(menuZoom_128);
    JMenuItem menuZoom_64 = new JMenuItem("64");
    menuZoom.add(menuZoom_64);
    JMenuItem menuZoom_32 = new JMenuItem("32");
    menuZoom.add(menuZoom_32);
    JPopupMenu rclickMenu = new JPopupMenu();
    rclickMenu.add(menuZoom);
    component.setComponentPopupMenu(rclickMenu);

    menuZoom.getPopupMenu().setLightWeightPopupEnabled(false);

    component.addMouseListener(new MouseListener()
    {
        @Override
        public void mouseClicked(MouseEvent e)
        {
            System.out.println("mouseClicked");
        }

        @Override
        public void mousePressed(MouseEvent e)
        {
            System.out.println("mousePressed");
        }

        @Override
        public void mouseReleased(MouseEvent e)
        {
            System.out.println("mouseReleased");
        }

        @Override
        public void mouseEntered(MouseEvent e)
        {
            System.out.println("mouseEntered");
        }

        @Override
        public void mouseExited(MouseEvent e)
        {
            System.out.println("mouseExited");
        }
    });
}

protected WorldWindow createWorldWindow()
{
    return new WorldWindowGLCanvas();
}

public WorldWindow getWwd()
{
    return wwd;
}

public StatusBar getStatusBar()
{
    return statusBar;
}
}

1 个答案:

答案 0 :(得分:1)

经过大量挖掘,我终于想出了一个解决方法。

首先,我将解决关于从World Wind wwd对象获取GLPanel的愚蠢的子问题:wwd对象 a GLPanel。好吧,从技术上讲,WorldWindow是一个接口,但是对于我正在绘制的World Wind ApplicationTemplate应用程序,WorldWindow的实现是一个扩展{{1}的类。 }}。我暂时没有注意到这一点。

如上所述,应用于包含World Wind显示的GLPanel的鼠标侦听器不会触发我在地图上的鼠标操作,并且World Wind显示没有向其自身添加鼠标侦听器的方法。我终于意识到World Window有一个JPanel,它返回一个可以添加鼠标监听器的对象。所以我必须做getInputHandler()

据我所知,wwd.getInputHandler().addMouseListener(myMouseAdapter);并没有被世界风的展示所隐藏;它只是没有被触发弹出。通过上面针对鼠标监听器的修复,我通过自己打开弹出窗口来解决这个问题,而不是依赖于Swing内置的右键单击JPopupMenu支持。我是通过在鼠标监听器中调用JPopupMenu来完成的。

这是我弹出菜单的代码(在World Wind的初始化代码中):

jPopupMenu.show(component, event.getX(), event.getY());

我还添加了一些我需要的东西,如果它有用,我会提到。我添加了一个检查,以确保右键单击的点是专门在世界地图上,我还想知道后来右键单击了哪个点,因为一些菜单项用于与右键单击的任何内容进行交互。

在这些添加之后,代码看起来像这样:

    wwd.getInputHandler().addMouseListener(new MouseAdapter()
    {
        @Override
        public void mouseClicked(MouseEvent event)
        {
            // right-click context-menu
            if(event.getButton() == MouseEvent.BUTTON3)
            {
                // component is my JPanel which contains the WorldWindow
                rclickMenu.show(component, event.getX(), event.getY());
            }
        }
    });