테이블 뷰는 정렬에서 맨 아래 행 (합계)을 제외합니다
문제
단순 테이블보기 (Java FX 2.0,하지만 문제가 상당히 일반적인 일반적인 정렬 기능이 있다고 가정합니다).그러나 테이블은 마지막 줄에 총계가 있으므로 정렬 알고리즘에서 그 마지막 줄을 제외하고 싶습니다.
전체 행에 대한 별도의 테이블 만들기 - 테이블 뷰에 전이가 없지만 조금 성가신 것 같습니다.나는 내 비교기를 구현하려고 시도했지만, 오름차순 및 내림차순으로 작동하는 것을 만들 수 있다고 생각하지 않는다.
해결책
JavaFX 8은 정렬 정책을 정의 할 수 있으며 문제가 더 쉽게 수정할 수 있습니다.합계가 포함 된 행이 TOTAL
입니다.
table.sortPolicyProperty().set(t -> {
Comparator<Row> comparator = (r1, r2) ->
r1 == TOTAL ? 1 //TOTAL at the bottom
: r2 == TOTAL ? -1 //TOTAL at the bottom
: t.getComparator() == null ? 0 //no column sorted: don't change order
: t.getComparator().compare(r1, r2); //columns are sorted: sort accordingly
FXCollections.sort(t.getItems(), comparator);
return true;
});
. 다른 팁
Lolsvemir의 답변을 기반으로 사용자 정의 비교기가있는 "전체"를 성공적으로 구현합니다.
C 럼의 SortTypeProperty로 비교기를 설정합니다.
col.setComparator(new BigDecimalColumnComparator(col.sortTypeProperty()));
사용자 정의 비교기 :
public class BigDecimalColumnComparator implements Comparator<BigDecimal> {
private final ObjectProperty<TableColumn.SortType> sortTypeProperty;
public BigDecimalColumnComparator(ObjectProperty<TableColumn.SortType> sortTypeProperty) {
this.sortTypeProperty = sortTypeProperty;
}
@Override
public int compare(BigDecimal o1, BigDecimal o2) {
TableColumn.SortType sortType = sortTypeProperty.get();
if (sortType == null) {
return 0;
}
if (o1 instanceof TotalBigDecimal) {
if (sortType == TableColumn.SortType.ASCENDING) {
return 1;
} else {
return -1;
}
} else if (o2 instanceof TotalBigDecimal) {
if (sortType == TableColumn.SortType.ASCENDING) {
return -1;
} else {
return 1;
}
}
return o1.compareTo(o2);
}
}
. 및 비교기의 비교 () 메소드에서 항상 0을 반환하면?그것은 모든 요소가 "동일하다"및 장소의 스와핑이 없어야 함을 의미합니다.
나는 테이블에서 볼 수있는 많은 행을 위해 셀 팩토리를 호출하는 테이블 뷰 속성으로 인해 TableView.setItems () 메서드가 설정 한 목록의 크기만큼 셀 팩토리에 대해 셀 팩토리를 호출하는 테이블 뷰 속성 때문입니다. IMO가 필요로하는 모든 열에 대해 셀 팩토리로 요약 값을 직접 설정하는 것이 좋습니다.
여기에 그러한 셀 팩토리 클래스의 간단한 예입니다.
public class LocalDateTableCell<T> implements
Callback<TableColumn<T, LocalDate>, TableCell<T, LocalDate>> {
@Override
public TableCell<T, LocalDate> call(TableColumn<T, LocalDate> p) {
TableCell<T, LocalDate> cell = new TableCell<T, LocalDate>() {
@Override
protected void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
} else {
setText(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
.format(item));
}
if (getTableView().getItems().size() == getIndex())
setText("Test"); // This shows in the summary row
}
};
return cell;
}
}
.
이 접근 방식의 장점은 그러한 행이 모든 것을 정렬하는 것 (테이블 항목 목록에 있지 않기 때문에)이 아니며 선택할 수 없습니다. 또한 무시 무시할 수있는 TableRow 팩토리는 전체 요약 행을 위해 다른 배경색을 설정하고 다른 행과 구별하는 것이 쉽습니다.
그러나 테이블 뷰 스크롤 구현이 추가 행을 모르고 뷰포트 하단의 항목 목록에서 마지막 행으로 만 스크롤 할 수 있으므로이 추가 행이 표시되지 않습니다. 다음 예제와 같이 TableViewskin.getItemCount () 메서드를 재정의하여 해결할 수 있습니다. 테이블 뷰 자체를 재정의 할 필요는 없지만 그러한 테이블을 자주 사용하는 경우 권장됩니다.
public class MyTableViewSkin<T> extends TableViewSkin<T> {
private TableView<T> tableView;
public MyTableViewSkin(final TableView<T> tableView) {
super(tableView);
this.tableView = tableView;
}
@Override
public int getItemCount() {
return tableView.getItems() == null || tableView.getItems().size() == 0 ?
0 : tableView.getItems().size() + 1;
}
}
public class MyTableView<S> extends TableView<S> {
public MyTableView() {
super();
setSkin(new MyTableViewSkin<>(this));
}
}
.
이것은 해킹처럼 보이지만 매력처럼 작동합니다.