在一个主要由一组jtables和jtextfields组成的应用程序中,我尝试使用键盘和鼠标来实现它的可访问性。我的想法是帮助用户使用vk\u tab键在组件之间导航的最佳方法。
我的第一个目标是阻止jtables在用户试图导航到邻居jtextfield时“吞下”vk\u tab键。我试图在下面列出一个最小的可编译和可运行的示例。我询问了聚焦jtable对vk\u enter的React:在那之后,它会对vk\u tab作出React,将焦点提供给下一个单元格,直到按下esc。
下面这个可运行的例子是我对得到的答案所做的分析的结果。编译代码时,行选择模式处于活动状态,tab键在文本字段和表之间跳跃。当您按enter键时,它将切换到单一编辑模式,您可以使用tab键更改单元格,直到按esc键为止。
我仍然存在的问题是:编辑单元格并按esc键时,单个单元格仍处于选中状态。相反,应该选择整行。我怎么才能做到?
谢谢!
package TableTest;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
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.ListSelectionModel;
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
final KeyStroke tabKey = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(tabKey, "tabNext");
final AbstractAction tabNext = new AbstractAction() {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent ae) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent();
}
};
table.getActionMap().put("tabNext", tabNext);
// When Shift+TAB is hit, go to previous Component instead of previous cell
final KeyStroke shiftTabKey = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK);
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(shiftTabKey, "tabBefore");
final AbstractAction tabBefore = new AbstractAction() {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent event) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().focusPreviousComponent();
}
};
table.getActionMap().put("tabBefore", tabBefore);
// on VK_ENTER, navigate in JTable only ("edit mode")
final KeyStroke enterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
final AbstractAction editModeAction = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent event) {
editMode(table, tabKey, shiftTabKey);
}
};
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(enterKey, "editModeAction");
table.getActionMap().put("editModeAction", editModeAction);
// On VK_ESCAPE or when JTable loses focus, quit the "edit mode"
final KeyStroke escKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
final AbstractAction quitEditModeAction = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent event) {
quitEditMode(table, tabKey, shiftTabKey);
}
};
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(escKey, "quitEditModeAction");
table.getActionMap().put("quitEditModeAction", quitEditModeAction);
final FocusListener listener = new FocusListener() {
@Override
public void focusGained(FocusEvent event) {
//do nothing
}
@Override
public void focusLost(FocusEvent event) {
quitEditMode(table, tabKey, shiftTabKey);
}
};
table.addFocusListener(listener);
JTextField jtf = new JTextField("Text here");
contentPane.add(jtf, BorderLayout.NORTH);
contentPane.add(table, BorderLayout.CENTER);
pack();
//printActions(table);
}
private void editMode(JTable table, final KeyStroke tabKey, final KeyStroke shiftTabKey) {
System.out.println("editing activated");
table.setCellSelectionEnabled(true);
InputMap input = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
input.remove(shiftTabKey);
input.remove(tabKey);
input.put(shiftTabKey, "selectPreviousColumnCell");
input.put(tabKey, "selectNextColumnCell");
}
private void quitEditMode(JTable table, final KeyStroke tabKey, final KeyStroke shiftTabKey) {
System.out.println("editing de-activated");
table.setCellSelectionEnabled(false);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
InputMap input = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
input.remove(shiftTabKey);
input.remove(tabKey);
input.put(shiftTabKey, "tabBefore");
input.put(tabKey, "tabNext");
}
// print a String representation of each KeyStroke from the InputMap
private void printActions(JTable table) {
InputMap input = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
if (input != null && input.allKeys() != null) {
for (KeyStroke key : input.allKeys()) {
if (key != null) {
printKeyStroke(key);
printActionName(input, key);
}
}
}
}
// build the String represantation
private void printKeyStroke(KeyStroke key) {
StringBuilder tk = new StringBuilder("[");
int modifiers = key.getModifiers();
if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0)
tk.append("shift+");
if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0)
tk.append("ctrl+");
if ((modifiers & InputEvent.META_DOWN_MASK) != 0)
tk.append("cmd+");
if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0)
tk.append("alt+");
tk.append("'");
tk.append(KeyEvent.getKeyText(key.getKeyCode()));
tk.append("'=");
tk.append("keycode=");
tk.append(key.getKeyCode());
tk.append("]");
System.out.print(tk.toString());
}
private void printActionName(InputMap input, KeyStroke key) {
System.out.print(": ");
Object string = input.get(key);
if (string != null && string instanceof String)
System.out.println(string.toString());
}
}
1条答案
按热度按时间8mmmxcuj1#
对你的身体做一些调整
quitEditMode
方法,您将得到想要的结果: