当前位置: 首页 > 面试题库 >

为什么我的ChangeListener仅对JMenu反应,而不对JMenuItem反应?

楚志强
2023-03-14
问题内容

现在,我有一个JMenu和其中的一些JMenuItems。我希望程序在JMenu和JMenuItem的状态更改为“已选择”时执行一些操作。我不使用MouseLitener的MouseOver,因为我希望用户也能够使用键盘在菜单中导航。现在,我写了这个监听器:

class MenuItemListener implements ChangeListener {
    @Override
    public void stateChanged(ChangeEvent arg0) {
        JMenuItem item = (JMenuItem) arg0.getSource();
        if(item.isSelected())
            System.out.println(item.getText()+" pressed!");
    }
}

当我将此侦听器添加到JMenu时,它可以正常工作,但是当我将其添加到JMenuItem时,什么也没有发生…当我删除if语句以使侦听器同时做出反应时,在选择并重新选择菜单时,我对JMenu以及用于JMenuItem。因此,正如我所看到的,JMenuItem无法“通过”
isSelected()测试……但是可能会有什么问题呢?:S


问题答案:

没有任何方向的冒犯,这只是有历史的问题之一

  • 初始要求:鼠标悬停在JMenuItem上时执行的操作
  • 最初的每个人的宠儿:MouseListener
  • 最初的偏离建议(对@mKorbel表示敬意):buttonModel上的ChangeListener,检查过渡属性

  • 改进的要求:当JMenuItem刚刚突出显示时,可以通过键盘和鼠标悬停在doSomething上。

  • 精致的宝贝:buttonModel上的ChangeListener,未指定属性

  • 精确偏差:ActionListener

  • 当前要求:更改JMenu或JMenuItem“选定”属性时的doSomething。

  • 当前的宠儿:无法用监听器完成,请覆盖…

  • 当前偏差:动作,MenuListener …

正确而完整的答案(事后看来,因为尚未提及键盘)在第一轮中就已经存在:某种语义监听器“足够低级”以捕获状态变化(候选者是过渡,武装,选中,在buttonModel级别上按下),使menuItem更改其
突出显示
状态。不幸的是,确切的关系尚不为人所知(至少对我而言),没有文档记录(请阅读:懒惰的我很快就找不到任何内容),甚至由于再次总是错误的(对我来说)而令人困惑(?)用于menuItems

实验人员的反应是尝试..
try:下面是一个代码段,该代码段侦听并记录某些菜单树上的状态更改(只需将其放入任意menuBar中并在鼠标周围移动并通过键盘进行导航)。

获胜者是:-使用ChangeListener并检查源是否已选择或已配置。

    ChangeListener ch = new ChangeListener() {

        @Override
        public void stateChanged(ChangeEvent e) {
            if (e.getSource() instanceof JMenuItem) {
                JMenuItem item = (JMenuItem) e.getSource();
                if (item.isSelected() || item.isArmed()) {
                    System.out.println("Highlighted: " + item.getActionCommand());
                }
            }
        }
    };

同时适用于键盘和鼠标,JMenu和JMenuItem

//----------- code snippet to track property changes in menuItem/buttonModel

    // test menu
    JMenu menu = new JMenu("Sample menu");
    menu.setMnemonic('s');
    installListeners(menu);

    // first menuitem
    JMenuItem other = menu.add("content1");
    installListeners(other);
    // second menuitem
    other = menu.add("again + ");
    installListeners(other);

    // sub
    JMenu sub = new JMenu("subMenu");
    installListeners(sub);
    menu.add(sub);

    // menus in sub
    other = sub.add("first in sub");
    installListeners(other);
    other = sub.add("second in sub");
    installListeners(other);

    getJMenuBar().add(menu);

private void installListeners(JMenuItem menu) {
    menu.getModel().addChangeListener(getChangeListener());
    menu.addChangeListener(getChangeListener());
}

private ChangeListener getChangeListener() {
    ChangeListener ch = new ChangeListener() {

        @Override
        public void stateChanged(ChangeEvent e) {
            if (e.getSource() instanceof ButtonModel) {
                ButtonModel model = (ButtonModel) e.getSource();
                System.out.println("from model: " + createStateText(model));
            } else if (e.getSource() instanceof JMenuItem) {
                JMenuItem item = (JMenuItem) e.getSource();
                System.out.println("  from item: " + createStateText(item));
            }
        }

        private String createStateText(ButtonModel model) {
            String text = model.getActionCommand() + " armed: " + model.isArmed();
            text += " selected: " + model.isSelected();
            text += " rollover " + model.isRollover();
            text += " pressed: " + model.isPressed();
            return text;
        }

        private String createStateText(JMenuItem model) {
            String text = model.getActionCommand() + " armed: " + model.isArmed();
            text += " selected: " + model.isSelected();
            // not supported on JMenuItem nor on AbstractButton
           // text += " rollover " + model.isRollover();
           // text += " pressed: " + model.isPressed();
            return text;
        }
    };
    return ch;
}


 类似资料:
  • 主要内容:1 Java JMenuBar JMenu JMenuItem的介绍,2 Java JMenuBar JMenu JMenuItem的声明,3 Java JMenuBar JMenu JMenuItem的案例1,4 Java JMenuBar JMenu JMenuItem的案例21 Java JMenuBar JMenu JMenuItem的介绍 JMenuBar类用于在窗口或框架上显示菜单栏。它可能有几个菜单。 JMenu类的对象是从菜单栏显示的下拉菜单组件。它继承了JMenuIt

  • 我有一个在端口3001上运行的节点后端服务器,以及一个我尝试代理到该端口以获取数据的反应服务器。 现在,我已经在客户端文件夹的package.json文件中包含了“代理”行,告诉React将请求代理到端口3001。 然而,当我试图向服务器上的“test”路由发出一个简单的请求时,React代码不会代理这个请求。它将我发送到localhost:3000/test,而不是localhost:3001/

  • 我有以下代码: 但我得到了以下错误: 未捕获的不变违规:对象作为React子对象无效(找到:带有键{正文、附件、视频、主题、updated_at、id、主题、反对票、作者、posted_at、注释、user_vote、好评、状态、标签、位置、track_impact、user_is_following、comments_count}的对象)。如果要呈现子集,请使用数组来代替,或者使用React加载

  • 我正在为Minecraft服务器的discord制作一个机器人。我在下面有一个on_会员加入事件和on_消息事件。on_member_join工作得很好,但是当我在discord服务器中发送消息时,on_message事件内部不会发生任何事情。这是我的代码,如果有人有可能的解决方案,我会非常感激。

  • 最近我在Droidcon Paris举办了一场技术讲座,我讲述了Square公司在使用Android fragments时遇到的问题,以及其他人如何避免使用fragments。 在2011年,基于以下原因我们决定在项目中使用fragments: 在那个时候,我们还没有支持平板设备-但是我们知道最终将会支持的,Fragments有助于构建响应式UI; Fragments是view controlle

  • MobX 通常会对你期望的东西做出反应。 这意味着在90%的场景下,mobx “都可以工作”。 然而,在某些时候,你会遇到一个情况,它可能不会像你所期望的那样工作。 在这个时候理解 MobX 如何确定对什么有反应就显得尤为重要。 MobX 会对在追踪函数执行过程中读取现存的可观察属性做出反应。 “读取” 是对象属性的间接引用,可以用过 . (例如 user.name) 或者 [] (例如 user