【问题标题】:Tabbing over a JTable component在 JTable 组件上切换
【发布时间】:2023-12-20 08:05:01
【问题描述】:

我有一个包含许多组件的面板,其中一个是JTable。当JTable 获得焦点并按下 TAB 键时,默认行为是将焦点从表格中的一个单元格移动到另一个单元格。我需要将其更改为专注于下一个组件,即完全保留 JTable

Ctrl-TAB 达到了预期的效果,但用户无法接受。我可以在表格中添加一个键侦听器并在按下 TAB 时更改焦点,但感觉好像有更好的方法可以做到这一点。

有什么想法吗?

谢谢...

【问题讨论】:

标签: java swing jtable


【解决方案1】:

您通常可以通过将Action 添加到组件操作映射中,然后在组件的输入映射中将击键与它绑定(下面的示例代码)来执行此操作。但是,这不适用于选项卡,因为焦点子系统会使用此事件除非您添加以下行以删除选项卡作为焦点遍历键:

tp.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.<AWTKeyStroke>emptySet());

这是完整的示例代码:

public static void main(String[] args) {
    final JTabbedPane tp = new JTabbedPane();

    // Remove Tab as the focus traversal key - Could always add another key stroke here instead.
    tp.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.<AWTKeyStroke>emptySet());

    KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);

    Action nextTab = new AbstractAction("NextTab") {
        public void actionPerformed(ActionEvent evt) {
            int i = tp.getSelectedIndex();
            tp.setSelectedIndex(i == tp.getTabCount() - 1 ? 0 : i + 1);
        }
    };

    // Register action.
    tp.getActionMap().put("NextTab", nextTab);
    tp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, "NextTab");

    tp.addTab("Foo", new JPanel());
    tp.addTab("Bar", new JPanel());
    tp.addTab("Baz", new JPanel());
    tp.addTab("Qux", new JPanel());

    JFrame frm = new JFrame();

    frm.setLayout(new BorderLayout());
    frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frm.add(new JButton(nextTab), BorderLayout.NORTH);
    frm.add(tp, BorderLayout.CENTER);
    frm.setBounds(50,50,400,300);
    frm.setVisible(true);
}

【讨论】:

  • 这就是我需要的小费。无法弄清楚为什么 TAB 不起作用,但有一个想法是因为 FocusPolicy。
【解决方案2】:

好吧,您可能不想仅仅摆脱 Tab Action,因为它还有其他职责。例如,当您正在编辑一个单元格时,选项卡操作会在移动到下一个单元格之前停止单元格编辑。因此,您可能希望保留此行为,同时添加额外的行为以将焦点转移到下一个组件。

我将其称为“包装动作”,您可以通过查看Table Tabbing 动作找到一个示例。您应该能够轻松自定义代码以使用 KeyboardFocusManager 来转移焦点。

【讨论】: