我有一个类,它是扩展 JComponent 的自定义 swing 组件。我试图通过简单地按 TAB 或 SHIFT+TAB 来实现此自定义组件的子组件的焦点遍历。相反,无论我另外指定什么,默认情况下它们似乎只能通过按 CTRL+TAB 或 CTRL+SHIFT+TAB 来遍历。我参考了here的答案,虽然我的组件不是JTextArea,并且我尝试直接在构造函数中使用下面的代码设置焦点遍历键,但无济于事。
setFocusCycleRoot(true);
setFocusTraversalKeysEnabled(true);
Set<AWTKeyStroke> forwardKeys = new HashSet<>();
forwardKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);
Set<AWTKeyStroke> backwardKeys = new HashSet<>();
backwardKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK));
setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys);
我还尝试向组件添加一个关键侦听器,以有效地使用下面的代码执行相同的操作,但这也不起作用。
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_TAB) {
if (e.isShiftDown()) {
transferFocusBackward();
} else {
transferFocus();
}
e.consume();
}
}
});
我发现,如果我不包含上面的任何一个代码块,而是重写 isManagingFocus() 方法以始终返回 true,我就会得到我想要的行为,但我不想这样做,因为 isManagingFocus() 已被弃用。
是的,我知道这个问题已经有五年了,是的,我知道我是最初提交它的人。不过,我又回到了这个问题上,终于找到了解决的方法。这个问题背后的主要推动力是保留组件的功能,同时消除已弃用代码的使用。
isManagingFocus()
的 JComponent
方法已被弃用,但重写它以始终返回“true”会导致组件成为可通过 TAB 和 SHIFT+TAB 进行焦点遍历的组件,而无需使用 CTRL 键,这是我想要保留的功能。
查看调用
JComponent
的 isManagingFocus()
构造函数的源代码,我找到了一种在自定义组件的构造函数中以非弃用方式调整该代码的方法,该方法将保留组件之前具有的相同行为。五年前我的尝试非常接近,基本上在设置焦点键时缺少额外的 InputEvent.CTRL_DOWN_MASK
修饰符。这是我所做的:
Set<KeyStroke> managingFocusForwardTraversalKeys;
Set<KeyStroke> managingFocusBackwardTraversalKeys;
synchronized (JComponent.class) {
managingFocusForwardTraversalKeys = new HashSet<KeyStroke>(1);
managingFocusForwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.CTRL_DOWN_MASK));
managingFocusBackwardTraversalKeys = new HashSet<KeyStroke>(1);
managingFocusBackwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK));
}
//The old deprecated way of doing this that isManagingFocus() would trigger in the JComponent constructor.
//LookAndFeel.installProperty(this, "focusTraversalKeysForward", managingFocusForwardTraversalKeys);
//LookAndFeel.installProperty(this, "focusTraversalKeysBackward", managingFocusBackwardTraversalKeys);
//The new way of doing this
setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, managingFocusForwardTraversalKeys);
setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, managingFocusBackwardTraversalKeys);