なぜ私のChangeListenerはJMenuのためにのみ反応し、JMenuItemではないのですか?
-
12-11-2019 - |
質問
今、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を返すように、(強調表示されています)。