2012-06-19 100 views
13

我有一個與TreeView關聯的TableView。每次選擇TreeView中的節點時,TableView都會刷新不同的數據。Javafx:在TableView中重新排序列

我能夠排序TableView中的任何列,只需按相應的列標題。這工作正常。

但是:當我在樹視圖中選擇不同的節點時,儘管列標題一直顯示爲已排序。數據不是。

有沒有一種方法可以通過編程實現每次數據更改時用戶所做的排序順序?

+0

未來的讀者:!保存自己一些時間和[向下滾動](http://stackoverflow.com/a/29743777/309308) –

回答

15

好吧,我發現如何去做。我將在這裏總結一下它的情況下,它是有用的人:

之前更新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 
     } 

我沒有考慮到在排序中有多個列的可能性,但這對於這些信息很簡單。

+0

'rooms.getSortOrder()的isEmpty()'會比'rooms.getSortOrder()。size()> 0'更優雅。此外,您的解決方案只保留一個排序列,而不是所有列。 – glglgl

+0

這種做法已經嘗試過,但有一個問題正在發生 https://stackoverflow.com/questions/46160528/exception-after-retaining-sorting-column-of-tableview-in-javafx –

6

如果您的TableView沒有被重新初始化,你也可以做到以下幾點:

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

fornacif作品的例子,但如果有一個以上的排序順序(嘗試在第二列按住Shift鍵單擊創建二級排序順序)。

要做到對所有列進行重新排序,你需要做這樣的事情:

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

當我試過這段代碼時,它顯示錯誤部分ArratList <>(roomTable.getSortOrder());它正在工作,當我使用ArratList >(roomTable.getSortOrder()); 你能解釋我的原因嗎 – learner

+0

我認爲<>語法只適用於以後的Java版本,你必須使用Java 6或7? –

2

馬可雅各布的回答是好於大多數情況,但我發現,我需要建立一個匹配比較表排序順序更靈活。然後,您可以使用任何需要比較器進行排序,搜索等的方法。爲了創建比較器,我從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'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中的表格排序會有一些改進,所以這在將來不是必需的。

11

我有同樣的問題,並發現該數據的更新後,你只需要調用函數排序()在表視圖:

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

表視圖知​​道對於這樣排序的列排序功能將按照想要的順序對新數據進行排序。 此函數僅在Java 8中可用。

3

如果使用TableView.setItems()方法,它似乎會重置TableView的幾個方面。保留TableView中的ObservableList,清除其內容,然後添加新項目。然後,TableView.sort()將仍然知道哪些列先前已排序並且可以工作。就像這樣:

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