You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用MouseInfo.getPointerInfo().getLocation()模拟开始菜单选中/取消选中

解决Windows 95模拟程序中开始菜单状态切换的问题

问题分析

你的代码未生效主要有三个核心问题:

  1. 坐标判断逻辑仅执行一次,不会持续监听鼠标移动,只有程序启动时会检查一次坐标,后续鼠标移动无法触发状态切换
  2. MouseInfo.getPointerInfo().getLocation()获取的是屏幕全局坐标,但你的开始菜单标签是嵌套在JDesktopPane中的组件,组件位置是相对父容器的,直接用屏幕坐标判断会存在偏差
  3. 直接移除再添加JLabel的操作冗余且易引发布局问题,实际上仅需切换JLabel的Icon即可实现状态变化

修正后的代码示例

// 初始化桌面容器
JDesktopPane desktop = new JDesktopPane();

// 只保留一个JLabel,通过切换Icon实现状态变化
JLabel startMenu = new JLabel(new ImageIcon(getClass().getClassLoader().getResource("StartMenuOpen.png")));
startMenu.setBounds(-155, 195, 600, 600);
desktop.add(startMenu);

// 给开始菜单添加鼠标移动监听,实时检测鼠标位置
startMenu.addMouseMotionListener(new MouseMotionAdapter() {
    @Override
    public void mouseMoved(MouseEvent e) {
        // 将鼠标屏幕坐标转换为相对于startMenu组件的内部坐标
        Point screenPoint = MouseInfo.getPointerInfo().getLocation();
        Point componentPoint = SwingUtilities.convertPointFromScreen(screenPoint, startMenu);
        
        // 根据组件内部坐标判断是否切换状态
        if (componentPoint.getX() > 4 && componentPoint.getX() < 287 
            && componentPoint.getY() > 630 && componentPoint.getY() < 680) {
            startMenu.setIcon(new ImageIcon(getClass().getClassLoader().getResource("StartMenuOpenShutDownSelected.png")));
        } else {
            // 鼠标离开目标区域时切回默认图标
            startMenu.setIcon(new ImageIcon(getClass().getClassLoader().getResource("StartMenuOpen.png")));
        }
    }
});

关键改进说明

  • 持续监听鼠标:通过MouseMotionListener的mouseMoved方法,实现鼠标在开始菜单上移动时的实时状态判断
  • 坐标转换:使用SwingUtilities.convertPointFromScreen将屏幕坐标转为组件内部相对坐标,确保判断逻辑的准确性
  • 简化组件操作:直接修改JLabel的Icon属性,避免移除/添加组件带来的布局混乱问题

原生Swing实现开始菜单的建议

若不想用图片模拟,原生Swing可以这样实现Win95风格开始菜单:

  • 用JPopupMenu作为菜单容器,内部添加JMenuItem对应各个菜单选项
  • 给开始按钮绑定点击事件,触发菜单弹出
  • 自定义JMenuItem的样式(颜色、字体等)模拟Win95视觉效果,示例代码:
// 创建开始菜单容器
JPopupMenu startMenu = new JPopupMenu();
startMenu.add(new JMenuItem("Programs"));
startMenu.add(new JMenuItem("Documents"));
JMenuItem shutDownItem = new JMenuItem("Shut Down...");
startMenu.add(shutDownItem);

// 开始按钮点击弹出菜单
JButton startBtn = new JButton("Start");
startBtn.addActionListener(e -> {
    // 在按钮下方位置弹出菜单
    startMenu.show(startBtn, 0, startBtn.getHeight());
});

// 自定义菜单选项样式(模拟Win95风格)
shutDownItem.setForeground(Color.BLUE);
shutDownItem.setBackground(Color.LIGHT_GRAY);
// 也可通过UIManager修改全局MenuItem的默认UI样式

内容的提问来源于stack exchange,提问作者Alanzhou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 20:19:01