Javafx: повторная сортировка столбца в TableView
У меня есть TableView, связанный с TreeView. Каждый раз, когда узел в TreeView выбран, TableView обновляется с различными данными.
Я могу сортировать любой столбец в TableView, просто нажав на соответствующий заголовок столбца. Это прекрасно работает.
но: когда я выбираю другой узел в древовидном представлении, хотя заголовки столбцов продолжают отображаться как отсортированные. Данных нет.
есть ли способ программно применять порядок сортировки, выполняемый Пользователем при каждом изменении данных?
7 ответов
Ок, я нашел как это сделать. Я подытожу это здесь, если это полезно для других:
до вы обновляете содержимое 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, вы должны восстановить потерянное состояние столбца сортировки и выполнить сортировку.
if (sortcolumn!=null) {
rooms.getSortOrder().add(sortcolumn);
sortcolumn.setSortType(st);
sortcolumn.setSortable(true); // This performs a sort
}
Я не учитываю возможность наличия нескольких столбцов в сортировке, но это было бы очень просто сделать с этой информацией.
У меня была такая же проблема, и я узнал, что после обновления данных вам нужно только вызвать функцию sort () на табличном представлении:
TableView rooms;
...
// Update data of rooms
...
rooms.sort()
таблица знает столбцы для сортировки таким образом, функция сортировки будет сортировать новые данные в нужном порядке. Эта функция доступна только в Java 8.
Если ваш TableView не повторно инициализирован, вы также можете сделать следующее:
TableColumn<BundleRow, ?> sortOrder = rooms.getSortOrder().get(0);
rooms.getSortOrder().clear();
rooms.getSortOrder().add(sortOrder);
пример fornacif работает, но не если есть более одного порядка сортировки (попробуйте Shift-клик на второй столбец, чтобы создать вторичный порядок сортировки).
чтобы выполнить повторную сортировку по всем столбцам, вам нужно будет сделать что-то вроде этого:
List<TableColumn<Room, ?>> sortOrder = new ArrayList<>(roomTable.getSortOrder());
roomTable.getSortOrder().clear();
roomTable.getSortOrder().addAll(sortOrder);
Если вы используете TableView.метод setItems (), похоже, сбрасывает несколько аспектов TableView. Оставьте ObservableList в TableView на месте, очистите его содержимое, а затем добавьте новые элементы. Затем TableView Для.sort () по-прежнему будет знать, какие столбцы были ранее отсортированы, и он будет работать. Вот так:
tableView.getItems().clear();
tableView.getItems().addAll(newTableData);
tableView.sort();
ответ Марко Якоба хорош для большинства случаев, но я обнаружил, что мне нужно создать компаратор, который соответствует порядку сортировки таблицы для большей гибкости. Затем вы можете использовать любой метод, который использует компаратор для сортировки,поиска и т. д. Чтобы создать компаратор, я расширил это ComparatorChain класс из общих коллекций apache, чтобы легко выполнять сортировку нескольких столбцов. Похоже на то.
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's 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's 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, поэтому это не будет необходимо в будущем.
вы также можете использовать SortedList
.
SortedList<MatchTableBean> tableItems = new SortedList<>(
observableList, Comparator.comparing(MatchTableBean::isMarker).reversed().thenComparing(MatchTableBean::getQueryRT));
tableItems.comparatorProperty().bind(table.comparatorProperty());
table.setItems(tableItems);
таким образом таблица сортируется, даже если содержимое изменяется или полностью заменяется.