【问题标题】:Java swing popup menu and jlistJava swing弹出菜单和jlist
【发布时间】:2011-08-25 20:37:32
【问题描述】:

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

然后右键选择有效(但弹出菜单不显示)。

那么,您认为使这两个功能(两者)都起作用的最佳方法是什么?

感谢和抱歉我的英语。

【问题讨论】:

    标签: java swing menu popup jlist


    【解决方案1】:

    不要做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
        }
    }
    

    这应该可行。

    编辑:代码现在同时检查pressrelease 事件,因为某些平台在鼠标按下时会显示弹出窗口,而在释放时会显示其他一些。请参阅the Swing tutorial 了解更多信息。

    【讨论】:

    • 不是未经测试代码的忠实拥护者,但不得不为检查 isPopupTrigger() 投赞成票 - 好电话。
    • 老实说,我会选择if(e.getButton() == MouseEvent.BUTTON3) 而不是if(e.isPopupTrigger()),原因很简单,触发器方法总是为我返回false。否则,我会将其编码为 100% 相同的 @jmendeth +1。
    • @Boro:有趣的一点(& 对“测试代码”的另一个肯定;)。您正在运行什么操作系统/Java?
    • 我已更新代码以检查 pressrelease 事件。
    • 请注意,以这种方式避免setComponentPopupMenu意味着您将无法通过键盘调用弹出菜单。
    【解决方案2】:

    如果您想继续使用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);
        }
    };
    

    【讨论】:

    • 缺少的部分是jList=new JList<ContactItem>() { @Override public Point getPopupLocation(MouseEvent event) { return JListUtility.getPopupLocation(this, event); } };
    • 谢谢,@palindrom。我更新了我的答案以包括 getPopupLocation 用法
    猜你喜欢
    • 2011-01-09
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    相关资源
    最近更新 更多