Подтвердить что ты не робот

Javafx: повторная сортировка столбца в TableView

У меня есть TableView, связанный с TreeView. Каждый раз, когда выбран параметр node в TreeView, TableView обновляется с различными данными.

Я могу отсортировать любой столбец в TableView, просто нажав соответствующий заголовок столбца. Это прекрасно работает.

Но: при выборе другого node в древовидном представлении, хотя заголовки столбцов продолжают отображаться как отсортированные. Данные отсутствуют.

Есть ли способ программно обеспечить порядок сортировки, создаваемый пользователем каждый раз, когда данные изменяются?

4b9b3361

Ответ 1

Хорошо, я нашел, как это сделать. Я опишу его здесь, если это полезно для других:

До вы обновляете содержимое TableView, вы должны сохранить sortcolum (если есть) и sortType:

        TableView rooms;
        ...
        TableColumn sortcolumn = null;
        SortType st = null;
        if (rooms.getSortOrder().size()>0) {
            sortcolumn = (TableColumn) rooms.getSortOrder().get(0);
            st = sortcolumn.getSortType();
        }

Затем после того, как вы закончите обновление данных в TableView, вы должны восстановить потерянное состояние sort-column и выполнить сортировку.

       if (sortcolumn!=null) {
            rooms.getSortOrder().add(sortcolumn);
            sortcolumn.setSortType(st);
            sortcolumn.setSortable(true); // This performs a sort
        }

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

Ответ 2

У меня была такая же проблема и выяснилось, что после обновления данных вам нужно только вызвать функцию sort() в представлении таблицы:

TableView rooms;
...
// Update data of rooms
...
rooms.sort()

В представлении таблицы есть столбцы для сортировки, поэтому функция сортировки сортирует новые данные в желаемом порядке. Эта функция доступна только на Java 8.

Ответ 3

Если ваш TableView не повторно инициализирован, вы также можете сделать следующее:

TableColumn<BundleRow, ?> sortOrder = rooms.getSortOrder().get(0);
rooms.getSortOrder().clear();
rooms.getSortOrder().add(sortOrder);

Ответ 4

Пример fornacif работает, но нет, если существует более одного порядка сортировки (попробуйте щелкнуть по второму столбцу, чтобы создать дополнительный порядок сортировки).

Чтобы выполнить повторный сортировку по всем столбцам, вам нужно сделать что-то вроде этого:

List<TableColumn<Room, ?>> sortOrder = new ArrayList<>(roomTable.getSortOrder());
roomTable.getSortOrder().clear();
roomTable.getSortOrder().addAll(sortOrder);

Ответ 5

Если вы используете метод TableView.setItems(), он выглядит как reset несколько аспектов TableView. Оставьте ObservableList в TableView на месте, очистите его содержимое и добавьте новые элементы. Затем TableView.sort() все равно будет знать, какие столбцы были предварительно отсортированы, и он будет работать. Вот так:

  tableView.getItems().clear();
  tableView.getItems().addAll(newTableData);
  tableView.sort();

Ответ 6

Ответ Марко Якоба хорош для большинства случаев, но я обнаружил, что мне нужно создать компаратор, который соответствует порядку сортировки таблиц для большей гибкости. Затем вы можете использовать любой метод, который использует компаратор для сортировки, поиска и т.д. Чтобы создать компаратор, я расширил класс ComparatorChain из apache Common-Collections позволяет легко выполнять сортировку нескольких столбцов. Это выглядит так.

public class TableColumnListComparator extends ComparatorChain {
    public TableColumnListComparator(ObservableList<? extends TableColumn> columns) {
        // Get list of comparators from column list.
        for (TableColumn column : columns) {
            addComparator(new ColumnComparator(column));
        }
    }

    /**
     * Compares two items in a table column as if they were being sorted in the TableView.
     */
    private static class ColumnComparator implements Comparator {

        private final TableColumn column;

        /**
         * Default Constructor.  Creates comparator based off given table column sort order.
         *
         * @param column
         */
        public ColumnComparator(TableColumn column) {
            this.column = column;
        }

        @Override
        public int compare(Object o1, Object o2) {
            // Could not find a way to do this without casts unfortunately
            // Get the value of the column using the column cell value factory.
            final ObservableValue<?> obj1 = (ObservableValue) column.getCellValueFactory().call(
                    new TableColumn.CellDataFeatures(column.getTableView(), column, o1));
            final ObservableValue<?> obj2 = (ObservableValue) column.getCellValueFactory().call(
                    new TableColumn.CellDataFeatures(column.getTableView(), column, o2));
            // Compare the column values using the column given comparator.
            final int compare = column.getComparator().compare(obj1.getValue(), obj2.getValue());
            // Sort by proper ascending or descending.
            return column.getSortType() == TableColumn.SortType.ASCENDING ? compare : -compare;
        }
    }
}

Затем вы можете сортировать в любое время с помощью

Collections.sort(backingList, new TalbeColumnListComparator(table.getSortOrder());

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