• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:Focusの移動
#navi(../)
*Focusの移動 [#x8547c84]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2004-04-26~
更新日:&lastmod;
---
category: swing
folder: FocusTraversal
title: Focusの移動
tags: [FocusTraversalPolicy, Focus]
author: aterai
pubdate: 2004-04-26T12:45:56+09:00
description: FocusTraversalPolicyを使って、KBD{Tab}キーなどによるフォーカスの移動を制御します。
image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTNE9BAwqI/AAAAAAAAAaM/57d2rzX7ixk/s800/FocusTraversal.png
---
* 概要 [#summary]
`FocusTraversalPolicy`を使って、KBD{Tab}キーなどによるフォーカスの移動を制御します。

#contents
#download(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTNE9BAwqI/AAAAAAAAAaM/57d2rzX7ixk/s800/FocusTraversal.png)

**概要 [#b257f3c8]
FocusTraversalPolicyを使って、Tabキーなどによるフォーカスの移動を制御します。[[dW : Java technology : Merlinの魔術: フォーカス、フォーカス、フォーカス>http://www-6.ibm.com/jp/developerworks/java/031010/j_j-mer07153.html]]からの引用です。

#screenshot

**サンプルコード [#le272dee]
#code{{
* サンプルコード [#sourcecode]
#code(link){{
JButton nb = new JButton("NORTH");
JButton sb = new JButton("SOUTH");
JButton wb = new JButton("WEST");
JButton eb = new JButton("EAST");
add(new JScrollPane(field), BorderLayout.CENTER);
add(new JScrollPane(textarea));
add(nb, BorderLayout.NORTH);
add(sb, BorderLayout.SOUTH);
add(wb, BorderLayout.WEST);
add(eb, BorderLayout.EAST);
final Component[] order = new Component[]{eb, wb, sb, nb};

FocusTraversalPolicy policy = new FocusTraversalPolicy() {
  java.util.List list = Arrays.asList(order);
  public Component getFirstComponent(Container focusCycleRoot) {
    return order[0];
  private final List<? extends Component> order = Arrays.asList(eb, wb, sb, nb);
  @Override public Component getFirstComponent(Container focusCycleRoot) {
    return order.get(0);
  }
  public Component getLastComponent(Container focusCycleRoot) {
    return order[order.length-1];

  @Override public Component getLastComponent(Container focusCycleRoot) {
    return order.get(order.size() - 1);
  }
  public Component getComponentAfter(Container fcr, Component cmp) {
    int index = list.indexOf(cmp);
    return order[(index + 1) % order.length];

  @Override public Component getComponentAfter(
      Container focusCycleRoot, Component aComponent) {
    int i = order.indexOf(aComponent);
    return order.get((i + 1) % order.size());
  }
  public Component getComponentBefore(Container fcr, Component cmp) {
    int index = list.indexOf(cmp);
    return order[(index - 1 + order.length) % order.length];

  @Override public Component getComponentBefore(
      Container focusCycleRoot, Component aComponent) {
    int i = order.indexOf(aComponent);
    return order.get((i - 1 + order.size()) % order.size());
  }
  public Component getDefaultComponent(Container focusCycleRoot) {
    return order[0];

  @Override public Component getDefaultComponent(Container focusCycleRoot) {
    return order.get(0);
  }
};
frame.setFocusTraversalPolicy(policy);
//setFocusTraversalPolicyProvider(true);
//setFocusTraversalPolicy(policy);
// setFocusTraversalPolicyProvider(true);
// setFocusTraversalPolicy(policy);
}}
-&jnlp;
-&jar;
-&zip;

**解説 [#h3d0848b]
上記のサンプルでは、Tabキー((Shift+Tabキーでは逆順))を押していくと、東西南北の順でボタンのフォーカスが移動します。中央のテキストフィールドにはTabキーでフォーカスは移動しません。
* 解説 [#explanation]
上記のサンプルでは、`FocusTraversalPolicy`を使用してキー入力によるフォーカスの移動を制御しています。また、`JRadioButton`で以下のような`FocusTraversalPolicy`に切り替えが可能です。

FocusTraversalPolicyを使用することで、キー入力によるフォーカスの移動を制御しています。コンポーネントを追加したパネルではなく、親のフレームにsetFocusTraversalPolicy()していることに注意してください。パネルに設定したい場合は、そのパネルがフォーカストラバーサルポリシーを提供するように、Container#setFocusTraversalPolicyProvider(true)としておく必要があります。
- `Default`
-- `JPanel`のデフォルトは、`null`
-- 実際のキー入力によるフォーカスの移動にはこのパネルの親(`JFrame`)に設定されている`FocusTraversalPolicy`を使用
- `Custom`
-- [https://www.ibm.com/developerworks/jp/java/library/j-mer07153/ Merlinの魔術: フォーカス、フォーカス、フォーカス]からの引用
-- KBD{Tab}キーを押していくと東西南北の順でボタンのフォーカスが移動(KBD{Shift+Tab}キーでは逆順)
-- `4`つの`JButton`以外にはKBD{Tab}キーでフォーカスは移動しない
- `Layout`
-- 以下のように`LayoutFocusTraversalPolicy`(`LayoutFocusTraversalPolicy`は`Swing`のデフォルト、`AWT`のデフォルトは`DefaultFocusTraversalPolicy`)の`accept`メソッドをオーバーライドして中央の`JTextArea`(通常`JTextArea`などから次のコンポーネントにフォーカス移動する場合はKBD{Ctrl+Tab})が編集不可の場合は、これにKBD{Tab}キーなどでフォーカスが移動しないように設定
#code{{
frame.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
  @Override protected boolean accept(Component c) {
    if (c instanceof JTextComponent) {
      return ((JTextComponent) c).isEditable();
    } else {
      return super.accept(c);
    }
  }
};
}}

**参考リンク [#n149aa1a]
-[[dW : Java technology : Merlinの魔術: フォーカス、フォーカス、フォーカス>http://www-6.ibm.com/jp/developerworks/java/031010/j_j-mer07153.html]]
* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/java/awt/doc-files/FocusSpec.html AWTフォーカス・サブシステム]
- [https://www.ibm.com/developerworks/jp/java/library/j-mer07153/ Merlinの魔術: フォーカス、フォーカス、フォーカス]
- [[Windowを開いたときのフォーカスを指定>Swing/DefaultFocus]]
- [[FocusTraversalKeysに矢印キーを追加してフォーカス移動>Swing/FocusTraversalKeys]]

**コメント [#o2ee0e2b]
* コメント [#comment]
#comment
#comment