Используя Eclipse TableViewer, как мне перемещаться и редактировать ячейки со стрелками?

Я использую TableViewer с поставщиком контента, поставщиком ярлыков, ICellModifier и TextCellEditors для каждого столбца.

Как я могу добавить навигацию по клавишам со стрелкой и редактирование ячеек, когда пользователь выбирает ячейку? Я бы хотел, чтобы это было как можно более естественным.

Посмотрев на некоторые из онлайн-примеров, кажется, что существует старый способ (с TableCursor) и новый способ (TableCursor не смешивается с CellEditors?).

В настоящее время мой TableViewer без курсора будет прокручиваться только в первом столбце. В базовой таблице SWT отображается курсор как null.

Есть ли хороший пример TableViewer с помощью CellEditors и сотовой навигации с клавиатуры?

Спасибо!

Ответы

Ответ 1

Я не знаю, есть ли хороший пример. Я использую кластер пользовательского кода, чтобы получить то, что я считаю основным поведением таблицы для моего приложения, работающего поверх TableViewer. (Обратите внимание, что на данный момент мы все еще нацелены на 3.2.2, поэтому, возможно, все стало лучше или иначе изменилось.) Некоторые основные моменты:

  • Я делаю setCellEditors() на моем TableViewer.
  • В каждом элементе управления CellEditor я устанавливаю то, что считаю подходящим TraverseListener. Например, для текстовых ячеек:

    cellEditor = new TextCellEditor(table, SWT.SINGLE | getAlignment());
    cellEditor.getControl().addTraverseListener(new TraverseListener() {
        public void keyTraversed(TraverseEvent e) {
            switch (e.detail) {
            case SWT.TRAVERSE_TAB_NEXT:
                // edit next column
                e.doit = true;
                e.detail = SWT.TRAVERSE_NONE;
                break;
    
            case SWT.TRAVERSE_TAB_PREVIOUS:
                // edit previous column
                e.doit = true;
                e.detail = SWT.TRAVERSE_NONE;
                break;
    
            case SWT.TRAVERSE_ARROW_NEXT:
                // Differentiate arrow right from down (they both produce the same traversal @*$&#%^)
                if (e.keyCode == SWT.ARROW_DOWN) {
                    // edit same column next row
                    e.doit = true;
                    e.detail = SWT.TRAVERSE_NONE;
                }
                break;
    
            case SWT.TRAVERSE_ARROW_PREVIOUS:
                // Differentiate arrow left from up (they both produce the same traversal @*$&#%^)
                if (e.keyCode == SWT.ARROW_UP) {
                    // edit same column previous row
                    e.doit = true;
                    e.detail = SWT.TRAVERSE_NONE;
                }
                break;
            }
        }
    });
    

(Для выпадающих ячеек таблицы я убираю стрелки влево и вправо, а не вверх и вниз.)

  • Я также добавляю элемент TraverseListener в элемент управления TableViewer, задачей которого является начало редактирования ячейки, если кто-то нажимает "return", когда выбрана целая строка.

    // This really just gets the traverse events for the TABLE itself.  If there is an active cell editor, this doesn't see anything.
    tableViewer.getControl().addTraverseListener(new TraverseListener() {
        public void keyTraversed(TraverseEvent e) {
            if (e.detail == SWT.TRAVERSE_RETURN) {
                // edit first column of selected row
            }
        }
    });
    
  • Теперь, как я могу управлять редактированием, это еще одна история. В моем случае весь мой TableViewer (и представление каждого столбца в нем) свободно обернуты в пользовательский объект с помощью методов, чтобы сделать то, что говорят выше. Реализации этих методов в конечном итоге заканчиваются вызовом tableViewer.editElement(), а затем проверкой tableViewer.isCellEditorActive(), чтобы убедиться, что ячейка действительно редактируема (поэтому мы можем перейти к следующей редактируемой, если нет).

  • Я также сочла полезным программировать "отказаться от редактирования" (например, при переходе из последней ячейки в строке). К сожалению, единственный способ, с помощью которого я мог придумать это, - ужасный хак, который решил работать с моей конкретной версией, spelunking через источник для вещей, которые могли бы вызвать желаемые "побочные эффекты":

        private void relinquishEditing() {
            // OMG this is the only way I could find to relinquish editing without aborting.
            tableViewer.refresh("some element you don't have", false);
        }
    

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

Ответ 2

Вот что сработало для меня:

TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(tableViewer,new FocusCellOwnerDrawHighlighter(tableViewer));
ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(tableViewer) {
    protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
        return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL 
            || event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION                                   
            || (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.CR) 
            || event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
       }
};

Я могу перемещаться во всех направлениях со вкладкой во время редактирования и стрелка вокруг, когда она не находится в режиме редактирования.

Ответ 4

Я работал над этим JFace Snippet, но мне также пришлось скопировать пару связанных классов:

  • org.eclipse.jface.snippets.viewers.TableCursor
  • org.eclipse.jface.snippets.viewers.CursorCellHighlighter
  • org.eclipse.jface.snippets.viewers.AbstractCellCursor

и я не помню точно, где я их нашел. Это также org.eclipse.swt.custom.TableCursor, но я не мог заставить это работать.

Ответ 5

Взгляните на Пример включения активации редактора при двойном щелчке.

Материал между строками [110 - 128] добавляет ColumnViewerEditorActivationStrategy и TableViewerEditor. В моем случае я хотел, чтобы один клик начал редактирование, поэтому я изменил строку 115: ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION в ColumnViewerEditorActivationEvent.MOUSE_CLICK_SELECTION. После добавления этого в мой TableViewer ключ вкладки переместился из поля в поле с включенным редактором.