TreeViewに関連付けられたTableViewがあります。 TreeViewのノードが選択されるたびに、TableViewは異なるデータで更新されます。
対応する列ヘッダーを押すだけで、TableViewの任意の列を並べ替えることができます。それはうまくいきます。
しかし:ツリービューで別のノードを選択すると、列ヘッダーが並べ替えられた状態で表示され続けます。データはそうではありません。
データが変更されるたびにユーザーが作成した並べ替え順序をプログラムで適用する方法はありますか?
わかりました、私はそれを行う方法を見つけました。他の人に役立つ場合に備えて、ここで要約します。
前 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キーを押しながら2番目の列をクリックして、2番目の並べ替え順序を作成してください)。
すべての列で再ソートを行うには、次のようなことを行う必要があります。
List<TableColumn<Room, ?>> sortOrder = new ArrayList<>(roomTable.getSortOrder());
roomTable.getSortOrder().clear();
roomTable.getSortOrder().addAll(sortOrder);
TableView.setItems()メソッドを使用すると、TableViewのいくつかの側面がリセットされているように見えます。 TableViewのObservableListをそのままにして、その内容をクリアしてから、新しいアイテムを追加します。その後、TableView.sort()は、以前にソートされた列を引き続き認識し、機能します。このような:
tableView.getItems().clear();
tableView.getItems().addAll(newTableData);
tableView.sort();
ほとんどの場合、Marco Jakobの答えは適切ですが、柔軟性を高めるために、テーブルの並べ替え順序に一致するコンパレータを作成する必要があることがわかりました。次に、コンパレータを使用して並べ替えや検索などを行う任意のメソッドを使用できます。コンパレータを作成するために、ApacheのCommon-Collectionsの ComparatorChain クラスを拡張して、複数列の並べ替えを簡単に実行しました。こんな感じです。
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());
これを使用して、同じ並べ替えで複数のリストを並べ替えたり、バックグラウンドスレッドで並べ替えたり、リスト全体を使用せずに効率的な更新を行ったりします。Javafx8のテーブルの並べ替えにはいくつかの改善があると思うので、これは必要ありません。将来は。
SortedList
を使用することもできます。
SortedList<MatchTableBean> tableItems = new SortedList<>(
observableList, Comparator.comparing(MatchTableBean::isMarker).reversed().thenComparing(MatchTableBean::getQueryRT));
tableItems.comparatorProperty().bind(table.comparatorProperty());
table.setItems(tableItems);
このようにして、コンテンツが変更されたり完全に置き換えられたりした場合でも、テーブルが並べ替えられます。