【问题标题】:Sorting TableView columns: a way to bypass an "unsorted" mode对 TableView 列进行排序:一种绕过“未排序”模式的方法
【发布时间】:2016-04-19 15:56:39
【问题描述】:

这是我希望得到答案的另一个 JavaFX 问题。目前,当您在 TableView 中对列进行排序时,您会从第一次单击获得升序,从第二次单击降序,第三次单击它什么也不做,排序箭头消失。我知道第三种排序模式应该将列返回到以前的未排序状态。我知道最近由于受欢迎的要求增加了这种模式,但是有没有办法完全绕过它?也就是第一次按升序排序,第二次按降序排序,就这样,第三次按升序排序?有没有简单的方法可以做到这一点?

谢谢

【问题讨论】:

  • 我试图找到一个解决方案,但我没有。如果您发现了黑客,请告诉我们!

标签: java javafx-2


【解决方案1】:

您是否尝试将 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);

【讨论】:

  • 这不起作用,因为如果用户每三次单击标题,则不会触发侦听器。
  • 好的,那么我能想到的唯一解决方案就是听每一次点击列。这可以通过设置列标题的图形来实现,例如 column.setGraphic(new Button("columnName"));并向此 Button 添加一个 ActionListener。
  • 您可以使用此信息编辑您的答案,因此我可以将其投票回 0。谢谢。
  • 我试了一下,但似乎逻辑缺少一些东西。排序类型设置得很好,但排序本身没有发生,列数据保持不变。
  • 你设置了 column.setSortable(true); 吗?
【解决方案2】:

这里有一个快速而肮脏的解决方案:

// 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】:

    对于当前的 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>
            }
    }
    

    希望对你有所帮助。

    【讨论】:

    • 不起作用。未知变量 - columnClicked, strSortTypeValue ...我猜这些可能是超类变量。但是在 JFX2 中 - 没有。
    【解决方案4】:

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

    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);
    

    Shift 单击多个列进行排序时的行为起初看起来有点不寻常,因为单击另一列时,“始终排序”列将成为第二个排序索引,并且任何其他列都将附加在它之后。如果用户希望它在索引的下方进一步下降,则单击“始终排序”列将再次强制将其作为最后一个排序索引附加。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      • 2017-03-06
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多