TableView исключить нижний ряд (всего) от сортировки

StackOverflow https://stackoverflow.com//questions/9699948

Вопрос

У меня простая табличка (Java fx 2.0, но я полагаю, проблема довольно общего), которая получает функцию сортировки по умолчанию.Однако таблица имеет всего в его последней строке, поэтому я хотел бы исключить эту последнюю строку из алгоритма сортировки.

Я нашел решение для качания JTable, который состоит в Создание отдельной таблицы для полной строки - это было бы транспонировано в таблицу, но кажется немного громоздким.Я попытался реализовать свой собственный компаратор, но я не думаю, что можно создать один, который будет работать в заказах по возрастанию, так и по убыванию.

Это было полезно?

Решение

с 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, я успешно реализует «всего» с пользовательским компаратором. Я установил компаратор с столбцом 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 в методе сравнения () вашего компаратора?Это означает, что все элементы «одинаковы», и не должно возникнуть замена мест?

У меня была такая же проблема, и, благодаря свойству TablView, чтобы позвонить в ячейку завод, как можно больше рядов, как видно в таблице, и не только для индексов строки до размера списка, установленного методом TableView.SetiTems (), ИМО лучше установить сводную ценность непосредственно по ячейке для каждого столбца, который должен иметь его.

Вот простой пример такого клеточного заводского класса:

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;
  }
}
.

Преимущества этого подхода заключаются в том, что такой строк не участвует в сортировке вообще (потому что он не находится в списке элементов таблицы), а не выбирается. Кроме того, с переоцененной фабрикой стоала легко установить различный цвет фона для цельного сводка и отличить его от других рядов.

Однако этот дополнительный ряд не будет видимым при прокрутке, потому что реализация прокрутки TableView не знает для дополнительной строки и будет прокручивать только в последнюю строку из списка элементов в нижней части Viewport. Это может быть решено путем переопределения метода TableViewskin.geteTemcount (), как в следующем примере. Переопределение самой таблицы не нужно, но рекомендуется, если такая таблица используется часто.

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));
  }
}
.

Это может выглядеть как хак, но работает как очарование.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top