新しいコンポーネントを削除して追加するという奇妙な動作を示す単純な Swing アプリケーションがあります。つまり、JButton によって JMenuItem アクセラレータ "F3" が応答しなくなりました。私が経験したことは、
初めて F3 を押して動作しました (JButton ラベル番号が 1 ずつ増えます)。F3 を繰り返し押しても機能しませんでした。ボタンをクリックしてもう一度 F3 を押すと、再び機能しました。
次のシナリオでは、ボタンをクリックする代わりに、メニュー項目「更新」をクリックし、F3 を繰り返し押して、ずっと機能しました。
JButton を削除せずにラベルを変更しただけの場合は、完全に機能します。私のコードはどこで間違っていましたか? 現時点では、JDK 1.7 を搭載した OSX (Mountain Lion) でのみこのアプリケーションをテストしました。他の OS ではまだ試していません。ありがとう
追加: これは単なる例です。実際には、ContentPane 内に可変数の JLabel と JButton があります。この数は、状況に応じて時々変化します。
public class ClickMeFrame {
private JButton clickMe = new JButton("1");
public ClickMeFrame() {
JFrame app = new JFrame("Numbers Frame");
app.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
final Container appContent = app.getContentPane();
clickMe.setSize(new Dimension(20, 20));
appContent.add(clickMe);
JMenuBar menuBar = new JMenuBar();
JMenu file = new JMenu("File");
menuBar.add(file);
AbstractAction refreshAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Refresh");
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
int nextIndex = Integer.parseInt(clickMe.getText()) + 1;
// remove from here
appContent.remove(clickMe);
clickMe = new JButton(nextIndex + "");
appContent.add(clickMe);
// to here to experiment with button text change instead of replacing with a new JButton
// enable me to experiment with button text change instead
//clickMe.setText(nextIndex + "");
appContent.revalidate();
appContent.repaint();
}
});
}
};
JMenuItem refresh = new JMenuItem("Refresh");
refresh.setAccelerator(KeyStroke.getKeyStroke("F3"));
refresh.addActionListener(refreshAction);
file.add(refresh);
app.setJMenuBar(menuBar);
app.pack();
app.setVisible(true);
}
public static void main(String[] args) {
new ClickMeFrame();
}
}