如何获取JFileChooser工具栏中视图菜单按钮触发的JPopup?
ActionListener没法直接拿到弹出的JPopupMenu,因为它只响应菜单的点击动作,而非popup的创建/显示事件。可以试试下面几种可行方法:
方法1:通过MenuListener监听菜单选中事件,直接获取Popup
给你的「视图」菜单(JMenu实例)添加MenuListener,在菜单被选中(即将弹出popup)时,调用getPopupMenu()拿到对应的JPopupMenu,之后就能对它做UI自定义:
JMenu viewMenu = ...; // 你的视图菜单实例 viewMenu.addMenuListener(new MenuListener() { @Override public void menuSelected(MenuEvent e) { // 菜单选中时,popup已初始化完成 JPopupMenu popup = viewMenu.getPopupMenu(); // 自定义UI示例:替换UI类 popup.setUI(new MyCustomPopupMenuUI()); // 或修改菜单项样式 for (Component comp : popup.getComponents()) { if (comp instanceof JMenuItem) { JMenuItem item = (JMenuItem) comp; item.setBackground(Color.LIGHT_GRAY); // 其他自定义操作 } } } @Override public void menuDeselected(MenuEvent e) {} @Override public void menuCanceled(MenuEvent e) {} });
方法2:给PopupMenu添加PopupMenuListener监听显示事件
如果需要在popup即将显示时做自定义,可直接给菜单的popup添加PopupMenuListener:
JPopupMenu popup = viewMenu.getPopupMenu(); popup.addPopupMenuListener(new PopupMenuListener() { @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { // popup即将显示时执行自定义逻辑 JPopupMenu targetPopup = (JPopupMenu) e.getSource(); targetPopup.setBorder(BorderFactory.createLineBorder(Color.RED)); } @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {} @Override public void popupMenuCanceled(PopupMenuEvent e) {} });
注意:如果菜单的popup是延迟创建的(比如第一次点击才初始化),建议先通过MenuListener触发一次获取,再添加这个监听器。
方法3:递归遍历组件树查找JPopupMenu(针对第三方组件场景)
如果你的菜单是第三方UI库中的组件,没法直接通过JMenu拿到popup,可以写一个递归方法遍历组件树查找:
private JPopupMenu findPopupMenu(Container container) { for (Component comp : container.getComponents()) { if (comp instanceof JPopupMenu) { return (JPopupMenu) comp; } else if (comp instanceof Container) { JPopupMenu found = findPopupMenu((Container) comp); if (found != null) { return found; } } } return null; }
使用时可在菜单的点击事件或者窗口的ComponentListener中调用,比如:
// 在窗口初始化完成后查找 frame.addComponentListener(new ComponentAdapter() { @Override public void componentShown(ComponentEvent e) { JPopupMenu popup = findPopupMenu(frame); if (popup != null) { // 执行自定义UI操作 } } });
内容的提问来源于stack exchange,提问作者Vasiliy Sokolov
相关产品推荐
相关产品推荐

