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

releaseTimeの形式を変更するにはどうすればよいですか?現時点では、Dateオブジェクトで単純なtoStringを呼び出しています。

4

9 に答える 9

10

TableColumnの並べ替え機能を保持したい場合は、上記の解決策はどれも有効ではありません。日付を文字列に変換し、TableViewにそのように表示する場合。テーブルはそれをそのようにソートします(とても間違っています)。

私が見つけた解決策は、toString()メソッドをオーバーライドするためにDateクラスをサブクラス化することでした。ただし、ここには注意点があります。TableViewはjava.util.Dateではなくjava.sql.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);
    }
}

テーブルは、日付を出力するためにそのメソッドを呼び出します。

もちろん、TableColumn宣言のDateクラスも新しいサブクラスに変更する必要があります。

@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を使用しているため、これを理解するのに少し時間がかかりました。うまくいけば、これは他の人の時間を節約するでしょう!

于 2015-02-26T15:21:23.000 に答える
8

Java FX8のアップデート:

(それがその答えに適しているかどうかはわかりませんが、JavaFX8で問題が発生し、java.timeパッケージなどのいくつかの変更があります)

以前の回答とのいくつかの違い:列に日付型を保持しているため、cellValueFactoryとcellFactoryの両方を使用する必要があります。すべての日付列のcellFactoryを生成するための一般的な再利用可能なメソッドを作成します。java.timeパッケージにjava8dateを使用しています!ただし、このメソッドは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));
        }
      }
    };
  };
}

利点は次のとおりです。

  • @Jordanによって引き起こされるソートの問題を回避するために、列は「java8Date」で入力されます
  • メソッド「getDateCell」は汎用であり、すべてのJava8時間タイプ(ローカルゾーンなど)のutil関数として使用できます。
于 2016-04-05T14:38:25.650 に答える
8

Javaジェネリックを使用して、任意のをとる再利用可能な列フォーマッタを作成することをお勧めします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")));
于 2016-08-16T05:24:39.763 に答える
6

私は最近これをする必要がありました-

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

ただし、Java8ではLamba式を使用する方がはるかに簡単です。

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

そのJava8リリースオラクルで急いでください!

于 2013-09-10T21:04:22.350 に答える
5

あなたはセルファクトリーを通してそれを達成することができます。
https://stackoverflow.com/a/10149050/682495
https://stackoverflow.com/a/10700642/682495を参照してください
。2番目のリンクは約ですListCellが、同じロジックがsにも完全に適用TableCellできます。

PSそれでもサンプルコードが必要な場合は、ここに添付してください。

于 2012-07-10T11:46:31.740 に答える
3

普遍的な解決策はそれと同じくらい簡単かもしれません:

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));
于 2017-12-03T04:59:18.760 に答える
2

これは私がしたことであり、私は完璧に働きました。

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")));
            }
        }
    };
});
于 2016-12-20T19:15:17.797 に答える
0

さまざまなタイプのプロパティを簡単にパイプ処理し、その間にフォーマッターまたはコンバーターを配置できます。

    //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;
               });
于 2017-12-23T10:33:37.800 に答える
0

クラスは別のStringConverterメカニズムです。

TextFieldTableCell次のようなコンストラクタがありますpublic TextFieldTableCell(StringConverter<T> converter)

...およびStringConvertersは、などのサブクラスで構成されLocalDateStringConverterます。デフォルトの実装は次のようになります。

new TextFieldTableCell( new LocalDateStringConverter() );

...これは悪いことではありませんが、パラメータなしでは、解析(メソッド)と。LocalDateStringConverterの両方に「dd / mm/yyyy」形式の日付が使用されます。ただし、またはを渡すことができるコンストラクターは他にもあります。fromString()toString()FormatStyleDateTimeFormatter

しかし、私の実験からは、無効な日付でスローされたものStringConverterをキャッチするのが難しいという点で、sは少し問題があります。DateTimeParseExceptionfromString()

StringConverterこれは、独自のクラスを作成することで解決できます。例:

class ValidatingLocalDateStringConverter extends LocalDateStringConverter {
    boolean valid;

    @Override
    LocalDate fromString(String value) {
        valid = true;
        if (value.isBlank()) return null;
        try {
            // NB wants ISO
            return LocalDate.parse( value );
        } catch ( DateTimeParseException e) {
            valid = false;
        }
        return null;
    }

    @Override
    String toString( LocalDate date ){
        // NB returns ISO or the String "null" with null date value (!)
        String s = date.toString();
        return s.equals( 'null' )? '' : s;
    }
}

このソリューションを使用すると、表現StringConverterに関係なく、日付が時系列に従って並べ替えられます。String

于 2020-04-24T09:31:40.207 に答える