...其中
T
是 TableView
的泛型类型。
到目前为止,我正在实现一个包含三列的文件列表视图。每个类型
java.nio.file.Path
。对于名称列,我编写了一个 Comparator<Path>
,它按目录优先且不区分大小写对文件进行排序。另外两个比较器按上次修改时间和文件大小排序。为此,他们在 long
字段上进行比较。
但是列的
comparatorProperty
是基于 Comparator<String>
的。我认为,根据显示的文本进行排序......
所以我必须找到一种方法,将标题单击排序功能与
TableView
的类型一起使用?
创建
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.
虽然@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();
}
}
}