2012-06-19 58 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();