JPopupMenu弹出菜单使用

wen java案例 2

本文目录导读:

JPopupMenu弹出菜单使用

  1. 基本概念
  2. 基础使用示例
  3. 高级特性
  4. 完整示例:文本编辑器右键菜单
  5. 常用技巧
  6. 注意事项

我来详细介绍Java Swing中JPopupMenu弹出菜单的使用方法。

基本概念

JPopupMenu是Swing中用于创建右键菜单或弹出菜单的组件,通常与鼠标事件结合使用。

基础使用示例

创建简单的弹出菜单

import javax.swing.*;
import java.awt.event.*;
public class PopupMenuExample extends JFrame {
    private JPopupMenu popupMenu;
    public PopupMenuExample() {
        setTitle("弹出菜单示例");
        setSize(400, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 创建弹出菜单
        popupMenu = new JPopupMenu();
        // 添加菜单项
        JMenuItem copyItem = new JMenuItem("复制");
        JMenuItem pasteItem = new JMenuItem("粘贴");
        JMenuItem deleteItem = new JMenuItem("删除");
        popupMenu.add(copyItem);
        popupMenu.add(pasteItem);
        popupMenu.add(deleteItem);
        // 添加分隔线
        popupMenu.addSeparator();
        JMenuItem selectAllItem = new JMenuItem("全选");
        popupMenu.add(selectAllItem);
        // 创建面板并添加鼠标监听
        JPanel panel = new JPanel();
        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    popupMenu.show(panel, e.getX(), e.getY());
                }
            }
        });
        add(panel);
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new PopupMenuExample().setVisible(true);
        });
    }
}

添加事件处理

public class PopupMenuWithEvents extends JFrame {
    private JTextArea textArea;
    public PopupMenuWithEvents() {
        // ... 初始化设置
        textArea = new JTextArea();
        JPopupMenu popupMenu = new JPopupMenu();
        // 添加带图标的菜单项
        JMenuItem cutItem = new JMenuItem("剪切");
        JMenuItem copyItem = new JMenuItem("复制");
        JMenuItem pasteItem = new JMenuItem("粘贴");
        // 添加事件监听
        cutItem.addActionListener(e -> textArea.cut());
        copyItem.addActionListener(e -> textArea.copy());
        pasteItem.addActionListener(e -> textArea.paste());
        popupMenu.add(cutItem);
        popupMenu.add(copyItem);
        popupMenu.add(pasteItem);
        // 右键菜单监听
        textArea.setComponentPopupMenu(popupMenu);
        add(new JScrollPane(textArea));
    }
}

高级特性

子菜单

JPopupMenu popupMenu = new JPopupMenu();
// 创建子菜单
JMenu editMenu = new JMenu("编辑");
editMenu.add(new JMenuItem("撤销"));
editMenu.add(new JMenuItem("重做"));
// 创建带子菜单的菜单项
JMenu formatMenu = new JMenu("格式");
JMenu fontMenu = new JMenu("字体");
fontMenu.add(new JMenuItem("粗体"));
fontMenu.add(new JMenuItem("斜体"));
fontMenu.add(new JMenuItem("下划线"));
formatMenu.add(fontMenu);
formatMenu.add(new JMenuItem("颜色"));
popupMenu.add(editMenu);
popupMenu.add(formatMenu);

复选框和单选按钮

JPopupMenu popupMenu = new JPopupMenu();
// 复选框菜单项
JCheckBoxMenuItem boldItem = new JCheckBoxMenuItem("粗体");
JCheckBoxMenuItem italicItem = new JCheckBoxMenuItem("斜体");
JCheckBoxMenuItem underlineItem = new JCheckBoxMenuItem("下划线");
popupMenu.add(boldItem);
popupMenu.add(italicItem);
popupMenu.add(underlineItem);
popupMenu.addSeparator();
// 单选按钮菜单项
ButtonGroup alignGroup = new ButtonGroup();
JRadioButtonMenuItem leftAlign = new JRadioButtonMenuItem("左对齐");
JRadioButtonMenuItem centerAlign = new JRadioButtonMenuItem("居中");
JRadioButtonMenuItem rightAlign = new JRadioButtonMenuItem("右对齐");
alignGroup.add(leftAlign);
alignGroup.add(centerAlign);
alignGroup.add(rightAlign);
popupMenu.add(leftAlign);
popupMenu.add(centerAlign);
popupMenu.add(rightAlign);

动态创建菜单

public void createDynamicPopupMenu() {
    JPopupMenu popupMenu = new JPopupMenu();
    // 根据条件动态添加菜单项
    List<String> items = getMenuItemList();
    for (String item : items) {
        JMenuItem menuItem = new JMenuItem(item);
        // 为每个菜单项创建事件监听
        menuItem.addActionListener(e -> {
            String action = ((JMenuItem) e.getSource()).getText();
            handleAction(action);
        });
        popupMenu.add(menuItem);
    }
}
private List<String> getMenuItemList() {
    // 模拟从数据源获取菜单项
    return Arrays.asList("选项1", "选项2", "选项3");
}
private void handleAction(String action) {
    System.out.println("执行操作: " + action);
}

完整示例:文本编辑器右键菜单

import javax.swing.*;
import javax.swing.undo.*;
import java.awt.*;
import java.awt.event.*;
public class TextEditorPopup extends JFrame {
    private JTextArea textArea;
    private UndoManager undoManager;
    public TextEditorPopup() {
        setTitle("文本编辑器 - 右键菜单");
        setSize(500, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 初始化文本区域
        textArea = new JTextArea();
        undoManager = new UndoManager();
        textArea.getDocument().addUndoableEditListener(undoManager);
        // 创建弹出菜单
        JPopupMenu popupMenu = new JPopupMenu();
        // 基本编辑操作
        JMenuItem undoItem = new JMenuItem("撤销");
        JMenuItem redoItem = new JMenuItem("重做");
        popupMenu.add(undoItem);
        popupMenu.add(redoItem);
        popupMenu.addSeparator();
        JMenuItem cutItem = new JMenuItem("剪切");
        JMenuItem copyItem = new JMenuItem("复制");
        JMenuItem pasteItem = new JMenuItem("粘贴");
        popupMenu.add(cutItem);
        popupMenu.add(copyItem);
        popupMenu.add(pasteItem);
        popupMenu.addSeparator();
        JMenuItem selectAllItem = new JMenuItem("全选");
        JMenuItem clearItem = new JMenuItem("清空");
        popupMenu.add(selectAllItem);
        popupMenu.add(clearItem);
        // 添加事件监听
        undoItem.addActionListener(e -> {
            if (undoManager.canUndo()) {
                undoManager.undo();
            }
        });
        redoItem.addActionListener(e -> {
            if (undoManager.canRedo()) {
                undoManager.redo();
            }
        });
        cutItem.addActionListener(e -> textArea.cut());
        copyItem.addActionListener(e -> textArea.copy());
        pasteItem.addActionListener(e -> textArea.paste());
        selectAllItem.addActionListener(e -> textArea.selectAll());
        clearItem.addActionListener(e -> textArea.setText(""));
        // 设置弹出菜单到组件
        textArea.setComponentPopupMenu(popupMenu);
        // 添加键盘快捷键
        InputMap inputMap = textArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap actionMap = textArea.getActionMap();
        KeyStroke ctrlC = KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK);
        KeyStroke ctrlV = KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK);
        KeyStroke ctrlX = KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_DOWN_MASK);
        inputMap.put(ctrlC, "copy");
        inputMap.put(ctrlV, "paste");
        inputMap.put(ctrlX, "cut");
        // 添加滚动面板
        add(new JScrollPane(textArea), BorderLayout.CENTER);
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new TextEditorPopup().setVisible(true);
        });
    }
}

常用技巧

弹出位置控制

// 在组件指定位置弹出
popupMenu.show(component, x, y);
// 在屏幕中心弹出
Point centerPoint = GraphicsEnvironment
    .getLocalGraphicsEnvironment()
    .getCenterPoint();
popupMenu.show(null, centerPoint.x, centerPoint.y);
// 在鼠标位置弹出
popupMenu.show(component, e.getX(), e.getY());

菜单状态控制

// 启用/禁用菜单项
cutItem.setEnabled(textArea.getSelectedText() != null);
pasteItem.setEnabled(Toolkit.getDefaultToolkit()
    .getSystemClipboard().getContents(null) != null);
// 显示/隐藏菜单项
menuItem.setVisible(true/false);

自定义外观

// 设置字体
Font menuFont = new Font("微软雅黑", Font.PLAIN, 14);
popupMenu.setFont(menuFont);
// 设置图标
ImageIcon icon = new ImageIcon("icon.png");
JMenuItem menuItem = new JMenuItem("菜单项", icon);

注意事项

  1. 跨平台兼容性:在macOS上,trigger事件是mousePressed,在Windows上是mouseReleased

  2. 最佳实践

    • 使用isPopupTrigger()方法判断触发事件
    • mousePressedmouseReleased中都检查触发条件
    • 使用setComponentPopupMenu()方法直接绑定
  3. 性能优化频繁变化的菜单,考虑使用懒加载

这就是JPopupMenu的完整使用指南,通过灵活运用这些特性,你可以创建功能丰富、交互友好的弹出菜单。

抱歉,评论功能暂时关闭!