2012-07-10 74 views
8
TableColumn<Event,Date> releaseTime = new TableColumn<>("Release Time"); 
    releaseTime.setCellValueFactory(
       new PropertyValueFactory<Event,Date>("releaseTime") 
      ); 

如何更改releaseTime的格式?目前它在Date對象上調用一個簡單的toString。JavaFX Table Cell格式化

回答

5

我需要最近做 -

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

但是 - 這是Java 8 很多更容易使用蘭巴表達式:

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發佈神諭!

+1

這工作正常最初填充表...如果在模型中的日期屬性改變比SimpleStringProperty後不發出通知,而不是更新的表。 – Adam 2015-09-01 10:28:12

7

如果要保留TableColumn的排序功能,上述解決方案都不是有效的:如果將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); 
    } 
} 

該表將調用該方法以打印日期。

當然,你需要的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;所以希望這會節省其他人一些時間!

4

更新爲Java FX8:

(我不知道它是這個問題的答案的好地方,但我在JavaFX8得到了問題,有些事情已經改變,像java.time包)

與以前的答案有一些區別: 我在列上保留日期類型,所以我需要同時使用cellValueFactory和cellFactory。 我做了一個通用的可重用方法來爲所有日期列生成cellFactory。 我使用java.time包的java 8日期!但是該方法可以很容易地爲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)); 
     } 
     } 
    }; 
    }; 
} 

的優點是:

  • 該柱鍵入一個「java8日期」,以避免由@Jordan evoqued排序問題
  • 的方法「getDateCell」是通用的,並且可以是用作所有Java8時間類型的實用函數(本地已分區等)
4

我推薦使用Java泛型創建可重用的列格式化程序,該程序可以使用任何java.text.Format。這減少了樣板代碼量......使用

birthday.setCellFactory(new ColumnFormatter<Person, Date>(new SimpleDateFormat("dd MMM YYYY"))); 
amplitude.setCellFactory(new ColumnFormatter<Levels, Double>(new DecimalFormat("0.0dB"))); 
2

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

例子這是我做的,我的工作完美。

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

一個通用的解決方案可能是那樣簡單:

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