TITLE:Windowを開いたときのフォーカスを指定

Posted by at 2004-10-11

Windowを開いたときのフォーカスを指定

JFrameやJDialogなどのWindowを開いたときに、デフォルトでフォーカスを持つコンポーネントを指定します。

  • &jnlp;
  • &jar;
  • &zip;
DefaultFocus.png

サンプルコード

EventQueue.invokeLater(new Runnable() {
  @Override public void run() {
    field.requestFocusInWindow();
  }
});

解説

上記のサンプルでは、JTextFieldがデフォルトのフォーカスを持つように、JComponent#requestFocusInWindowメソッドを使用しています。

requestFocusInWindowメソッドは、チュートリアルHow to Use the Focus Subsystemにあるように、frame.pack();した後で実行する必要があります。このため、このサンプルではEventQueue.invokeLaterを使って、待ち状態のすべてのイベントが処理されたあとで実行するようにしています。


以下のように、FocusTraversalPolicyやWindowListenerを使う方法でも、同様にデフォルトのフォーカスを持つコンポーネントを指定することが出来ます。

  • FocusTraversalPolicyを使用
    • FocusTraversalPolicy を設定して、最初にフォーカスの当たるコンポーネントを指定(JDK 1.4 以降)
      frame.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
        @Override public Component getInitialComponent(Window w) {
          return field;
        }
      });
      
  • WindowListener#windowOpened で、requestFocusInWindow
    • フレームにWindowListenerを設定して、windowOpenedが呼び出されたときに、requestFocusInWindow
      frame.addWindowListener(new WindowAdapter() {
        @Override public void windowOpened(WindowEvent e) {
          field.requestFocusInWindow();
        }
      });
      
  • ComponentListener#componentShown で、requestFocusInWindow
    • フレームにComponentListenerを設定して、componentShownが呼び出されたとき(=フレームがsetVisible(true)されたとき)に、requestFocusInWindow
      frame.addComponentListener(new ComponentAdapter() {
        @Override public void componentShown(ComponentEvent e) {
          field.requestFocusInWindow();
        }
      });
      
  • KeyboardFocusManager#addPropertyChangeListener で、requestFocusInWindow
    • KeyboardFocusManagerにPropertyChangeListenerを設定して、propertyChangeが呼び出され、PropertyNameが、"activeWindow"、かつPropertyChangeEvent#getNewValueがnullでないときに、requestFocusInWindow
      KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
      kfm.addPropertyChangeListener(new PropertyChangeListener() {
        @Override public void propertyChange(PropertyChangeEvent e) {
          String prop = e.getPropertyName();
          if("activeWindow".equals(prop) && e.getNewValue()!=null) {
            System.out.println("activeWindow");
            field.requestFocusInWindow();
          }
        }
      });
      

参考リンク

コメント

  • JFrame#getRootPane()#setDefaultButton()は使用方法がよくわからない… -- aterai
  • setDefaultButtonって、Enterしたときに押されたとみなすボタンだったかな…… --
    • ありがとうございます。おかげでようやく理解できました。JTextFieldなどを編集状態にしたあと、EnterするとsetDefaultButtonしたボタンが押されるのですね。 -- aterai
    • というわけで、frame.getRootPane().setDefaultButton(eb);を追加してみました。上記のサンプルでは、中央のJTextFieldにフォーカスがある状態で、リターンキーを押すと、EASTボタンが押されたことになります。 -- aterai
    • いつか、DefaultButton のページを別に作成すること。 -- aterai
    • DefaultButtonの設定に移動。 -- aterai
  • HierarchyListenerを使用する場合のテスト -- aterai