JavaFx - TableView:如何使用自定义比较器<T>进行排序?

问题描述 投票:0回答:2

...其中

T
TableView
的泛型类型。

到目前为止,我正在实现一个包含三列的文件列表视图。每个类型

java.nio.file.Path
。对于名称列,我编写了一个
Comparator<Path>
,它按目录优先且不区分大小写对文件进行排序。另外两个比较器按上次修改时间和文件大小排序。为此,他们在
long
字段上进行比较。

但是列的

comparatorProperty
是基于
Comparator<String>
的。我认为,根据显示的文本进行排序......

所以我必须找到一种方法,将标题单击排序功能与

TableView
的类型一起使用?

java sorting javafx tableview javafx-8
2个回答
2
投票

创建

TableColumn
时使用了错误的类型参数。如果您创建
TableColumn<Path, Path>
,则可以为该列指定
Comparator<Path>
。同样
TableColumn<Path, FileTime>
TableColumn<Path, Long>
使用
Comparator<FileTime>
Comparator<Long>

来自文档:

Class TableColumnBase<S,T>
Type Parameters:
S - The type of the UI control (e.g. the type of the 'row').
T - The type of the content in all cells in this table column.

0
投票

虽然@Christian Rädel 的答案是正确的,但它没有显示如何实现它。

我正在寻找这个实现,因为我想按“排序值”而不是“显示值”对列进行排序。

例如,“姓名”字段优选显示为“名字姓氏”,但您希望该字段按“姓氏、名字”排序。 此外,您可能有一个复合为“TagName [版本]”的列,并且您希望版本按数字顺序而不是按字母顺序排序。

public class SomeView extends SplitPane
{   
    ToolBar searchBar = new ToolBar();
    TextField searchField = new TextField();

    TableView<Widget> widgets = new TableView<Widget>();

    TableColumn<Widget, String> number_col;
    TableColumn<Widget, WidgetTitle> title_col;
    TableColumn<Widget, WidgetName> name_col;
    TableColumn<Widget, WidgetVersion> version_col;


    public SomeView() 
    {   
        super();

        setOrientation(Orientation.VERTICAL);
        setDividerPositions(0.05);

        searchField.setPrefWidth(200);
        searchField.setMaxWidth(360);
        searchField.setMinWidth(80);
        searchField.setPrefColumnCount(360);
        searchField.setText("");

        searchBar.getItems().add(searchField);

        number_col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Widget, String>, ObservableValue<String>>() {
            @Override public ObservableValue<String> call(TableColumn.CellDataFeatures<Widget, String> p) {
                return new ReadOnlyObjectWrapper( (1 + widgets.getItems().indexOf(p.getValue())) + "");
            }
        });
        number_col.setSortable(false);
        number_col.setPrefWidth(60);
        number_col.setMinWidth(30);

        title_col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Widget, WidgetTitle>, ObservableValue<WidgetTitle>>() {
            public ObservableValue<WidgetTitle> call(TableColumn.CellDataFeatures<Widget, WidgetTitle> p) {
                return new ReadOnlyObjectWrapper<WidgetTitle>( new WidgetTitle(p.getValue()) );
            }
        });
    
        name_col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Widget, WidgetName>, ObservableValue<WidgetName>>() {
            public ObservableValue<WidgetName> call(TableColumn.CellDataFeatures<Widget, WidgetName> p) {
                return new ReadOnlyObjectWrapper<WidgetName>( new WidgetName(p.getValue()) );
            }
        });
        version_col.setMinWidth(80.0);
        version_col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Widget, WidgetVersion>, ObservableValue<WidgetVersion>>() {
            public ObservableValue<WidgetVersion> call(TableColumn.CellDataFeatures<Widget, WidgetVersion> p) {     
                return new ReadOnlyObjectWrapper<WidgetVersion>( new WidgetVersion(p.getValue()) );
            }
        });
    
       widgets.getColumns().setAll(number_col, title_col, name_col, version_col, date_col);

       ObservableList<Widget> widgetList = widgets.geItems();
       widgetList.addAll( /* get List<Widget> */ );

       FilteredList<Widget> filtered = new FilteredList<>(widgetList);
        searchField.textProperty().addListener((obsv, ovalue, nvalue) -> {
            filtered.setPredicate( awidget -> {
                if (null == nvalue || nvalue.isEmpty())
                    return true;
                String lcfilter = nvalue.toLowerCase();
                if (awidget.getName().toLowerCase().contains(lcfilter)
                    || awidget.getTitle().toLowerCase().contains(lcfilter))
                    return true;
               return false;
           });
       });

        SortedList<Widget> sorted = new SortedList<>(filtered);
        widgets.setItems(sorted);
        sorted.comparatorProperty().bind(widgets.comparatorProperty());

        getItems().addAll(searchBar, widgets);
    }

    // customize the sorting of Title Column
    private class WidgetTitle implements Comparable<WidgetTitle>
    {
        Widget widget;

        WidgetTitle(Widget title)
        {
            widget = title;
        }

        @Override
        public int compareTo(WidgetTitle obj)
        {
            return widget.getSortTitle().compareTo(obj.widget.getSortTitle());
        }

        @Override
        public String toString()
        {
            return widget.getTitle();
        }
    }

    // customize the sorting of Name Column
    private class WidgetName implements Comparable<WidgetName>
    {   
        Widget widget;

        WidgetName(Widget name)
        {
            widget = name;
        }

        @Override
        public int compareTo(WidgetName obj)
        {
            return widget.getNameSort().compareTo(obj.widget.getNameSort());
        }

        @Override
        public String toString()
        {
            return widget.getName();
        }
    }

    // customize the sorting of Version Column
    private class WidgetVersion implements Comparable<WidgetVersion>
    {
        Widget widget;

        WidgetVersion(Widget version)
        {
            widget = version;
        }

        @Override
        public int compareTo(WidgetVersion obj)
        {
            String ser1 = widget.getVersionName();
            String ser2 = obj.widget.getVersionName();

            if (null == ser1 && null != ser2)
                return -1;

            if (null != ser1 && null == ser2)
                return 1;

            int scompare = ser1.compareTo(ser2);
            return (0 == scompare)
                ? widget.getVersionIndex().compareTo(obj.widget.getVersionIndex()) : scompare;
        }

        @Override
        public String toString()
        {
            return widget.versionProperty().getValue();
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.