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

时间:2016-04-19 15:56:40

标签: java javafx-2

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

谢谢

4 个答案:

答案 0 :(得分:0)

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

column.sortTypeProperty().addListener( new ChangeListener<javafx.scene.control.TableColumn.SortType>() {
        @Override
        public void changed(final ObservableValue<? extends javafx.scene.control.TableColumn.SortType> 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<ActionEvent>() {
        @Override
        public void handle(ActionEvent arg0) {
            if (column.getSortType()==SortType.DESCENDING) {
                column.setSortType(SortType.ASCENDING);
            }
        }
    });
column.setGraphic(columnHeader);

答案 1 :(得分:0)

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

public class MyTableView<S>  extends TableView {
    private int countHeaderClick = -1 ;

    @Override
    public void sort(){
        final ObservableList<? extends TableColumn<S,?>> 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{
           <what ever you want to perform>
        }
}

希望它有所帮助。

答案 2 :(得分:0)

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

// global variables
TableView<Object> 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);
      }
    }
  });
}

答案 3 :(得分:0)

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

TableColumn<?,?> aColumnThatMustAlwaysBeSorted = ...;

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

getSortOrder().add(aColumnThatMustAlwaysBeSorted);

当转换点击多列进行排序时的行为最初看起来有点不寻常,因为点击另一列时总是排序&#39;列将成为第二个排序索引,任何其他列将在其后追加。如果用户希望它在索引的下方进一步向下移动,那么请点击“始终排序”&#39;列将再次强制将其作为最后一个排序索引附加。