2

我有一个正在用 Java 实现的新 UI,我在实现一个包含 JMenu(以及几个 JMenuItems)的 JPopupMenu 时遇到了麻烦,它本身包含几个 JMenuItems。JPopupMenu 出现在我单击人民币的位置,它看起来不错,但是当我将鼠标悬停时,“连接”JMenu 似乎没有任何孩子,尽管我尽了最大努力 .add() 它们。
在此处输入图像描述

在网上查看了几个示例后,我还没有看到任何专门为 mouseEntered() 实现侦听器以推出子项的示例。我想我在我的菜单初始化方法中搞砸了。

我已附上相关代码供您阅读。

//Elsewhere...
private JPopupMenu _clickMenu;
//End Elsehwere...

private void initializeMenu()
{
    _clickMenu = new JPopupMenu();
    _clickMenu.setVisible(false);

    _clickMenu.add(generateConnectionMenu());

    JMenuItem menuItem;
    menuItem = new JMenuItem("Configure");
    addMenuItemListeners(menuItem);
    _clickMenu.add(menuItem);

    menuItem = new JMenuItem("Status");
    addMenuItemListeners(menuItem);
    _clickMenu.add(menuItem);
}

private JMenu generateConnectionMenu()
{
    JMenu menu = new JMenu("Connect");

    List<Port> portList = _database.getAllPortsInCard(_cardId);

    for(int i = 0; i < portList.size(); i++)
    {
        menu.add(new JMenuItem(portList.get(i).getName()));
    }

    return menu;
}

该代码当然不是最漂亮的,但对我来说放轻松,因为在我试图弄清楚为什么它不起作用时,今天在时间允许的情况下它被修改了太多次。我认为这可能是范围问题,但我尝试了一些不同的代码配置无济于事。随意提出任何后续问题或打我一个明显的疏忽(以前发生过......)。谢谢大家!

编辑: 将此归结为缺乏 Java 和 Swing 经验……我是手动定位并使其JPopupMenu可见,而不是使用该JComponent.setComponentPopupMenu(menu)方法。对上图中的卡片模块(本身是一个 JButton)执行此操作后,子菜单会正确显示。下面包含了初始化代码的不同功能版本。

    private void initializeMenu()
{
    _cardMenu = new JPopupMenu();

    JMenu menu = new JMenu("Connect");

    JMenuItem menuItem;
    menuItem = new JMenuItem("1");
    menu.add(menuItem);

    menuItem = new JMenuItem("2");
    menu.add(menuItem);

    _cardMenu.add(menu);
    _cardMenu.add(new JMenuItem("Configure"));
    _cardMenu.add(new JMenuItem("Status"));

    _mainButton.setComponentPopupMenu(_cardMenu); //Important, apparently!
}

所以,吸取教训。谢谢你们的帮助!

4

2 回答 2

2

这是常见的 Bug或 Swing 属性,在某一时刻只能看到一个Lightweight弹出窗口,同样的问题是例如将JComboBox 中的弹出窗口添加到 JPopupMenu中,

  • Lightweight属性更改为Heavyweight

更好的是

  • 使用 un_decoratedJDialogJOptionPanewithJComponents

编辑@trashgod

  • 一切正常,除了我之外,所有 JMenus,JMenuItems 都是可见的,并且重复触发了正确的事件

代码

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class ContextMenu implements ActionListener, MenuListener, MenuKeyListener {

    private JTextArea textArea = new JTextArea();

    public ContextMenu() {
        final JPopupMenu contextMenu = new JPopupMenu("Edit");
        JMenu menu = new JMenu("Sub Menu");
        menu.add(makeMenuItem("Sub Menu Save"));
        menu.add(makeMenuItem("Sub Menu Save As"));
        menu.add(makeMenuItem("Sub Menu Close"));
        menu.addMenuListener(this);
        JMenu menu1 = new JMenu("Sub Menu");
        menu1.add(makeMenuItem("Deepest Sub Menu Save"));
        menu1.add(makeMenuItem("Deepest Sub Menu Save As"));
        menu1.add(makeMenuItem("Deepest Sub Menu Close"));
        menu.add(menu1);
        menu1.addMenuListener(this);
        contextMenu.add(menu);
        contextMenu.add(makeMenuItem("Plain Save"));
        contextMenu.add(makeMenuItem("Plain Save As"));
        contextMenu.add(makeMenuItem("Plain Close"));
        contextMenu.addMenuKeyListener(this);
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        frame.add(panel);
        panel.setComponentPopupMenu(contextMenu);
        textArea.setInheritsPopupMenu(true);
        panel.add(BorderLayout.CENTER, textArea);
        JTextField textField = new JTextField();
        textField.setInheritsPopupMenu(true);
        panel.add(BorderLayout.SOUTH, textField);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 200);
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        textArea.append(e.getActionCommand() + "\n");
    }

    private JMenuItem makeMenuItem(String label) {
        JMenuItem item = new JMenuItem(label);
        item.addActionListener(this);
        return item;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                ContextMenu contextMenu = new ContextMenu();
            }
        });
    }

    public void menuSelected(MenuEvent e) {
        textArea.append("menuSelected" + "\n");
    }

    public void menuDeselected(MenuEvent e) {
        textArea.append("menuDeselected" + "\n");
    }

    public void menuCanceled(MenuEvent e) {
        textArea.append("menuCanceled" + "\n");
    }

    public void menuKeyTyped(MenuKeyEvent e) {
        textArea.append("menuKeyTyped" + "\n");
    }

    public void menuKeyPressed(MenuKeyEvent e) {
        textArea.append("menuKeyPressed" + "\n");
    }

    public void menuKeyReleased(MenuKeyEvent e) {
        textArea.append("menuKeyReleased" + "\n");
    }
}
于 2012-04-02T21:35:32.050 回答
2

尽管@mKorbel 的观点可能适用,但我在显示的代码中没有看到明显的问题。作为参考,这ControlPanel增加了一个subMenu与几个项目。

于 2012-04-02T21:53:58.393 回答