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

Làm cách nào để thay đổi định dạng của bản phát hành? Tại thời điểm này nó gọi một toString đơn giản trên đối tượng Date.Định dạng ô di động JavaFX

Trả lời

5

tôi cần phải làm điều này thời gian gần đây -

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

Tuy nhiên - đó là một nhiều dễ dàng hơn trong Java 8 sử dụng Lamba Expressions:

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

Nhanh lên với Java 8 phát hành oracle!

+1

Điều này hoạt động tốt khi ban đầu điền bảng ... nếu thuộc tính ngày trong mô hình thay đổi sau SimpleStringProperty không phát ra thông báo và bảng không được cập nhật. – Adam

7

Nếu bạn muốn duy trì khả năng phân loại của TableColumn của bạn, không có giải pháp nào ở trên hợp lệ: nếu bạn chuyển ngày thành chuỗi và hiển thị theo cách đó trong TableView; bảng sẽ sắp xếp nó như vậy (không chính xác).

Giải pháp tôi tìm thấy là phân lớp lớp Ngày để ghi đè phương thức toString(). Tuy nhiên, có một báo trước ở đây: TableView sử dụng java.sql.Date thay vì java.util.Date; vì vậy bạn cần phải phân lớp trước đây.

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

Bảng sẽ gọi phương thức đó để in ngày.

Tất nhiên, bạn cần phải thay đổi quá ngày lớp học của bạn trong việc kê khai TableColumn đến lớp con mới:

@FXML 
TableColumn<MyObject, CustomDate> myDateColumn; 

Cùng một điều khi bạn đính kèm thuộc tính đối tượng của bạn để cột của bảng của bạn:

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

Và cuối cùng, cho rung rõ ràng đây là cách bạn khai báo các getter trong lớp đối tượng của bạn:

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

Tôi mất một thời gian để tìm ra điều này do thực tế là nó sử dụng java.sql.Date đằng sau hậu trường; vì vậy hy vọng điều này sẽ cứu người khác một thời gian!

4

Cập nhật cho Java FX8:

(Tôi không chắc nó là nơi tốt cho câu trả lời đó, nhưng tôi nhận được vấn đề trong JavaFX8 và một số thứ đã thay đổi, giống như gói java.time)

Một số khác biệt với các câu trả lời trước: Tôi giữ kiểu ngày trên cột, vì vậy tôi cần sử dụng cả cellValueFactory và cellFactory. Tôi Thực hiện một phương pháp tái sử dụng chung để tạo cellFactory cho tất cả các cột ngày tháng. Tôi sử dụng java 8 ngày cho gói java.time! Nhưng phương pháp này có thể dễ dàng được thực hiện lại cho 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)); 
     } 
     } 
    }; 
    }; 
} 

Những lợi thế là rằng:

  • Các cột được đánh máy với một "Ngày java8" để tránh những vấn đề loại evoqued bởi @Jordan
  • Phương pháp "getDateCell" là chung chung và có thể được sử dụng như một hàm util cho tất cả các loại Thời gian Java8 (Vùng được phân vùng cục bộ, vv)
4

Tôi muốn sử dụng Generics Java để tạo ra định dạng cột có thể sử dụng lại, mất java.text.Format. Điều này cắt giảm xuống trên số lượng mã soạn sẵn ...

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

Ví dụ về việc sử dụng

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

Đây là những gì tôi đã làm và tôi làm việc một cách hoàn hảo.

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

Một giải pháp phổ biến có thể là đơn giản như vậy:

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

Và việc sử dụng mẫu của nó:

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

Bạn có thể dễ dàng tính ống các loại khác nhau và đặt một trình định dạng hay chuyển đổi ở giữa.

//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; 
       }); 
Các vấn đề liên quan