如何从Tab键导航中排除列?

问题描述 投票:2回答:2

通过按Tab键,焦点将移至下一个单元格。我想更改此行为,以便某些列从Tab键导航中排除。假设一个表由5列组成,那么只有第1列和第3列应被考虑进行导航。根据我的阅读,FocusTraversalPolicy用于此目的。但是,由于未提供列和行指示,因此实现此行为似乎相当复杂。那么如何返回正确的组件?

public class Table extends JTable{
int columnCount = 5;
int[] tab = { 1, 3 };  
    public Table(){
        ...
        this.setFocusTraversalPolicy(new FocusTraversalPolicy() {

        @Override
        public Component getLastComponent(Container arg0) {
             return null;
        }

        @Override
        public Component getFirstComponent(Container arg0) {
            return null;
        }

        @Override
        public Component getDefaultComponent(Container arg0) {
            return null;
        }

        @Override
        public Component getComponentBefore(Container arg0, Component arg1) {
            return null;
        }

        @Override
        public Component getComponentAfter(Container arg0, Component arg1) {
            return null;
        }
    }); 
    } 
}
java swing jtable key-bindings
2个回答
5
投票

根据我的阅读,FocusTraversalPolicy用于此目的

表列不是真正的组件,因此一旦表获得焦点,FocusTraversalPolicy就没有任何意义。 JTable提供了从一个单元格移动到另一个单元格的操作。

您也许可以使用Table Tabbing中的概念。例如:

public class SkipColumnAction extends WrappedAction
{
    private JTable table;
    private Set columnsToSkip;

    /*
     *  Specify the component and KeyStroke for the Action we want to wrap
     */
    public SkipColumnAction(JTable table, KeyStroke keyStroke, Set columnsToSkip)
    {
        super(table, keyStroke);
        this.table = table;
        this.columnsToSkip = columnsToSkip;
    }

    /*
     *  Provide the custom behaviour of the Action
     */
    public void actionPerformed(ActionEvent e)
    {
        TableColumnModel tcm = table.getColumnModel();
        String header;

        do
        {
            invokeOriginalAction( e );

            int column = table.getSelectedColumn();
            header = tcm.getColumn( column ).getHeaderValue().toString();
        }
        while (columnsToSkip.contains( header ));
    }
}

要使用该类,您会做:

Set<String> columnsToSkip = new HashSet<String>();
columnsToSkip.add("Column Name ?");
columnsToSkip.add("Column Name ?");
new SkipColumnAction(table, KeyStroke.getKeyStroke("TAB"), columnsToSkip);
new SkipColumnAction(table, KeyStroke.getKeyStroke("shift TAB"), columnsToSkip);

关键是您必须用自己的一个替换表的默认制表符操作。


0
投票

有点陈旧,但另一个解决方案是覆盖JTable方法public void changeSelection(final int row, final int column, boolean toggle, boolean extend) 。根据文档,此方法...

根据两个标志的状态更新表的选择模型:toggleextend。 UI接收到的键盘或鼠标事件的结果,对选择所做的大多数更改都通过此方法传递,以便该行为可以被子类覆盖。一些UI可能需要比此方法提供的功能更多的功能,例如,在操纵潜在顾客进行不连续选择时,可能不对某些选择更改调用此方法。

JTable类在确定焦点应如何移动之后调用此方法,因此rowcolumn代表新的目标单元格。

如果覆盖该方法,则可以根据需要更改此调用中的行和列,例如,跳过对只读单元格的选择。只需确定新的行和列是什么,然后将它们传递回super.changeSelection()方法即可。

此方法的优点在于,它可与定义的JTable焦点遍历键一起使用。

© www.soinside.com 2019 - 2024. All rights reserved.