なぜ私のChangeListenerはJMenuのためにのみ反応し、JMenuItemではないのですか?

StackOverflow https://stackoverflow.com/questions/5973875

質問

今、JMENU、そしてその中にいくつかのJMenuitemがあります。JMENUとJMENUITEMの状態が「選択」に変更されたときに、プログラムが何らかの行動を実行したいです。私はユーザーがキーボードを使ってメニューをナビゲートできるようにするので、Mouselitenerのマウスオーバーを使用しません。今、私はこのリスナーを書きました:

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に追加しても何も起こりません。JMenuitemと同様に。だから、私が見るように、JMenuItemは「渡す」ISSELECTED()テストを行うことはできません...しかし問題になることができるのでしょうか。:s

役に立ちましたか?

解決

違法なしの方向性を意図していない、これは歴史を持つ質問のうちの1つです

  • 初期要件:マウスがjmenuitem の上にあるときのDO - 何か
  • 皆さんの最愛の人:MouseListener
  • 初期偏差提案(@MKORBELへの賞):ボタンモーデルのChangeListener、Rolloverプロパティ を確認します。

  • 洗練された要件:jmenuitemが強調表示されたときのDosomething、キーボードとマウスの両方で。

  • 洗練された最愛の人:ボタンモーデルのChangeListener、プロパティが指定されていない
  • 洗練された偏差:ActionListener

  • 現在の要件:JMENUまたはJMENUITEM「選択」プロパティが変更されたときのDOSOMENT。

  • 現在の最愛の人:リスナーではできません、上書き...
  • 電流偏差:行動、メニューシーナー...

    正しい完全な(ただし、キーボードがまだ言及されていなかったので)答えはすでに最初のラウンドで利用可能でした。州の変更を捉える「低レベル」であるいくつかの意味リスナー(候補者はロールオーバーMenuItemsが強調表示されている状態になるようにするボタンモーデルレベルで、武装して選択された、選択された、選択しました。残念なことに、正確な関係はよく知られていません(少なくとも)、文書化されていません(読み取り:怠惰な私は簡単な外観に何かを見つけることができませんでした)、そしてコロローバーが誤って誤って(?) MenuItems の場合

    実験主義者の反応は.. tray:下記のメニューツリーでの状態変更を聴取して記録するコードスニペット(単に任意のメニューバーに投入してキーボードで移動してナビゲートする)です。

    と勝者は次のとおりです。 - 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;
    }
    
    .

他のヒント

これは予想される多型挙動です。 isSelected() JMenuItemから継承されます。 AbstractButton は上書きされていますメニューが現在選択されている場合はtrueを返すように、(強調表示されています)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top