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

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

Posted by terai at 2004-10-11

概要

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

  • &jnlp;
  • &jar;
  • &zip;

#screenshot

サンプルコード

EventQueue.invokeLater(new Runnable() {
  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が呼び出されたときに、requestFocusInWindow
      frame.addComponentListener(new ComponentAdapter() {
        @Override
        public void componentShown(ComponentEvent e) {
          field.requestFocusInWindow();
        }
      });
      

このサンプルでは、ウィンドウを開いたときにフォーカスを持つコンポーネントとは別に、フォーカスがどこにあるかどうかにかかわらず、Enterしたときに起動されるボタンを以下のメソッドを使って設定しています(JRootPane#setDefaultButton(javax.swing.JButton))。

frame.getRootPane().setDefaultButton(eb);

参考リンク

コメント

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