Java swing 弹出菜单和 jlist

发布于 2024-11-07 07:47:32 字数 594 浏览 0 评论 0原文

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

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

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

谢谢并抱歉我的英语。

here is my problem:
I have a jList and a popup menu. When I right click the jList, the popup menu shows. The problem is that the jList item which the mouse is pointing at won't select.
And I want it to do that. When I point my cursor at an item in the list and press the right button, I want two things to happen. Select the item on which I clicked and show the popup menu.

I tried this:

jLists.addMouseListener(new MouseAdapter() {

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

jList.setComponentPopupMenu(jPopupMenu);

But it only shows the popup menu.
If I delete this line:

jList.setComponentPopupMenu(jPopupMenu);

then the right-click select works (but the popup menu doesn't show).

So, what do you think is the best way to make these two functions (both) work ?

Thanks and sorry for my english.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

话少情深 2024-11-14 07:47:32

不要执行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事件,因为某些平台在按下鼠标时显示弹出窗口,而另一些则在释放时显示弹出窗口。有关详细信息,请参阅Swing 教程

Don't do setComponentPopupMenu. In the MouseAdapter do the following:

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

This should work.

EDIT: The code now checks both press and release events, because some platforms show popups when mouse presses and some other on release. See the Swing tutorial for more info.

烟花易冷人易散 2024-11-14 07:47:32

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

并在 JPopupMenu.show 的覆盖中调用 isPopupTriggeredByMouseEvent 来确定是否选择弹出窗口中的行位置(或任何对底层组件有意义的操作):

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

If you want to continue to use setComponentPopupMenu (which is nice because it handles mouse and keyboard invocations of the popup in a cross platform way), you could override JPopupMenu.show(Component, int, int) to select the appropriate row.

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

Note that when your popup is invoked via the keyboard (and you don't also override getPopupLocation on your target component), the x, y location you get in JPopupMenu.show will be the midpoint of your component. If there's already a selection in this case you probably don't want to change the selection.

The solution I came up with to solve the keyboard vs. mouse invocation problem was to set a client property on the component in an override of getPopupLocation and then check it when showing the popup. The argument to getPopupLocation will be null when invoked via the keyboard. Here's the core code (perhaps implemented in a utility class available to your component and its popup menu).

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

Then override getPopupLocation in your component:

@Override
public Point getPopupLocation(MouseEvent event)
{
    return PopupMenuUtils.getPopupLocation(this, event);
}

and call isPopupTriggeredByMouseEvent in an override of JPopupMenu.show to determine whether or not to select the row at the popup location (or whatever action may make sense for the underlying component):

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);
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文