いかなる方向への攻撃も意図していません。これは歴史のある質問の 1 つに過ぎません。
- 初期要件: マウスが JMenuItem の上にあるときに何かをする
- みなさんのイニシャル: MouseListener
最初の逸脱した提案 (@mKorbel に敬意を表します!): buttonModel の ChangeListener、rollover プロパティのチェック
洗練された要件: キーボードとマウスの両方で、JMenuItem が強調表示されたときに doSomething。
- 洗練された最愛の人: buttonModel の ChangeListener、プロパティが指定されていません
洗練された逸脱: ActionListener
現在の要件: JMenu または JMenuItem の "selected" プロパティが変更されたときの doSomething。
- 現在の最愛の人: リスナーでは実行できません。オーバーライド...
- 現在の偏差: Action、MenuListener ...
正確で完全な (ただし、後から考えると、キーボードについてはまだ言及されていないため) 回答は、最初のラウンドで既に利用可能でした: 状態の変化をキャプチャするのに十分な「低レベル」のセマンティック リスナー (候補は、ロールオーバー、武装、選択され、buttonModel レベルで押された場合)、menuItems の強調表示された状態を変更します。残念ながら、正確な関係は (少なくとも私には) よく知られておらず、文書化されておらず (読んでください: 怠惰な私はざっと見ても何も見つかりませんでした)、ロールオーバーは常に false であるため (これもまた私にとって) 混乱を招くことさえあります (?)。メニューアイテム用
実験者の反応は .. 試してみることです: 以下は、いくつかのメニュー ツリーの状態の変化をリッスンしてログに記録するコード スニペットです (単純に任意のメニュー バーにスローし、マウスを動かしてキーボードでナビゲートします)。
勝者は次のとおりです。 - 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;
}