在java/jfc swing jtable中切换行选择模式和单单元格选择模式

k97glaaz  于 2021-06-27  发布在  Java
关注(0)|答案(1)|浏览(425)

在一个主要由一组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());
    } 

}
8mmmxcuj

8mmmxcuj1#

对你的身体做一些调整 quitEditMode 方法,您将得到想要的结果:

private void quitEditMode(JTable table, final KeyStroke tabKey, final KeyStroke shiftTabKey) {
        System.out.println("editing de-activated");
        table.setCellSelectionEnabled(false);
        table.getCellEditor(table.getSelectedRow(), table.getSelectedColumn() ).stopCellEditing();
        table.setRowSelectionAllowed( true );
        table.setRowSelectionInterval( table.getSelectedRow(), table.getSelectedRow() );
        InputMap input = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        input.remove(shiftTabKey);
        input.remove(tabKey);
        input.put(shiftTabKey, "tabBefore");
        input.put(tabKey, "tabNext");
    }

相关问题