TableView исключить нижнюю строку (итого) из сортировки - PullRequest
3 голосов
/ 14 марта 2012

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

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

Ответы [ 4 ]

3 голосов
/ 11 марта 2013

Основываясь на ответе Лолсвемира, я успешно реализую «ИТОГО» с помощью специального компаратора.Я установил компаратор с помощью столбца 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);
    }
}
3 голосов
/ 14 января 2014

С помощью 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;
});
2 голосов
/ 14 марта 2012

А если вы всегда возвращаете 0 в методе CompareTo () вашего Comparator?Это означает, что все элементы "одинаковы" и не должно происходить перестановка мест?

1 голос
/ 08 октября 2014

У меня была та же проблема, и из-за свойства TableView вызывать фабрику ячеек для стольких строк, сколько видно в таблице, а не только для индексов строк вплоть до размера списка, установленного методом 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 легко установить другой цвет фона для всей строки сводки и отличить его от других строк.

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...