Java Swing 弹出菜单和 jlist

2022-09-02 03:19:55

这是我的问题:我有一个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);

然后右键单击选择工作(但弹出菜单不显示)。

那么,您认为使这两个函数(两者)工作的最佳方法是什么?

谢谢,对不起我的英语。


答案 1

不要做.在执行以下操作中:setComponentPopupMenuMouseAdapter

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
    }
}

这应该有效。

编辑:该代码现在同时检查和事件,因为某些平台在按下鼠标时显示弹出窗口,而其他一些平台在发布时显示弹出窗口。有关详细信息,请参阅 Swing 教程pressrelease


答案 2

如果要继续使用(这很好,因为它以跨平台的方式处理弹出窗口的鼠标和键盘调用),则可以覆盖以选择适当的行。setComponentPopupMenuJPopupMenu.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);

请注意,当通过键盘调用弹出窗口时(并且您不会在目标组件上覆盖),您进入的x,y位置将是组件的中点。如果在这种情况下已有选择,您可能不想更改选择。getPopupLocationJPopupMenu.show

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

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);
}

并调用 覆盖 ,以确定是否选择弹出位置处的行(或对基础组件可能有意义的任何操作):isPopupTriggeredByMouseEventJPopupMenu.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);
    }
};

推荐