TITLE:Windowを開いたときのフォーカスを指定
#navi(../)
*Windowを開いたときのフォーカスを指定 [#q0754f35]
Posted by [[terai]] at 2004-10-11

#contents

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

-&jnlp;
-&jar;
-&zip;

#screenshot

**サンプルコード [#c961d3aa]
#code{{
EventQueue.invokeLater(new Runnable() {
  public void run() {
    field.requestFocusInWindow();
  }
});
}}

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

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

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

-FocusTraversalPolicyを使用
--FocusTraversalPolicy を設定して、最初にフォーカスの当たるコンポーネントを指定(JDK 1.4 以降)
#code{{
frame.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
  @Override
  public Component getInitialComponent(Window w) {
    return field;
  }
});
}}
-WindowListener#windowOpened で、requestFocusInWindow
--フレームにWindowListenerを設定して、windowOpenedが呼び出されたときに、requestFocusInWindow
#code{{
frame.addWindowListener(new WindowAdapter() {
  @Override
  public void windowOpened(WindowEvent e) {
    field.requestFocusInWindow();
  }
});
}}
-ComponentListener#componentShown で、requestFocusInWindow
--フレームにComponentListenerを設定して、componentShownが呼び出されたときに、requestFocusInWindow
#code{{
frame.addComponentListener(new ComponentAdapter() {
  @Override
  public void componentShown(ComponentEvent e) {
    field.requestFocusInWindow();
  }
});
}}

//----
//このサンプルでは、ウィンドウを開いたときにフォーカスを持つコンポーネントとは別に、フォーカスがボタンにない場合((ルート区画内に JTextPane やフォーカスのあるJButtonなどの起動イベントを消費する別のコンポーネントがある場合は除く))でも、Enterキーを押したときに起動されるボタンを以下のメソッドを使って設定しています([[JRootPane#setDefaultButton(javax.swing.JButton)>http://java.sun.com/javase/ja/6/docs/ja/api/javax/swing/JRootPane.html#setDefaultButton(javax.swing.JButton)]])。
//#code{{
//frame.getRootPane().setDefaultButton(eb);
//}}

**参考リンク [#z4f652d0]
-[[Focusの移動>Swing/FocusTraversal]]
-[[Swing - When does requestFocusInWindow() fail>http://forums.sun.com/thread.jspa?threadID=579294]]

**コメント [#x1950fff]
-JFrame#getRootPane()#setDefaultButton()は使用方法がよくわからない… -- [[terai]] 
-setDefaultButtonって、Enterしたときに押されたとみなすボタンだったかな…… --  &new{2004-10-14 (木) 23:21:53};
-なるほど、さっきやっと理解できました。JTextFieldなどを編集状態にしたあと、EnterするとsetDefaultButtonしたボタンが押されるのですね。 -- [[terai]] &new{2004-10-18 (月) 12:14:15};
-というわけで、frame.getRootPane().setDefaultButton(eb);を追加してみました。上記のサンプルでは、中央のJTextFieldにフォーカスがある状態で、リターンキーを押すと、EASTボタンが押されたことになります。 -- [[terai]] &new{2004-10-18 (月) 12:20:58};
-- %%いつか、DefaultButton のページを別に作成すること。 -- [[terai]] &new{2008-05-07 (水) 19:19:44};%%
-- [[DefaultButtonの設定>Swing/DefaultButton]]に移動。 -- [[terai]] &new{2008-05-12 (月) 14:40:15};

#comment