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

Posted by at 2004-10-11

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

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

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

サンプルコード

EventQueue.invokeLater(new Runnable() {
  @Override public void run() {
    field.requestFocusInWindow();
  }
});
View in GitHub: Java, Kotlin

解説

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

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


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

  • `FocusTraversalPolicy`を使用
    • `FocusTraversalPolicyを設定して、最初にフォーカスの当たるコンポーネントを指定(JDK 1.4.0`以降)
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`
    • `KeyboardFocusManagerPropertyChangeListenerを設定して、propertyChangeが呼び出され、PropertyNameが、activeWindow、かつPropertyChangeEvent#getNewValuenullでないときに、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