【问题标题】:Java FX table column sorting with Comparator does not work使用 Comparator 的 Javafx 表列排序不起作用
【发布时间】:2013-09-04 05:59:27
【问题描述】:

在 Java FX 中,我想在排序后的 TableView 中显示此模型:

   public class ProfilZuordnungTableRowModel {
    private int id;
    private double kundenwert;
    private String kundenwertFormatted;
    private BooleanProperty selected; }

我想将表格列排序与“Kundenwert”列集成。 显示的值应该是属性“kundenwertFormatted”(字符串),并且应该使用属性“kundenwert”(双精度)进行排序。

所以我写了一个比较器:

class ProfilZuordnungTableRowModelComparator implements Comparator<ProfilZuordnungTableRowModel> {

    @Override
    public int compare(ProfilZuordnungTableRowModel t, ProfilZuordnungTableRowModel t1) {
         return t.getKundenwert() < t1.getKundenwert() ? -1 : t.getKundenwert() == t1.getKundenwert() ? 0 : 1;
    }
}

据我了解,该比较器应按以下方式使用:

    TableColumn kundenwertColumn = new TableColumn();
    kundenwertColumn.setText("Kundenwert");

    kundenwertColumn.setCellValueFactory(new PropertyValueFactory("kundenwertFormatted"));
    kundenwertColumn.setComparator(new ProfilZuordnungTableRowModelComparator());

但当尝试按“Kundenwert”列排序时,出现以下异常:

java.lang.ClassCastException: java.lang.String cannot be cast to model.ProfilZuordnungTableRowModel
    at dialog.TableCellFactorySample$ProfilZuordnungTableRowModelComparator.compare(TableCellFactorySample.java:53)

指向这条线:

kundenwertColumn.setComparator(new ProfilZuordnungTableRowModelComparator());

有什么想法吗?

【问题讨论】:

  • 你为什么要一个kundenwert和一个kundenwertFormatted?我认为它们是多余的,格式化应该由 UI 完成,而不是模型。

标签: java sorting javafx comparator


【解决方案1】:

您的问题可以通过在显示Kundenwert 的列中使用CellFactory 来解决。这样您就不需要模型中的 kundenwertFormatted 字段,因为格式化将由单元工厂完成:

public class KundenwertCellFactory implements Callback<TableColumn<ProfilZuordnungTableRowModel, Double>, TableCell<ProfilZuordnungTableRowModel, Double>> {

    public TableCell<ProfilZuordnungTableRowModel, Double> call(TableColumn<ProfilZuordnungTableRowModel, Double> param) {
        TableCell<ProfilZuordnungTableRowModel, Double> cell = new TableCell<ProfilZuordnungTableRowModel, Double>() {

            @Override
            public void updateItem(final Double item, boolean empty) {
                if (item != null) {
                    setText(item.toString()); // you can format your value here
                }
            }
        };
        return cell;
    }
}

然后,您可以创建比较器来比较 kundenwert 是双精度:

public class KundenwerComparator implements Comparator<Double> {

    public int compare(Double o1, Double o2) {
        return o1 < o2 ? -1 : o1 == o2 ? 0 : 1;

    }

}

最后,您可以按如下方式设置您的列:

TableColumn<ProfilZuordnungTableRowModel, Double> kundenwertColumn = new TableColumn<ProfilZuordnungTableRowModel, Double>();
kundenwertColumn.setText("Kundenwert");

kundenwertColumn.setCellValueFactory(new PropertyValueFactory<ProfilZuordnungTableRowModel, Double>("kundenwert"));
kundenwertColumn.setComparator(new KundenwerComparator());
kundenwertColumn.setCellFactory(new KundenwertCellFactory());

请注意,我使用了类型参数,因为 TableColumn(及其伙伴)是通用的。

【讨论】:

    【解决方案2】:

    您的 kundenwertColumn 比较器应该实现一个字符串比较器。就像

    class KundenwertFormattedComparator implements Comparator<String> {
        @Override
        public int compare(String t, String t1) {
             return getKundenwertFromFormatted(t) < getKundenwertFromFormatted(t1)  ? -1 : getKundenwertFromFormatted(t) == getKundenwertFromFormatted(t1) ? 0 : 1;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多