在 World Wind 显示中获取 JPopupMenu
Getting a JPopupMenu in a World Wind display
我需要在 World Wind 显示中添加右键单击 JPopupMenu
。 World Wind显示在JPanel
。我几乎只是从 World Wind 的示例 ApplicationTemplate
class 中复制了 ApplicationTemplate.AppPanel
inner-class 的成员变量和方法,并将其粘贴到我需要 WW- 的 GUI 中显示,并将 this.add(component)
引用从复制的代码更改为 myJPanel.add(component)
.
除了缺少弹出菜单外,它工作得很好;我的应用程序中嵌入了一个 World Wind 显示,并通过我的应用程序的对话框对其进行控制。
世界风显示的JPanel
加了一个JPopupMenu
后,好像完全不显示了。我右键单击,没有弹出任何内容。我不认为这是隐藏菜单的重量级与轻量级 Java 组件问题,因为我可以将菜单附加到 World Wind 显示上方的组件(WWD 在 BorderLayout
中心,其他组件是在它的北)而不是菜单将愉快地进入世界风显示的 space 而不会被它隐藏。为了安全起见,我设置了 JPopupMenu
的 setLightWeightPopupEnabled(false)
并在主 class 的静态初始化程序顶部设置了 JPopupMenu.setDefaultLightWeightPopupEnabled(false)
我用 MouseListener
附加到包含世界风显示的 JPanel
进行了测试,MouseListener
事件中的 none 正在触发。所以我最好的猜测是我不应该将 JPopupMenu
添加到 JPanel
而应该将它添加到 wwd 对象的某些特定子组件。 wwd 对象本身似乎没有添加弹出菜单的方法,而且我在 wwd 的方法中也没有看到任何类似 "getGLCanvas" 的东西。如果我在这里的方向正确,应该将菜单添加到哪个组件,以及如何访问该组件?
所以我的问题很简单,或者看起来很简单:如何在 World Wind 显示屏上显示 JPopupMenu
?
其次,这个问题也提出了在显示器上显示 MouseListener
的问题,但我认为这个问题的答案与在显示器上显示 JPopupMenu
的答案不符。
下面是我插入的世界风模板代码,以及我对它的修改。其他地方的另一个 class 使用 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;
}
}
经过大量挖掘,我终于找到了解决方法。
首先,我将解决关于从 World Wind wwd 对象获取 GLPanel
的愚蠢子问题:wwd 对象 是 a GLPanel
.好吧,从技术上讲,WorldWindow
是一个接口,但对于我正在绘制的 World Wind ApplicationTemplate
应用程序,WorldWindow
的实现是一个 class,它扩展 GLPanel
。我有一段时间没注意到。
如问题所述,应用于包含世界风显示的 JPanel
的鼠标侦听器不会触发我在地图上的鼠标操作,并且世界风显示没有将鼠标侦听器添加到的方法本身。我终于意识到 World Window 有一个 getInputHandler()
其中 returns 一个可以添加鼠标侦听器的对象。所以我不得不做 wwd.getInputHandler().addMouseListener(myMouseAdapter);
正如我所相信的那样,JPopupMenu
并没有被世界风显示隐藏;它只是没有被触发弹出。通过以上针对鼠标侦听器的修复,我通过自己打开弹出窗口而不是依赖 Swing 的内置右键单击 JPopupMenu
支持来解决此问题。我通过从鼠标侦听器中调用 jPopupMenu.show(component, event.getX(), event.getY());
来完成此操作。
这是我为弹出菜单所做的代码(在 World Wind 的初始化代码中):
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());
}
}
});
我需要在 World Wind 显示中添加右键单击 JPopupMenu
。 World Wind显示在JPanel
。我几乎只是从 World Wind 的示例 ApplicationTemplate
class 中复制了 ApplicationTemplate.AppPanel
inner-class 的成员变量和方法,并将其粘贴到我需要 WW- 的 GUI 中显示,并将 this.add(component)
引用从复制的代码更改为 myJPanel.add(component)
.
除了缺少弹出菜单外,它工作得很好;我的应用程序中嵌入了一个 World Wind 显示,并通过我的应用程序的对话框对其进行控制。
世界风显示的JPanel
加了一个JPopupMenu
后,好像完全不显示了。我右键单击,没有弹出任何内容。我不认为这是隐藏菜单的重量级与轻量级 Java 组件问题,因为我可以将菜单附加到 World Wind 显示上方的组件(WWD 在 BorderLayout
中心,其他组件是在它的北)而不是菜单将愉快地进入世界风显示的 space 而不会被它隐藏。为了安全起见,我设置了 JPopupMenu
的 setLightWeightPopupEnabled(false)
并在主 class 的静态初始化程序顶部设置了 JPopupMenu.setDefaultLightWeightPopupEnabled(false)
我用 MouseListener
附加到包含世界风显示的 JPanel
进行了测试,MouseListener
事件中的 none 正在触发。所以我最好的猜测是我不应该将 JPopupMenu
添加到 JPanel
而应该将它添加到 wwd 对象的某些特定子组件。 wwd 对象本身似乎没有添加弹出菜单的方法,而且我在 wwd 的方法中也没有看到任何类似 "getGLCanvas" 的东西。如果我在这里的方向正确,应该将菜单添加到哪个组件,以及如何访问该组件?
所以我的问题很简单,或者看起来很简单:如何在 World Wind 显示屏上显示 JPopupMenu
?
其次,这个问题也提出了在显示器上显示 MouseListener
的问题,但我认为这个问题的答案与在显示器上显示 JPopupMenu
的答案不符。
下面是我插入的世界风模板代码,以及我对它的修改。其他地方的另一个 class 使用 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;
}
}
经过大量挖掘,我终于找到了解决方法。
首先,我将解决关于从 World Wind wwd 对象获取 GLPanel
的愚蠢子问题:wwd 对象 是 a GLPanel
.好吧,从技术上讲,WorldWindow
是一个接口,但对于我正在绘制的 World Wind ApplicationTemplate
应用程序,WorldWindow
的实现是一个 class,它扩展 GLPanel
。我有一段时间没注意到。
如问题所述,应用于包含世界风显示的 JPanel
的鼠标侦听器不会触发我在地图上的鼠标操作,并且世界风显示没有将鼠标侦听器添加到的方法本身。我终于意识到 World Window 有一个 getInputHandler()
其中 returns 一个可以添加鼠标侦听器的对象。所以我不得不做 wwd.getInputHandler().addMouseListener(myMouseAdapter);
正如我所相信的那样,JPopupMenu
并没有被世界风显示隐藏;它只是没有被触发弹出。通过以上针对鼠标侦听器的修复,我通过自己打开弹出窗口而不是依赖 Swing 的内置右键单击 JPopupMenu
支持来解决此问题。我通过从鼠标侦听器中调用 jPopupMenu.show(component, event.getX(), event.getY());
来完成此操作。
这是我为弹出菜单所做的代码(在 World Wind 的初始化代码中):
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());
}
}
});