猿问

有没有办法检测 JPopupMenu 中的当前选择

我想检测选择内容何时发生变化JPopupMenu。不是单击菜单项时,而是选择(武装)菜单项时。用更简单的话来说,我想检测到这一点:

https://i.stack.imgur.com/gSUvP.gif

应该起作用的事情是将 a 添加ChangeListener到其SelectionModel,但它似乎没有响应选择事件:


public class PopupSelection extends JFrame {

    private static final long serialVersionUID = 363879723515243543L;


    public PopupSelection() {

        super("something");

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        setLayout(new FlowLayout());


        JLabel label = new JLabel("right click me");


        JPopupMenu menu = new JPopupMenu();

        menu.getSelectionModel().addChangeListener(System.out::println);


        JMenuItem menuItem1 = new JMenuItem("Item1");

        JMenuItem menuItem2 = new JMenuItem("Item2");

        JMenuItem menuItem3 = new JMenuItem("Item3");

        menu.add(menuItem1);

        menu.add(menuItem2);

        menu.add(menuItem3);


        label.setComponentPopupMenu(menu);


        getContentPane().add(label);

        setSize(400, 400);

        setLocationRelativeTo(null);

    }


    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> new PopupSelection().setVisible(true));

    }

}

我尝试的第二件事是使用 a PropertyChangeListener,但它不起作用(不检测此特定事件):


menu.addPropertyChangeListener(System.out::println);

我知道有另一种选择,ChangeListener即JMenuItem每次迭代 的所有组件时都添加 a JPopupMenu,以便找到选择的组件,但这不是我想要遵循的解决方案,因为它会在我的代码中增加不必要的复杂性。


那么,有没有办法检测选择呢?

如果出现XY 问题,我的最终目标是当用户使用箭头按钮更改菜单选择时正确增加/减少此滚动条: 



暮色呼如
浏览 136回答 2
2回答

MM们

在项目的按钮模型上使用更改侦听器。这是解决方案:import java.awt.Component;import java.awt.FlowLayout;import java.util.stream.Stream;import javax.swing.AbstractButton;import javax.swing.ButtonModel;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenuItem;import javax.swing.JPopupMenu;import javax.swing.SwingUtilities;import javax.swing.event.ChangeEvent;import javax.swing.event.ChangeListener;/**&nbsp;* <code>PopupSelection</code>.&nbsp;*/public class PopupSelection extends JFrame {&nbsp; &nbsp; private static final long serialVersionUID = 363879723515243543L;&nbsp; &nbsp; public PopupSelection() {&nbsp; &nbsp; &nbsp; &nbsp; super("something");&nbsp; &nbsp; &nbsp; &nbsp; setDefaultCloseOperation(EXIT_ON_CLOSE);&nbsp; &nbsp; &nbsp; &nbsp; setLayout(new FlowLayout());&nbsp; &nbsp; &nbsp; &nbsp; JLabel label = new JLabel("right click me");&nbsp; &nbsp; &nbsp; &nbsp; JPopupMenu menu = new MyPopupMenu();&nbsp; &nbsp; &nbsp; &nbsp; menu.getSelectionModel().addChangeListener(System.out::println);&nbsp; &nbsp; &nbsp; &nbsp; JMenuItem menuItem1 = new JMenuItem("Item1");&nbsp; &nbsp; &nbsp; &nbsp; JMenuItem menuItem2 = new JMenuItem("Item2");&nbsp; &nbsp; &nbsp; &nbsp; JMenuItem menuItem3 = new JMenuItem("Item3");&nbsp; &nbsp; &nbsp; &nbsp; menu.add(menuItem1);&nbsp; &nbsp; &nbsp; &nbsp; menu.add(menuItem2);&nbsp; &nbsp; &nbsp; &nbsp; menu.add(menuItem3);&nbsp; &nbsp; &nbsp; &nbsp; label.setComponentPopupMenu(menu);&nbsp; &nbsp; &nbsp; &nbsp; getContentPane().add(label);&nbsp; &nbsp; &nbsp; &nbsp; setSize(400, 400);&nbsp; &nbsp; &nbsp; &nbsp; setLocationRelativeTo(null);&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; SwingUtilities.invokeLater(() -> new PopupSelection().setVisible(true));&nbsp; &nbsp; }&nbsp; &nbsp; private static class MyPopupMenu extends JPopupMenu {&nbsp; &nbsp; &nbsp; &nbsp; private final ChangeListener listener = this::changed;&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; protected void addImpl(Component comp, Object constraints, int index) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; super.addImpl(comp, constraints, index);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (comp instanceof AbstractButton) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((AbstractButton) comp).getModel().addChangeListener(listener);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; public void remove(int index) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Component comp = getComponent(index);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (comp instanceof AbstractButton) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((AbstractButton) comp).getModel().removeChangeListener(listener);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; super.remove(index);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; private void changed(ChangeEvent e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ButtonModel model = (ButtonModel) e.getSource();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AbstractButton selected = Stream.of(getComponents()).filter(AbstractButton.class::isInstance)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(AbstractButton.class::cast)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter(b -> b.getModel().isArmed() && b.getModel() == model).findAny().orElse(null);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setSelected(selected);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

温温酱

您可以将a添加到 MenuSelectionManager,而不是向ChangeListener每个添加 a 。JMenuItemChangeListenerMenuSelectionManager.defaultManager().addChangeListener(e -> {&nbsp; Object o = e.getSource();&nbsp; if (o instanceof MenuSelectionManager) {&nbsp; &nbsp; MenuSelectionManager m = (MenuSelectionManager) o;&nbsp; &nbsp; printMenuElementArray(m.getSelectedPath());&nbsp; }});PopupSelection2.javaimport java.awt.*;import javax.swing.*;public class PopupSelection2 extends JFrame {&nbsp; public PopupSelection2() {&nbsp; &nbsp; super("something");&nbsp; &nbsp; setDefaultCloseOperation(EXIT_ON_CLOSE);&nbsp; &nbsp; setLayout(new FlowLayout());&nbsp; &nbsp; JLabel label = new JLabel("right click me");&nbsp; &nbsp; JPopupMenu menu = new JPopupMenu();&nbsp; &nbsp; menu.getSelectionModel().addChangeListener(System.out::println);&nbsp; &nbsp; JMenuItem menuItem1 = new JMenuItem("Item1");&nbsp; &nbsp; JMenuItem menuItem2 = new JMenuItem("Item2");&nbsp; &nbsp; JMenuItem menuItem3 = new JMenuItem("Item3");&nbsp; &nbsp; menu.add(menuItem1);&nbsp; &nbsp; menu.add(menuItem2);&nbsp; &nbsp; menu.add(menuItem3);&nbsp; &nbsp; label.setComponentPopupMenu(menu);&nbsp; &nbsp; MenuSelectionManager.defaultManager().addChangeListener(e -> {&nbsp; &nbsp; &nbsp; Object o = e.getSource();&nbsp; &nbsp; &nbsp; if (o instanceof MenuSelectionManager) {&nbsp; &nbsp; &nbsp; &nbsp; MenuSelectionManager m = (MenuSelectionManager) o;&nbsp; &nbsp; &nbsp; &nbsp; printMenuElementArray(m.getSelectedPath());&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; });&nbsp; &nbsp; getContentPane().add(label);&nbsp; &nbsp; setSize(400, 400);&nbsp; &nbsp; setLocationRelativeTo(null);&nbsp; }&nbsp; // @see javax/swing/MenuSelectionManager.java&nbsp; private static void printMenuElementArray(MenuElement[] path) {&nbsp; &nbsp; System.out.println("Path is(");&nbsp; &nbsp; for (int i = 0, j = path.length; i < j ; i++) {&nbsp; &nbsp; &nbsp; for (int k = 0; k <= i; k++) {&nbsp; &nbsp; &nbsp; &nbsp; System.out.print("&nbsp; ");&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; MenuElement me = path[i];&nbsp; &nbsp; &nbsp; if (me instanceof JMenuItem) {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(((JMenuItem)me).getText() + ", ");&nbsp; &nbsp; &nbsp; } else if (me instanceof JMenuBar) {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("JMenuBar, ");&nbsp; &nbsp; &nbsp; } else if (me instanceof JPopupMenu) {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("JPopupMenu, ");&nbsp; &nbsp; &nbsp; } else if (me == null) {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("NULL , ");&nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("" + me + ", ");&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; System.out.println(")");&nbsp; }&nbsp; public static void main(String[] args) {&nbsp; &nbsp; SwingUtilities.invokeLater(() -> new PopupSelection2().setVisible(true));&nbsp; }}
随时随地看视频慕课网APP

相关分类

Java
我要回答