Pregunta

Tengo una simple tabla (Java FX 2.0, pero supongo que el problema es bastante genérico) que obtiene la función de clasificación predeterminada.Sin embargo, la tabla tiene un total en su última línea, por lo que me gustaría excluir esa última línea desde el algoritmo de clasificación.

Encontré una solución para un swing jtable que consiste en creando una tabla separada para la fila total - Eso sería transponible a una mesa, pero parece un poco incómodo.He intentado implementar mi propio comparador, pero no creo que sea posible crear uno que funcione tanto en órdenes ascendentes como descendentes.

¿Fue útil?

Solución

Con Javafx 8, es posible definir una política de clasificación, y el problema es más fácil de solucionar.Suponiendo que la fila que contenga los totales sea 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;
});

Otros consejos

Basado en la respuesta de Lolsvemir I implementa exitosamente un "total" con un comparador personalizado. Establece el comparador con la clasificación de clasificación de la columna: col.setComparator(new BigDecimalColumnComparator(col.sortTypeProperty()));

Comparador personalizado:

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

¿Y si siempre devuelve 0 en el método compareco () de su comparador?¿Significa que todos los elementos "son iguales" y no debe haber intercambio de lugares?

Tuve el mismo problema y, debido a la propiedad de TableView para llamar a la fábrica de células para la fabricación de tantas filas, ya que son visibles en la tabla, y no solo para índices de filas hasta el tamaño de la lista establecida por TableView.setitems (). IMO Es mejor establecer el valor de resumen directamente por la fábrica de células para cada columna que necesita tenerla.

Aquí está el ejemplo simple de dicha clase de fábrica de células:

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

Las ventajas de este enfoque son que tal fila no está involucrada en la clasificación en absoluto (porque no está en la lista de elementos de la tabla) y no se puede seleccionar también. Además, con la fábrica de tablerow primordiando es fácil establecer un color de fondo diferente para la fila de resumen completa y para distinguirlo de otras filas.

Sin embargo, esta fila adicional no será visible mientras se desplaza hacia abajo porque la implementación de desplazamiento de TableView no se conoce para la fila adicional y se desplazará solo a la última fila de la lista de elementos en la parte inferior de la ventana. Que se puede resolver al anular el método TEJAVIEJIERSKIN.GETITEMCOUNT (), como en el siguiente ejemplo. La visualización de la tabla en sí misma no es necesaria, pero se recomienda si dicha tabla se usa a menudo.

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

Esto puede parecer un truco, pero funciona como un encanto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top