Форматирование ячеек таблицы JavaFX

    TableColumn<Event,Date> releaseTime  = new TableColumn<>("Release Time");
    releaseTime.setCellValueFactory(
                new PropertyValueFactory<Event,Date>("releaseTime")
            );

Как я могу изменить формат releaseTime? На данный момент он вызывает простую строку toString для объекта Date.

Ответы на вопрос(8)

ми форматтер или конвертер.

    //from my model
    ObjectProperty<Date> valutaProperty;

    //from my view
    TableColumn<Posting, String> valutaColumn;

    valutaColumn.setCellValueFactory(
            cellData -> {
                  SimpleStringProperty property = new SimpleStringProperty();
                  property.bindBidirectional(cellData.getValue().valutaProperty,  new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN));
                  return property;
               });

tbColDataMovt.setCellFactory((TableColumn<Auditoria, Timestamp> column) -> {
    return new TableCell<Auditoria, Timestamp>() {
        @Override
        protected void updateItem(Timestamp item, boolean empty) {
            super.updateItem(item, empty);
            if (item == null || empty) {
                setText(null);
            } else {
                setText(item.toLocalDateTime().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));
            }
        }
    };
});

import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.util.Callback;

public interface AbstractConvertCellFactory<E, T> extends Callback<TableColumn<E, T>, TableCell<E, T>> {

    @Override
    default TableCell<E, T> call(TableColumn<E, T> param) {
        return new TableCell<E, T>() {
            @Override
            protected void updateItem(T item, boolean empty) {
                super.updateItem(item, empty);
                if (item == null || empty) {
                    setText(null);
                } else {
                    setText(convert(item));
                }
            }
        };
    }

    String convert(T value);        
}

И его пример использования:

TableColumn<Person, Timestamp> dateCol = new TableColumn<>("employment date");
dateCol.setCellValueFactory(new PropertyValueFactory<>("emploumentDateTime"));    
dateCol.setCellFactory((AbstractConvertCellFactory<Person, Timestamp>) value -> new SimpleDateFormat("dd-MM-yyyy").format(value));

ни одно из приведенных выше решений не является действительным: если вы преобразуете свою Date в String и покажите ее таким образом в TableView; таблица будет сортировать как таковую (так неправильно).

Решением, которое я нашел, было создание подкласса класса Date для переопределения метода toString (). Здесь есть предостережение: TableView использует java.sql.Date вместо java.util.Date; так что вам нужно подкласс первого.

import java.text.SimpleDateFormat;

public class CustomDate extends java.sql.Date {

    public CustomDate(long date) {
        super(date);
    }

    @Override
    public String toString() {
        return new SimpleDateFormat("dd/MM/yyyy").format(this);
    }
}

Таблица будет вызывать этот метод для печати даты.

Конечно, вам также необходимо изменить свой класс Date в объявлении TableColumn на новый подкласс:

@FXML
TableColumn<MyObject, CustomDate> myDateColumn;

То же самое, когда вы присоединяете атрибут объекта к столбцу таблицы:

myDateColumn.setCellValueFactory(new PropertyValueFactory< MyObject, CustomDate>("myDateAttr"));

И, наконец, для ясности, вот как вы объявляете метод получения в своем классе объектов:

public CustomDate getMyDateAttr() {
    return new CustomDate(myDateAttr.getTime()); //myDateAttr is a java.util.Date           
}

Мне потребовалось некоторое время, чтобы понять это из-за того, что он использует java.sql.Date за кулисами; так что, надеюсь, это сэкономит время другим людям!

орно используемого средства форматирования столбцов, которое принимает любыеjava.text.Format, Это сокращает количество стандартного кода ...

private class ColumnFormatter<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> {
    private Format format;

    public ColumnFormatter(Format format) {
        super();
        this.format = format;
    }
    @Override
    public TableCell<S, T> call(TableColumn<S, T> arg0) {
        return new TableCell<S, T>() {
            @Override
            protected void updateItem(T item, boolean empty) {
                super.updateItem(item, empty);
                if (item == null || empty) {
                    setGraphic(null);
                } else {
                    setGraphic(new Label(format.format(item)));
                }
            }
        };
    }
}

Примеры использования

birthday.setCellFactory(new ColumnFormatter<Person, Date>(new SimpleDateFormat("dd MMM YYYY")));
amplitude.setCellFactory(new ColumnFormatter<Levels, Double>(new DecimalFormat("0.0dB")));
 13 сент. 2018 г., 11:19
но какое свойство это использовать? в вашем образце нет имени свойства.

dateAddedColumn.setCellValueFactory(
   new Callback<TableColumn.CellDataFeatures<Film, String>, ObservableValue<String>>() {
      @Override
      public ObservableValue<String> call(TableColumn.CellDataFeatures<Film, String> film) {
         SimpleStringProperty property = new SimpleStringProperty();
         DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
         property.setValue(dateFormat.format(film.getValue().getCreatedDate()));
         return property;
      }
   });

Однако - этоlot проще в Java 8, используя выражения Lamba:

dateAddedColumn.setCellValueFactory(
   film -> {
      SimpleStringProperty property = new SimpleStringProperty();
      DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
      property.setValue(dateFormat.format(film.getValue().getCreatedDate()));
      return property;
   });

Спешите с этим оракулом выпуска Java 8!

 01 сент. 2015 г., 12:28
Это прекрасно работает для первоначального заполнения таблицы ... если свойство даты в модели изменяется позже, чем SimpleStringProperty, не отправляет уведомление, и таблица не обновляется.
Решение Вопроса


https://stackoverflow.com/a/10149050/682495
https://stackoverflow.com/a/10700642/682495
Хотя вторая ссылка оListCellта же логика полностью применима кTableCellс тоже.

Постскриптум Тем не менее, если вам нужен пример кода, пожалуйста, приложите здесь.

(Я не уверен, что это подходящее место для такого ответа, но у меня проблема в JavaFX8, и некоторые вещи изменились, например, в пакете java.time)

Некоторые отличия от предыдущих ответов: Я сохраняю тип даты в столбце, поэтому мне нужно использовать и cellValueFactory, и cellFactory. Я делаю универсальный метод многократного использования для генерации cellFactory для всех столбцов даты. Я использую дату java 8 для пакета java.time! Но метод может быть легко переопределён для java.util.date.

 @FXML
 private TableColumn<MyBeanUi, ZonedDateTime> dateColumn;

@FXML
public void initialize () {
  // The normal binding to column 
  dateColumn.setCellValueFactory(cellData -> cellData.getValue().getCreationDate());

  //.. All the table initialisation and then
  DateTimeFormatter format = DateTimeFormatter .ofLocalizedDate(FormatStyle.SHORT);
  dateColumn.setCellFactory (getDateCell(format));

}

public static <ROW,T extends Temporal> Callback<TableColumn<ROW, T>, TableCell<ROW, T>> getDateCell (DateTimeFormatter format) {
  return column -> {
    return new TableCell<ROW, T> () {
      @Override
      protected void updateItem (T item, boolean empty) {
        super.updateItem (item, empty);
        if (item == null || empty) {
          setText (null);
        }
        else {
          setText (format.format (item));
        }
      }
    };
  };
}

Преимущества в том, что:

The column is typed with a "java8 Date" to avoid the sort problem evoqued by @Jordan The method "getDateCell" is generic and can be used as an util function for all Java8 Time types (Local Zoned etc.)

Ваш ответ на вопрос