JSpinnerがキーイベントを食い潰す
Java1.4だと困ってしまう問題。
private static void test(Window window) { Component[] components = {new JTextField(10), new JSpinner(), new JButton("SUBMIT")}; JOptionPane pane = new JOptionPane(components, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION); pane.createDialog(window, "").setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { JFrame frame = new JFrame(); test(frame); frame.dispose(); } }); }
このコードを実行すると、5つのコンポーネントが並んだダイアログが表示されます。それぞれコンポーネントにフォーカスを当てた状態でENTERキーかESCキーを押すと、ダイアログが閉じるはずです。但し、Java1.4で実行した場合、JSpinnerにフォーカスした状態で押しても反応しません。Java1.5以降では大丈夫です。
SUNのBugDatabaseでは、次のような報告があります。
この問題は1.4.1rcの時に報告され、修正されたのは5.0となっています。
回避策として、JSpinnerに直接KeyEvent処理を追加することが考えられますが、JSpinnerはKeyListenerを直接追加してもダメで、EditorのTextFieldに付けてあげる必要があるみたいです。
JSpinner spinner = new JSpinner(); Component[] components = {new JTextField(10), spinner, new JButton("SUBMIT")}; JOptionPane pane = new JOptionPane(components, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION); final JDialog dialog = pane.createDialog(window, ""); final DefaultEditor editor = (DefaultEditor)spinner.getEditor(); editor.getTextField().addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_ENTER: try { editor.commitEdit(); } catch (ParseException ex) { ex.printStackTrace(); } dialog.dispose(); break; case KeyEvent.VK_ESCAPE: dialog.dispose(); break; default: } } }); dialog.setVisible(true);