这是我的问题: 我有一个jList和一个弹出菜单。当我右键单击jList时,弹出菜单显示。问题是鼠标指向的jList项目不会选择。 我希望它能做到这一点。当我将光标指向列表中的某个项目并按下右键时,我想要发生两件事。选择我单击的项目并显示弹出菜单。
我试过了:
jLists.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
jList.setSelectedIndex(jList.locationToIndex(e.getPoint()));
}
});
jList.setComponentPopupMenu(jPopupMenu);
但它只显示弹出菜单。 如果我删除这一行:
jList.setComponentPopupMenu(jPopupMenu);
然后右键单击选择有效(但弹出菜单不显示)。
那么,您认为使这两个函数(两者)都起作用的最佳方法是什么?
谢谢,对不起我的英语。
答案 0 :(得分:27)
不要setComponentPopupMenu
。在MouseAdapter
执行以下操作:
public void mousePressed(MouseEvent e) {check(e);}
public void mouseReleased(MouseEvent e) {check(e);}
public void check(MouseEvent e) {
if (e.isPopupTrigger()) { //if the event shows the menu
jList.setSelectedIndex(jList.locationToIndex(e.getPoint())); //select the item
jPopupMenu.show(jList, e.getX(), e.getY()); //and show the menu
}
}
这应该有用。
编辑:代码现在检查press
和release
个事件,因为某些平台在鼠标按下时显示弹出窗口,而其他一些平台在发布时显示弹出窗口。有关详细信息,请参阅the Swing tutorial。
答案 1 :(得分:9)
如果您想继续使用setComponentPopupMenu
(这很好,因为它以跨平台的方式处理弹出窗口的鼠标和键盘调用),您可以覆盖JPopupMenu.show(Component, int, int)
以选择适当的行。
JPopupMenu jPopupMenu = new JPopupMenu() {
@Override
public void show(Component invoker, int x, int y) {
int row = jList.locationToIndex(new Point(x, y));
if (row != -1) {
jList.setSelectedIndex(row);
}
super.show(invoker, x, y);
}
};
jList.setComponentPopupMenu(jPopupMenu);
请注意,当您通过键盘调用弹出窗口时(并且您还没有覆盖目标组件上的getPopupLocation
),您在JPopupMenu.show
中获得的x,y位置将是你的组件。如果在这种情况下已经有选择,您可能不想更改选择。
我想出的解决键盘与鼠标调用问题的解决方案是在覆盖getPopupLocation
的情况下在组件上设置客户端属性,然后在显示弹出窗口时检查它。通过键盘调用getPopupLocation
的参数为null
。这是核心代码(可能在组件及其弹出菜单中可用的实用程序类中实现)。
private static final String POPUP_TRIGGERED_BY_MOUSE_EVENT = "popupTriggeredByMouseEvent"; // NOI18N
public static Point getPopupLocation(JComponent invoker, MouseEvent event)
{
boolean popupTriggeredByMouseEvent = event != null;
invoker.putClientProperty(POPUP_TRIGGERED_BY_MOUSE_EVENT, Boolean.valueOf(popupTriggeredByMouseEvent));
if (popupTriggeredByMouseEvent)
{
return event.getPoint();
}
return invoker.getMousePosition();
}
public static boolean isPopupTriggeredByMouseEvent(JComponent invoker)
{
return Boolean.TRUE.equals(invoker.getClientProperty(POPUP_TRIGGERED_BY_MOUSE_EVENT));
}
然后覆盖组件中的getPopupLocation
:
@Override
public Point getPopupLocation(MouseEvent event)
{
return PopupMenuUtils.getPopupLocation(this, event);
}
并在覆盖isPopupTriggeredByMouseEvent
时调用JPopupMenu.show
以确定是否在弹出位置选择行(或对底层组件可能有意义的任何操作):
JPopupMenu jPopupMenu = new JPopupMenu() {
@Override
public void show(Component invoker, int x, int y) {
int row = jList.locationToIndex(new Point(x, y));
if (row != -1 && PopupMenuUtils.isPopupTriggeredByMouseEvent((JComponent) invoker)) {
jList.setSelectedIndex(row);
}
super.show(invoker, x, y);
}
};