java - 在世界风显示中获取 JPopupMenu

标签 java worldwind

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

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

添加JPopupMenu后前往世界风展JPanel ,似乎根本没有表现出来。我右键单击,什么也没有弹出。我不认为这是隐藏菜单的重量级与轻量级 Java 组件问题,因为我可以将菜单附加到世界风显示上方的组件(WWD 位于 BorderLayout 中心,其他组件位于其北部)并且菜单会很高兴地进入世界风显示的空间,而不会被它隐藏。为了安全起见,我设置了JPopupMenusetLightWeightPopupEnabled(false)在主类的静态初始化器顶部我做了 JPopupMenu.setDefaultLightWeightPopupEnabled(false)

我用 MouseListener 进行了测试附于JPanel包含世界风显示,并且没有 MouseListener事件正在触发。所以我最好的猜测是我不应该添加 JPopupMenuJPanel但应该将其添加到 wwd 对象的某些特定子组件中。 wwd 对象本身似乎没有添加弹出菜单的方法,并且我在 wwd 的方法中没有看到类似“getGLCanvas”的内容。如果我的思路是正确的,菜单应该添加到哪个组件,以及如何访问该组件?

所以我的问题非常简单,或者看起来是这样:我如何获得 JPopupMenu到世界风显示屏上?

其次,这个问题也同样要求得到 MouseListener在显示屏上,但我认为这个问题的答案将超出获得 JPopupMenu 的答案。在显示屏上。

下面是我插入的世界风模板代码,以及我对其的修改。其他地方的另一个类使用 getComponent()添加JPanel包含世界风显示到我的应用程序的用户界面。我保留了默认的“世界风”内容,并对其进行了注释,以防万一有什么重大意义。通过图层名称的 String[] 循环只是我轻松仅显示 map 和单位比例的一种方法。 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;
}
}

最佳答案

经过一番研究,我终于找到了解决方法。

首先,我将解决有关从 World Wind wwd 对象获取 GLPanel 的愚蠢子问题:wwd 对象一个 GLPanel >。嗯,从技术上讲,WorldWindow 是一个接口(interface),但在我从中绘图的 World Wind ApplicationTemplate 应用程序中,WorldWindow 的实现> 是一个扩展GLPanel 的类。我有一段时间没有注意到这一点。

如问题所述,应用于包含世界风显示的 JPanel 的鼠标监听器不会触发我在 map 上的鼠标操作,并且世界风显示没有添加鼠标监听器的方法对自己。我终于意识到世界窗口有一个 getInputHandler() ,它返回一个可以添加鼠标监听器的对象。所以我必须做 wwd.getInputHandler().addMouseListener(myMouseAdapter);

正如我所相信的,JPopupMenu 并没有被世界风显示隐藏;它只是没有被触发弹出。通过上述针对鼠标监听器的修复,我通过自己打开弹出窗口而不是依赖 Swing 的内置右键单击 JPopupMenu 支持来解决此问题。我通过从鼠标监听器中调用 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());
            }
        }
    });

我还添加了一些我需要的东西,如果有用的话我会提到。我添加了一项检查以确保右键单击的点专门位于世界地图上,并且我还想稍后知道右键单击的位置,因为某些菜单项用于与右键单击的内容进行交互。

添加这些内容后,代码如下所示:

    wwd.getInputHandler().addMouseListener(new MouseAdapter()
    {
        @Override
        public void mouseClicked(MouseEvent event)
        {
            // right-click context-menu
            if(event.getButton() == MouseEvent.BUTTON3)
            {
                Position p = wwd.getCurrentPosition();
                // abort if not on-map
                if(p == null) return;

                // need later to know what was right-clicked on
                mPositionAtRightClickMoment = wwd.getCurrentPosition();

                rclickMenu.show(component, event.getX(), event.getY());
            }
        }
    });

关于java - 在世界风显示中获取 JPopupMenu,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40844281/

相关文章:

Java世界风: how to access AnalyticSurface on DragEvent

java - 无法在 Win2008 64 位上设置 Java 堆空间 > 2GB

java - x 时间后跳过 Selenium 测试

java - 如何在单击按钮时导出到 .excel 时添加 openwith 并另存为对话框

java - JComboBox 自动完成

java - 使用 Java WorldWind,但想要替代方案

java - 美国宇航局世界风 : How do you fix these weird run time exceptions?

javascript - WebWorldWind 可渲染位置更新

javafx - 如何在 WorldWind 中绘制具有高程表示的线

java - 使用gradle获取sh的输出