为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

暮色呼如 2023-11-01 22:02:54
我想检测选择内容何时发生变化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 问题,我的最终目标是当用户使用箭头按钮更改菜单选择时正确增加/减少此滚动条:↑ ↓
查看完整描述

2 回答

?
MM们

TA贡献1886条经验 获得超2个赞

在项目的按钮模型上使用更改侦听器。这是解决方案:


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;


/**

 * <code>PopupSelection</code>.

 */

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 MyPopupMenu();

        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));

    }


    private static class MyPopupMenu extends JPopupMenu {


        private final ChangeListener listener = this::changed;


        @Override

        protected void addImpl(Component comp, Object constraints, int index) {

            super.addImpl(comp, constraints, index);

            if (comp instanceof AbstractButton) {

                ((AbstractButton) comp).getModel().addChangeListener(listener);

            }

        }


        @Override

        public void remove(int index) {

            Component comp = getComponent(index);

            if (comp instanceof AbstractButton) {

                ((AbstractButton) comp).getModel().removeChangeListener(listener);

            }

            super.remove(index);

        }


        private void changed(ChangeEvent e) {

            ButtonModel model = (ButtonModel) e.getSource();

            AbstractButton selected = Stream.of(getComponents()).filter(AbstractButton.class::isInstance)

                    .map(AbstractButton.class::cast)

                    .filter(b -> b.getModel().isArmed() && b.getModel() == model).findAny().orElse(null);

            setSelected(selected);

        }

    }

}


查看完整回答
反对 回复 2023-11-01
?
温温酱

TA贡献1752条经验 获得超4个赞

您可以将a添加到 MenuSelectionManager,而不是向ChangeListener每个添加 a 。JMenuItemChangeListener


MenuSelectionManager.defaultManager().addChangeListener(e -> {

  Object o = e.getSource();

  if (o instanceof MenuSelectionManager) {

    MenuSelectionManager m = (MenuSelectionManager) o;

    printMenuElementArray(m.getSelectedPath());

  }

});

PopupSelection2.java


import java.awt.*;

import javax.swing.*;


public class PopupSelection2 extends JFrame {

  public PopupSelection2() {

    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);


    MenuSelectionManager.defaultManager().addChangeListener(e -> {

      Object o = e.getSource();

      if (o instanceof MenuSelectionManager) {

        MenuSelectionManager m = (MenuSelectionManager) o;

        printMenuElementArray(m.getSelectedPath());

      }

    });


    getContentPane().add(label);

    setSize(400, 400);

    setLocationRelativeTo(null);

  }


  // @see javax/swing/MenuSelectionManager.java

  private static void printMenuElementArray(MenuElement[] path) {

    System.out.println("Path is(");

    for (int i = 0, j = path.length; i < j ; i++) {

      for (int k = 0; k <= i; k++) {

        System.out.print("  ");

      }

      MenuElement me = path[i];

      if (me instanceof JMenuItem) {

        System.out.println(((JMenuItem)me).getText() + ", ");

      } else if (me instanceof JMenuBar) {

        System.out.println("JMenuBar, ");

      } else if (me instanceof JPopupMenu) {

        System.out.println("JPopupMenu, ");

      } else if (me == null) {

        System.out.println("NULL , ");

      } else {

        System.out.println("" + me + ", ");

      }

    }

    System.out.println(")");

  }


  public static void main(String[] args) {

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

  }

}


查看完整回答
反对 回复 2023-11-01
  • 2 回答
  • 0 关注
  • 125 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信