对TableView列进行排序:绕过“未排序”模式的方法

这是我希望得到答案的另一个JavaFX问题。 目前,当您在TableView中对列进行排序时,您将从第一次单击开始按升序排序,从第二次单击开始降序,在第三次单击时,它不执行任何操作,排序箭头将消失。 据我所知,第三种排序模式应该将列返回到先前的未排序状态。 我知道由于受欢迎的请求,最近添加了这种模式,但有没有办法完全绕过它? 也就是说,在第一次点击时我们按升序排序,在第二次点击时我们按降序排序,就是这样,第三次点击将再次按升序排序? 是否有捷径可寻?

谢谢

您是否尝试将ChangeListener添加到列中?

column.sortTypeProperty().addListener( new ChangeListener() { @Override public void changed(final ObservableValue observable, final javafx.scene.control.TableColumn.SortType oldValue, final javafx.scene.control.TableColumn.SortType newValue) { if (oldValue==javafx.scene.control.TableColumn.SortType.DESCENDING) { column.sortTypeProperty().set(javafx.scene.control.TableColumn.SortType.ASCENDING); } } }); 

编辑 :由于上面的代码不起作用(见评论)我建议如下:

 Button columnHeader = new Button("column name"); columnHeader.setOnAction(new EventHandler() { @Override public void handle(ActionEvent arg0) { if (column.getSortType()==SortType.DESCENDING) { column.setSortType(SortType.ASCENDING); } } }); column.setGraphic(columnHeader); 

以下是此问题的快速而肮脏的解决方案:

 // global variables TableView table; TableColumn currentSortColumn; void initialize() { // set default sort column currentSortColumn = table.getColumns().get(0); table.getSortOrder().setAll(currentSortColumn); // update current sort column after sorting changes for (TableColumn column : table.getColumns()) { column.sortTypeProperty().addListener((observable, oldValue, newValue) -> { currentSortColumn = column; }); } // if table loses comparator restore the sort order! table.comparatorProperty().addListener((observable, oldValue, newValue) -> { if (newValue == null) { table.getSortOrder().setAll(currentSortColumn); if (currentSortColumn.getSortType().equals(TableColumn.SortType.ASCENDING)) { currentSortColumn.setSortType(TableColumn.SortType.DESCENDING); } else { currentSortColumn.setSortType(TableColumn.SortType.ASCENDING); } } }); } 

从当前的JFX API开始,唯一的解决方案如下:创建一个名为MyTableView的新类,它扩展了TableView ,现在您可以根据自己的方便覆盖现有的sort()方法。 在第三次单击时,列表sortOrder将不返回任何内容,其大小将为零。 此时,如果是第三次点击,您可以跟踪计数。 请参考附带的小代码。

 public class MyTableView extends TableView { private int countHeaderClick = -1 ; @Override public void sort(){ final ObservableList> sortOrder = getSortOrder(); countHeaderClick++ ; super.sort(); if(sortOrder.size() > 0) { columnClicked = sortOrder.get(0).getId(); // name of column clicked strSortTypeValue = sortOrder.get(0).getSortType().toString(); // ascending or descending }else{  } } 

希望它有点帮助。

TableView上的sortOrder属性负责保存显示为已排序的列。 考虑到这一点,要确保列始终排序,可以观察到此属性,并且只要发现不包含列(例如“第三次单击”),就可以通过侦听器将其添加回来,如下所示:

 TableColumn aColumnThatMustAlwaysBeSorted = ...; tableView.getSortOrder().addListener( (ListChangeListener>)observable -> { if( !tableView.getSortOrder().contains(aColumnThatMustAlwaysBeSorted) ){ aColumnThatMustAlwaysBeSorted.setSortType(SortType.ASCENDING); tableView.getSortOrder().add(aColumnThatMustAlwaysBeSorted); } }); getSortOrder().add(aColumnThatMustAlwaysBeSorted); 

移位单击多列进行排序时的行为最初看起来有点不寻常,因为在单击另一列时,“始终排序”列将成为第二个排序索引,并且任何其他列将在其后追加。 如果用户想要在索引的下方进一步向下移动,则单击“always-sorted”列将再次强制将其作为最后一个排序索引追加。