2

通过按 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;
        }
    }); 
    } 
}
4

2 回答 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);

关键是您必须将表格的默认选项卡操作替换为您自己的选项卡操作。

于 2013-03-15T00:56:00.787 回答
0

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

根据两个标志的状态更新表的选择模型:toggleextend。UI 接收到的键盘或鼠标事件导致的对选择的大多数更改都通过此方法进行引导,因此该行为可能会被子类覆盖。某些 UI 可能需要比此方法提供的更多功能,例如在操作引线以进行不连续选择时,并且可能不会调用此方法进行某些选择更改。

JTable 类在确定焦点应如何移动后调用此方法,从而row表示column新的目标单元格。

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

这种方法的好处是它可以与定义的 JTable 焦点遍历键一起使用。

于 2019-10-27T19:35:34.623 回答