Как исключить столбцы из навигации по табуляции?

При нажатии 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;
        }
    }); 
    } 
}

person Pedro    schedule 14.03.2013    source источник
comment
никогда не пробовал, эти keys_short_cuts реализованы с помощью KeyBindings @ camickr, вы можете слушать ListSelectionListener, я уверен который решался здесь несколько раз, обратите внимание, что ListSelectionModel является только одномерным   -  person mKorbel    schedule 15.03.2013
comment
Взгляните на это   -  person MadProgrammer    schedule 15.03.2013


Ответы (2)


Из того, что я читал, для этой цели используется FocusTraversalPolicy.

Столбцы таблицы не являются реальными компонентами, поэтому FocusTraversalPolicy не имеет значения, когда таблица получает фокус. JTable предоставляет действия для перехода от ячейки к ячейке.

Возможно, вы сможете использовать концепции, приведенные в разделе Таблица вкладок. Например:

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);

Ключевым моментом является то, что вы должны заменить действие табуляции таблицы по умолчанию своим собственным.

person camickr    schedule 15.03.2013

Немного устаревшее, но другое решение - перезаписать метод JTable public void changeSelection(final int row, final int column, boolean toggle, boolean extend) . Согласно документам, этот метод...

Обновляет модели выбора таблицы в зависимости от состояния двух флагов: toggle и extend. Большинство изменений в выборе, которые являются результатом событий клавиатуры или мыши, полученных пользовательским интерфейсом, направляются через этот метод, поэтому поведение может быть переопределено подклассом. Некоторым пользовательским интерфейсам может потребоваться больше функциональных возможностей, чем предоставляет этот метод, например, при манипулировании лидом для несмежного выбора, и этот метод может не вызываться для некоторых изменений выбора.

Класс JTable вызывает этот метод после определения того, как должен перемещаться фокус, поэтому row и column представляют новую целевую ячейку.

Если вы переопределите метод, вы можете изменить строку и столбец в этом вызове по мере необходимости, например, чтобы пропустить выбор ячеек только для чтения. Просто определите, что такое новая строка и столбец, и передайте их обратно в метод super.changeSelection().

Преимущество этого подхода заключается в том, что он работает с определенными ключами обхода фокуса JTable.

person Michael McKay    schedule 27.10.2019