在 Java Swing 中处理 VK_TAB 以在组件之间移动以及仅使用键盘在表格单元格之间移动的最佳实践 [英] Best practise for handling VK_TAB in Java Swing to move between components as well as to move between table cells using the keyboard only
问题描述
我正在尝试寻找与其他组件相关的表格可访问性方面的最佳实践.在主要由一组 JTable 和 JTextField 组成的应用程序中,我尝试使用键盘和鼠标使其可访问.我的想法是帮助用户使用 VK_TAB 键在组件之间导航的最佳方式.
I'm trying to find a best practise in terms of accessibility on Tables in relation to other components. In an app that's mainly a set of JTables and JTextFields, I tried to make it accessibility with keyboard as well as mouse. My thoughts are on the best way to help the user to navigate around between components using the VK_TAB key.
我的第一个目标是在用户尝试使用来自 Coderanch.我试图在下面组合一个最小的可编译和可运行示例.
My first goal was to stop JTables "swallow" the VK_TAB key when the user tries to navigate to a neighbor JTextField using a solution from Coderanch. I tried to put together a minimal compilable and runnable example below.
package TableTest;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
public class MyFrame extends JFrame {
private static final long serialVersionUID = 1L;
public MyFrame() {
super();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MyFrame frame = new MyFrame();
frame.init();
frame.setVisible(true);
}
});
}
private void init() {
JPanel contentPane = new JPanel(new BorderLayout());// new GridBagLayout()
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
JTable table = new JTable(new DefaultTableModel(new Object[][] { { 1, 2, 3 }, //
{ 4, 5, 6 }, //
{ 7, 8, 9 }, //
{ "#", 0, "*" }, }, //
new String[] { "First", "Second", "Third" }));
// When TAB is hit, go to next Component instead of next cell
table.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "tabNext");
table.getActionMap().put("tabNext", new AbstractAction() {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent ae) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent();
}
});
// When Shift+TAB is hit, go to previous Component instead of previous cell
table.getInputMap(JComponent.WHEN_FOCUSED)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK), "tabBefore");
table.getActionMap().put("tabBefore", new AbstractAction() {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent ae) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().focusPreviousComponent();
}
});
JTextField jtf = new JTextField("Text here");
contentPane.add(jtf, BorderLayout.NORTH);
contentPane.add(table, BorderLayout.CENTER);
pack();
}
}
但是对于想要导航到表格单元格的用户来说,这是相当激进和令人沮丧的,例如仅使用键盘进行编辑.所以,我的第二个目标是让键盘访问表格单元格.
But that's rather radical and frustrating for a user who wants to navigate to a Table cell, e.g. for editing, using only the keyboard. So, my second goal is to give keyboard access to Table Cells as well.
这里的最佳实践是什么?我想到了聚焦 JTable 对 VK_ENTER 的反应:之后,它会通过将焦点放在下一个单元格来对 VK_TAB 做出反应,直到...按下 ESC 或其他什么.
What is a best practise here? I thought of the focussed JTable reacting to VK_ENTER: after that, it would react to VK_TAB by giving focus to the next cell until ... ESC is pressed or whatever.
谢谢!
推荐答案
这里的最佳做法是什么?
What is a best practise here?
默认实现是:
- Tab - 移动到下一个组件
Ctrl+Tab - 移动到下一个组件
- Tab - moves to the next component
Ctrl+Tab - moves to the next component
Shift+Tab - 移动到上一个组件
Shift+Tab - moves to the previous component
某些组件处理 Tab 键.例如:
Some components handle the Tab key. For example:
- JTable - tab 用于移动到下一个单元格
- 文本组件(JTextArea、JTextPane) - 将一个制表符插入到文本中
因此对于处理 Tab 键的组件,用户将在使用键盘时使用 Ctrl+Tab 导航到下一个组件.
So for components that handle the Tab key the user would use Ctrl+Tab to navigate to the next component when using the keyboard.
我想到了聚焦 JTable 对 VK_ENTER 的反应
I thought of the focussed JTable reacting to VK_ENTER
您已经知道如何为 Tab 键分配不同的操作.
You already know how to assign a different Action to the Tab key.
所以现在您需要做的就是将默认的 Tab Action 分配给 Enter 键.您可以通过更改表的 InputMap 中的绑定来做到这一点:
So now all you need to do is assign the default Tab Action to the Enter key. You can do this by changing the binding in the InputMap of the Table:
InputMap im = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
KeyStroke addedKeyStroke = KeyStroke.getKeyStroke("ENTER");
im.put(addedKeyStroke, "selectNextColumnCell");
查看键绑定,了解一个显示每个 Swing 组件的所有默认操作.
Check out Key Bindings for a simple app that display all the default Actions for each Swing component.
这篇关于在 Java Swing 中处理 VK_TAB 以在组件之间移动以及仅使用键盘在表格单元格之间移动的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!