Swing/InputVerifierFocusOrder のバックアップ(No.12)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/InputVerifierFocusOrder へ行く。
- 1 (2016-08-15 (月) 02:10:21)
- 2 (2016-08-22 (月) 08:55:12)
- 3 (2016-10-25 (火) 17:53:18)
- 4 (2017-02-20 (月) 19:40:38)
- 5 (2017-02-28 (火) 17:51:53)
- 6 (2017-11-14 (火) 18:04:32)
- 7 (2018-02-15 (木) 14:23:42)
- 8 (2019-06-28 (金) 20:34:23)
- 9 (2021-03-10 (水) 14:38:51)
- 10 (2025-01-03 (金) 08:57:02)
- 11 (2025-01-03 (金) 09:01:23)
- 12 (2025-01-03 (金) 09:02:38)
- 13 (2025-01-03 (金) 09:03:21)
- 14 (2025-01-03 (金) 09:04:02)
- category: swing folder: InputVerifierFocusOrder title: InputVerifierを設定したコンポーネントのフォーカスナビゲーションをテストする tags: [JTextField, InputVerifier, FocusTraversalPolicy, FocusListener] author: aterai pubdate: 2016-08-15T02:09:37+09:00 description: InputVerifierを設定したコンポーネントの入力の検証とフォーカス移動イベントの順番をテストします。 image: https://drive.google.com/uc?id=19ojUQl6rF4StwHNdQO_xPRlqnkOognwULw
Summary
InputVerifier
を設定したコンポーネントの入力の検証とフォーカス移動イベントの順番をテストします。
Screenshot
Advertisement
Source Code Examples
JTextField textField = new JTextField(24);
textField.setInputVerifier(new InputVerifier() {
@Override public boolean verify(JComponent c) {
if (c instanceof JTextComponent) {
JTextComponent tc = (JTextComponent) c;
String str = tc.getText().trim();
return !str.isEmpty() && MAX_LEN - str.length() >= 0;
}
return false;
}
@Override public boolean shouldYieldFocus(JComponent input) {
System.out.println("shouldYieldFocus");
if (isAllValid()) {
button.setEnabled(true);
// EventQueue.invokeLater(() -> button.requestFocusInWindow());
} else {
button.setEnabled(false);
}
return super.shouldYieldFocus(input);
}
});
setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
@Override public Component getComponentAfter(
Container focusCycleRoot, Component aComponent) {
System.out.println("getComponentAfter");
button.setEnabled(isAllValid());
return super.getComponentAfter(focusCycleRoot, aComponent);
}
@Override public Component getComponentBefore(
Container focusCycleRoot, Component aComponent) {
System.out.println("getComponentAfter");
button.setEnabled(isAllValid());
return super.getComponentBefore(focusCycleRoot, aComponent);
}
});
setFocusCycleRoot(true);
View in GitHub: Java, Kotlin解説
上記のサンプルでは、パネル内のJTextField
がすべて入力検証に成功した場合、JButton
をクリック可能に更新するUI
のテストを行っています。
- Tabキーを押してフォーカス移動するときすべての
JTextField
がすべて入力検証に成功する場合は、JButton
をクリック可能に更新、JButton
にフォーカスを移動、直後にSpaceキーなどでクリックしたい InputVerifier#shouldYieldFocus(...)
やFocusListener#focusLost(...)
でJButton#setEnabled(true)
としても、フォーカスはJButton
に移動しない(初めてJButton
がクリック可能になったときは先頭のJCheckBox
にフォーカスが移動する)- これらの実行より先に
LayoutFocusTraversalPolicy#getComponentAfter(...)
で次にフォーカスが移動するコンポーネントが決定されるため、この時点でJButton#setEnabled(true)
になっていないJButton
はスキップされる
- これらの実行より先に
- 回避方法:
InputVerifier#shouldYieldFocus(...)
やFocusListener#focusLost(...)
内でEventQueue.invokeLater(() -> button.requestFocusInWindow() );
などを実行し、一番後でフォーカスを強制的にJButton
に移動する- または
LayoutFocusTraversalPolicy#getComponentAfter(...)
をオーバーライドして事前にJButton#setEnabled(true)
を実行する