当前位置: 首页 > 知识库问答 >
问题:

JComboBox,带有JPopupMenu作为右键单击选项

蒲昊苍
2023-03-14

所以我需要的功能是组合框,在扩展时可以右键单击,然后弹出菜单显示不同的操作。

为此,我使用以下构造函数扩展了JCombobox:

    public HistoryComboBox(DefaultComboBoxModel model) {
    super(model);
    super.setUI(new BasicComboBoxUI(this){

        @Override protected ComboPopup createPopup() {
            return new HistoryComboPopup(comboBox);
        }
    });

创建了HistoryComboPopup类,它扩展了BasicComboPopup,并有一个鼠标侦听器

@Override
protected MouseListener createListMouseListener() {
    if (handler2 == null)
        handler2 = new Handler2();
    return handler2;
}

private class Handler2 implements MouseListener {
    @Override
    public void mouseClicked(MouseEvent e) {
        JPopupMenu popup = new JPopupMenu();
        ...
        popup.show();
    }
}

弹出窗口工作,我可以处理它的菜单点击。唯一的麻烦是当我打开JPopupMenu时,组合框关闭,我点击右键的项目不再出现。

我目前不知道该怎么办,所以任何帮助都将不胜感激。

编辑:我拼凑了一个可编译的示例:

public class MainPanel extends JPanel{
public MainPanel() {
    super(new BorderLayout());

    JComboBox combo1 = makeComboBox(5);
    combo1.setUI(new BasicComboBoxUI() {
        @Override protected ComboPopup createPopup() {
            return new HistoryComboPopup(comboBox);
        }
    });

    add(combo1,BorderLayout.NORTH);
}

private static JComboBox makeComboBox(int size) {
    DefaultComboBoxModel model = new DefaultComboBoxModel();
    for(int i=0;i<size;i++) {
        model.addElement("No."+i);
    }
    return new JComboBox(model);
}

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override public void run() {
            JFrame frame = new JFrame("DisableRightClick");
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.getContentPane().add(new MainPanel());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}
}

class HistoryComboPopup extends BasicComboPopup {
private Handler2 handler2;

@Override
public void uninstallingUI() {
    super.uninstallingUI();
    handler2 = null;
}

public HistoryComboPopup(JComboBox combo) {
    super(combo);
}

@Override
protected MouseListener createListMouseListener() {
    if (handler2 == null)
        handler2 = new Handler2();
    return handler2;
}

private class Handler2 implements MouseListener {
    @Override public void mouseEntered(MouseEvent e) {}
    @Override public void mouseExited(MouseEvent e) {}
    @Override public void mouseClicked(MouseEvent e) {}
    @Override public void mousePressed(MouseEvent e) {}

    @Override
    public void mouseReleased(MouseEvent e) {
        if (SwingUtilities.isRightMouseButton(e)) {
            JPopupMenu popup = new JPopupMenu();

            JMenuItem copymethod = new JMenuItem("copy");
            copymethod.addMouseListener(new MouseAdapter() {

                @Override
                public void mousePressed(MouseEvent e) {
                    System.out.println("copy clicked");
                }
            });
            popup.add(copymethod);
            popup.show(HistoryComboPopup.this, 
                    e.getXOnScreen() - HistoryComboPopup.this.getLocationOnScreen().x, 
                    e.getYOnScreen() - HistoryComboPopup.this.getLocationOnScreen().y);

        } else {
            comboBox.setSelectedIndex(list.getSelectedIndex());
            comboBox.setPopupVisible(false);
        }
    }
}
}

共有1个答案

叶展
2023-03-14

所以我需要的功能是组合框,在扩展时可以右键单击,然后弹出菜单显示不同的操作。

>

  • popup.show();不是适当的加速器

    这不可能直接实现,很难覆盖常见的错误,

    Swing不允许同时显示两个lightwieght弹出组件

    使用JWindows或未修饰的JDialog而不是JPopup

    代码示例演示了一个正式的bug

        import javax.swing.*;
        import java.awt.event.*;
    
        public class Test {
    
            public static void main(String[] args) {
                JFrame frame = new JFrame();
                frame.setSize(400, 400);
                frame.setVisible(true);
                String[] list = {"1", "2", "3", "4",};
                JComboBox comb = new JComboBox(list);
                final JPopupMenu pop = new JPopupMenu();
                pop.add(comb);
                frame.addMouseListener(new MouseAdapter() {
    
                    @Override
                    public void mousePressed(MouseEvent e) {
                        System.out.println("mousePressed");
                        pop.show(e.getComponent(), e.getX(), e.getY());
                    }
                });
            }
       }
    

  •  类似资料:
    • 我知道如何通过鼠标左键点击所选项目来获取项目。我可以使用。 但我需要用鼠标右键点击项目。显示与单击的项目相关的弹出菜单。我试过这个: 但如果用户用右键点击该项,则会出现问题。右键单击不选择项目。如何按事件坐标选择项目或如何解决此问题?主要我需要得到的对象是点击没有选择项目,如果可能的话。

    • 我有一个JTree,我可以(ctrl)选择多个节点。当我右键点击时,我会弹出一个窗口,在那里我可以选择“刷新”。(本网站上还有其他问题解释如何做到这一点) 问题是,当我选择多个节点并右键单击时,只有右键单击的节点被选中,其他节点被取消选择。 例如,我想选择3个节点(叶),右键单击,选择刷新,仍然选择这3个节点。 有什么建议吗?谢谢。 例子:

    • 我设置了一个JPopupMenu,它将显示用户是否右键单击JList中的某个单元格,但现在必须先选择该单元格,才能显示JPopupMenu。我想知道如何在右键单击后选择该单元格,然后像现在一样显示JPopupMenu。当没有选择任何项目并且鼠标不在列表中的任何项目上时,我也会显示一个菜单。 代码:

    • 我正在为一个服务器做一个插件,我是开发者,我正在开发一个插件!我想通过执行boss give lvl命令来生成boss鸡蛋

    • 在IntelliJ中,当我右键单击测试时,我再也看不到“RunClassX或MethodY”。事实上,没有“运行”窗口,当我右键单击时,我无法运行任何类。 大约3个小时前,一切正常,所以我不太确定发生了什么变化? IntelliJ 10.5.1(许可和非社区版)Java1.6.0_24 有人能帮我吗?PS:这适用于所有项目。 更新1我安装了IDEA 11并从10导入了设置,然后发现这不是免费升级。