Java swing弹出菜单和jlist

Java swing弹出菜单和jlist,java,swing,menu,popup,jlist,Java,Swing,Menu,Popup,Jlist,我的问题是: 我有一个jList和一个弹出菜单。右键单击jList时,将显示弹出菜单。问题是,鼠标指向的jList项目无法选择。 我希望它能做到这一点。当我将光标指向列表中的一个项目并按下右键时,我希望发生两件事。选择我单击的项目并显示弹出菜单 private static final String POPUP_TRIGGERED_BY_MOUSE_EVENT = "popupTriggeredByMouseEvent"; // NOI18N public static Point getPo

我的问题是: 我有一个jList和一个弹出菜单。右键单击jList时,将显示弹出菜单。问题是,鼠标指向的jList项目无法选择。 我希望它能做到这一点。当我将光标指向列表中的一个项目并按下右键时,我希望发生两件事。选择我单击的项目并显示弹出菜单

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));
}
我试过这个:

jLists.addMouseListener(new MouseAdapter() {

     @Override
     public void mousePressed(MouseEvent e) {
            jList.setSelectedIndex(jList.locationToIndex(e.getPoint()));
     }
});

jList.setComponentPopupMenu(jPopupMenu);
但它只显示弹出菜单。 如果我删除这一行:

jList.setComponentPopupMenu(jPopupMenu);
然后,右键单击“选择”可以工作(但弹出菜单不显示)

那么,你认为让这两个功能(两者)都发挥作用的最佳方式是什么


感谢并为我的英语感到抱歉。

不要做
设置组件弹出菜单
。在
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
    }
}
这应该行得通


编辑:代码现在会检查
按下
释放
事件,因为有些平台在鼠标按下时会显示弹出窗口,有些平台在释放时会显示弹出窗口。有关更多信息,请参阅。

如果要继续使用
setComponentPopupMenu
(这很好,因为它以跨平台的方式处理弹出窗口的鼠标和键盘调用),可以覆盖
jpopMenu.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
),您在
jpopumenus.show
中得到的x,y位置将是组件的中点。如果在这种情况下已经有选择,您可能不想更改选择

我提出的解决键盘与鼠标调用问题的解决方案是在组件上设置一个客户端属性,覆盖
getPopupLocation
,然后在显示弹出窗口时检查它。通过键盘调用时,
getPopupLocation
的参数将为
null
。下面是核心代码(可能在组件及其弹出菜单可用的实用程序类中实现)

然后覆盖组件中的
getPopupLocation

@Override
public Point getPopupLocation(MouseEvent event)
{
    return PopupMenuUtils.getPopupLocation(this, event);
}
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);
    }
};
并在
jpoppmenu.show
的覆盖中调用
isPopupTriggeredByMouseEvent
,以确定是否在弹出位置选择行(或对基础组件有意义的任何操作):


不太喜欢未经测试的代码,但被迫放弃投票,选择检查
isPopupTrigger()
-这是个好主意。@Vena:当你找到问题的答案时,请接受它。很简单,只需单击投票区域下方的勾号。谢谢老实说,我会选择
if(e.getButton()==MouseEvent.BUTTON3)
而不是
if(e.isPopupTrigger())
,原因很简单,触发器方法总是为我返回false。否则,我将100%地将其编码为相同的@jmendeth+1。@Boro:有趣的一点(&对“测试代码”的另一个肯定)。您正在运行什么OS/Java?请注意,以这种方式避免
setComponentPopupMenu
意味着您将无法通过键盘调用弹出菜单。缺少的部分是
jList=new jList(){@Override public Point getPopupLocation(MouseEvent event){return JListUtility.getPopupLocation(这个,事件);};
谢谢,@palindrom。我更新了我的答案,加入了
getPopupLocation
用法