当前位置: 首页 > 知识库问答 >
问题:

JavaFX TableView在排序时忽略空单元格

段干跃
2023-03-14

当有空单元格时,我在对列进行排序时有问题。

我为我的codemed列创建了一个新的比较器:

codeMed.setComparator(new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {

            if (o1 == null)return -1;
            if (o2 == null) return -1;
            return o1 < o2 ? -1 : o1 == o2 ? 0 :1;
        }
    });

一开始,它似乎很管用:

if (codeMed.getSortType() == TableColumn.SortType.DESCENDING) {
    return (o1 != null ? o1 : Integer.MAX_VALUE) - (o2 != null ? o2 : Integer.MAX_VALUE);
} else if (codeMed.getSortType()==TableColumn.SortType.ASCENDING){
    return (o1 != null ? o1 : Integer.MIN_VALUE) - (o2 != null ? o2 : Integer.MIN_VALUE);
}
return 0;

非常感谢Jai,我修改您的代码只是因为我想将其用于两个不同的列:

Comparator<Integer> integerComparator = new Comparator<>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            final boolean isDesc = tabInfosPatient.getSortOrder().get(0).getSortType() == TableColumn.SortType.DESCENDING;
            if (o1 == null && o2 == null) return 0;
            else if (o1 == null) return isDesc ? -1 : 1;
            else if (o2 == null) return isDesc ? 1 : -1;
            else return Integer.compare(o1, o2);
        }
    };

共有1个答案

冷英光
2023-03-14

我很惊讶它竟然一次也管用。我认为这是一个很好的方法

codeMed.setComparator(new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return (o1 != null ? o1 : Integer.MAX_VALUE) - (o2 != null ? o2 : Integer.MAX_VALUE);
        }
    });

这将假定任何null值都被视为表示可能的最大int值。这将迫使它在升序排序的列中移动到列表的底部,如果它在降序排序的列中,则移动到列表的顶部。如果需要相反,请将integer.max_value切换到integer.min_value

你所做的不起作用,因为你违反了这一点:

public class Model {
    private final ObjectProperty<Integer> v = new SimpleObjectProperty<>();

    public Model(Integer v) {
        this.v.setValue(v);
    }

    public final ObjectProperty<Integer> vProperty() {
        return this.v;
    }

    public final Integer getV() {
        return this.vProperty().get();
    }

    public final void setV(final Integer v) {
        this.vProperty().set(v);
    }
}

ObservableList<Model> list = FXCollections.observableArrayList();
list.addAll(new Model(20), new Model(-30), new Model(null), new Model(10));

TableView<Model> tv = new TableView<>();
TableColumn<Model, Integer> tc = new TableColumn<>();
tc.setCellValueFactory(new PropertyValueFactory<>("v"));
tv.getColumns().add(tc);
tv.setItems(list);

Comparator<Integer> ascComparator = (o1, o2) ->
                                (o1 != null ? o1 : Integer.MAX_VALUE) - 
                                (o2 != null ? o2 : Integer.MAX_VALUE);

Comparator<Integer> descComparator = (o1, o2) ->
                                (o1 != null ? o1 : Integer.MIN_VALUE) - 
                                (o2 != null ? o2 : Integer.MIN_VALUE);

@SuppressWarnings("unchecked")
Comparator<Integer> defaultComparator = TableColumn.DEFAULT_COMPARATOR;

tc.comparatorProperty().bind(
        Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.ASCENDING))
                .then(ascComparator)
                .otherwise(
                        Bindings.when(tc.sortTypeProperty().isEqualTo(SortType.DESCENDING))
                                .then(descComparator)
                                .otherwise(defaultComparator)));

另外,我想指出的是,虽然使用integer.min_valueinteger.max_value大部分时间都可以工作,但整数下溢和溢出问题的风险要高得多,我不确定这是否是使用比较器和比较项的问题。

如果你想更安全,那么做一堆if-else:

Comparator<Integer> ascComparator = (o1, o2) -> {
    if (o1 == null && o2 == null) return 0;
    else if (o1 == null && o2 != null) return -1;
    else if (o1 != null && o2 == null) return 1;
    else return Integer.compare(o1, o2);
};

在看了您的尝试之后,我意识到这是有效的:

Comparator<Integer> comparator = (o1, o2) -> {
    final boolean isDesc = tc.getSortType() == SortType.DESCENDING;
    if (o1 == null && o2 == null) return 0;
    else if (o1 == null && o2 != null) return isDesc ? -1 : 1;
    else if (o1 != null && o2 == null) return isDesc ? 1 : -1;
    else return Integer.compare(o1, o2);
};
 类似资料:
  • 我目前有一个表,其中的项可以根据各种列进行排序。我的当前表有空行,允许在不使用任何外部控件(表外按钮)的情况下随时插入新项。 我还没有找到一个解决方案,允许我在忽略空单元格的情况下对给定的列进行排序(即空单元格应该始终保留在表的底部,而所有其他单元格都根据需要进行排序) 对此的任何帮助都将不胜感激。 谢谢。

  • 读取文件已支持 windows 系统,版本号大于等于 1.3.4.1; 扩展版本大于等于 1.2.7; PECL 安装时将会提示是否开启读取功能,请键入 yes; 测试数据准备 $config = ['path' => './tests']; $excel = new \Vtiful\Kernel\Excel($config); ​ // 写入测试数据 $filePath = $excel->f

  • 问题内容: 给定一个文件: 致电时,我获得: 换句话说,这不是正确的排序,它会删除/忽略空格!我希望这是它的行为,但是无论是否带有标志,它都会发生。 我想获得“正确”的排序: 我应该怎么做? 问题答案: 解决者: 从文档中: 警告:环境指定的语言环境会影响排序顺序。设置LC_ALL = C可获得使用本机字节值的传统排序顺序。 (至少适用于ASCII,不适用于UTF8)

  • 在MongoDB 2.6.5上使用mongo shell运行查询 问题是:。limit()似乎忽略了。排序()。 这是正常的行为吗?我不认为应该这样做,但我不确定。如果没有,有没有办法让它通过排序然后限制而不是限制然后排序来工作。 我正在运行以下查询 db。邮递查找({categories:{$in:[“101”]},位置:{$near:[1.310000,103.700000],$maxDist

  • 我正在使用Apache POI解析Excel。是否可以让Apache POI将空字符串视为null并忽略它们? 可能有excel表将数百万个单元格设置为文本,如下所示,导致所有单元格被Apache POI解释为空字符串。由于有数百万个空的字符串单元格,逐个单元格地检查会导致严重的性能问题: 无论如何,Apache POI是否可以忽略这些空字符串单元格,这样我们就不必逐个单元格地单独读取单元格来检查

  • 问题内容: 有没有一种方法告诉DB-Unit忽略应该比较行的顺序?我的问题是,我不知道将以什么顺序将行写入数据库,但是DB-Unit强迫我给出一个有序列表。 我想要dbunit做的是: 检查数据库中的行数与预期的数据集是否匹配(已解决:开箱即用 检查是否仅在结果集中找到每一行。(不解决) 有任何想法吗? 问题答案: 为我解决了这个问题。我正在对实际表和预期表的行进行排序。因此,我使用可以在期望表中