2017-05-08 87 views
0

我有一個包含許多列的TableView。第一個包含日期(以dd/mm/yyyy格式),但日期不能「正確」排序。JavaFX按日期排序TableView列(dd/mm/yyyy格式)

這裏是一個小例子,我已經準備:

Image

這裏是代碼:

Test.java

package test; 

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Scene; 
import javafx.scene.layout.AnchorPane; 
import javafx.stage.Stage; 

public class Test extends Application { 
    private AnchorPane rootLayout; 

    @Override 
    public void start(Stage primaryStage) throws Exception{ 

     FXMLLoader loader = new FXMLLoader(); 
     loader.setLocation(Test.class.getResource("FXMLDocument.fxml")); 
     FXMLDocumentController controller = new FXMLDocumentController(); 
     loader.setController(controller); 

     rootLayout = (AnchorPane) loader.load(); 
     Scene scene = new Scene(rootLayout); 

     primaryStage.setScene(scene); 
     primaryStage.setTitle("Test"); 

     primaryStage.centerOnScreen(); 
     primaryStage.show(); 

    } 

} 

FXMLDocumentController.java

package test; 

import java.util.List; 
import java.util.Map; 
import javafx.fxml.FXML; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.control.cell.PropertyValueFactory; 

public class FXMLDocumentController { 
    private ObservableList<ExampleTable> datos; 
    @FXML public TableView<ExampleTable> tv_example; 
    @FXML public TableColumn<ExampleTable, String> col_date, col_name; 

    public void initialize(){ 
     datos = FXCollections.observableArrayList(); 
     col_date.setCellValueFactory(new PropertyValueFactory<>("date")); 
     col_name.setCellValueFactory(new PropertyValueFactory<>("name")); 

     setTable(); 
    } 

    public void setTable(){ 
     List<Map<String, String>> lmap = ExampleTable.lmap(); 
     for(Map<String, String> element : lmap){ 
      ExampleTable objEt = new ExampleTable(element.get("date"), element.get("name")); 
      datos.add(objEt); 
     } 

     tv_example.setItems(datos); 
     tv_example.getSortOrder().setAll(col_date); 
    } 
} 

ExampleTable.java

package test; 

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 

public class ExampleTable { 
    public StringProperty date; 
    public StringProperty name; 

    public ExampleTable(String date, String name){ 
     this.date = new SimpleStringProperty(date); 
     this.name = new SimpleStringProperty(name); 
    } 

    public String getDate(){ 
     return date.get(); 
    } 

    public void setDate(String date){ 
     this.date.set(date); 
    } 

    public String getName(){ 
     return name.get(); 
    } 

    public void setName(String name){ 
     this.name.set(name); 
    } 

    public static List<Map<String, String>> lmap(){ 
     List<Map<String, String>> list = new ArrayList<>(); 

     Map<String, String> row = new HashMap<>(); 
     row.put("date", "14/01/1988"); 
     row.put("name", "Hagen"); 
     list.add(row); 

     row = new HashMap<>(); 
     row.put("date", "27/02/1988"); 
     row.put("name", "Herrman"); 
     list.add(row); 

     row = new HashMap<>(); 
     row.put("date", "16/03/1988"); 
     row.put("name", "Hank"); 
     list.add(row); 

     row = new HashMap<>(); 
     row.put("date", "19/05/1994"); 
     row.put("name", "Jack"); 
     list.add(row); 

     return list; 
    } 
} 

而且FXML文件:

FXMLDocument.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.control.TableColumn?> 
<?import javafx.scene.control.TableView?> 
<?import javafx.scene.layout.AnchorPane?> 
<?import javafx.scene.layout.VBox?> 

<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="500.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111"> 
    <children> 
     <VBox layoutX="32.0" layoutY="40.0" prefHeight="200.0" prefWidth="100.0" AnchorPane.bottomAnchor="4.0" AnchorPane.leftAnchor="4.0" AnchorPane.rightAnchor="4.0" AnchorPane.topAnchor="4.0"> 
     <children> 
      <TableView fx:id="tv_example" maxHeight="1.7976931348623157E308" prefWidth="200.0" VBox.vgrow="ALWAYS"> 
       <columns> 
       <TableColumn fx:id="col_date" minWidth="120.0" prefWidth="120.0" text="Date" /> 
       <TableColumn fx:id="col_name" minWidth="100.0" prefWidth="300.0" text="Name" /> 
       </columns> 
      </TableView> 
     </children> 
     </VBox> 
    </children> 
</AnchorPane> 

編輯:

我剛剛做用的LOCALDATE代替String作爲日期這些變化:

ExampleTable.java

public ObjectProperty<LocalDate> date; 
    public StringProperty name; 

    public ExampleTable(LocalDate date, String name){ 
     this.date = new SimpleObjectProperty(date); 
     this.name = new SimpleStringProperty(name); 
    } 

    public LocalDate getDate(){ 
     return date.get(); 
    } 

    public void setDate(LocalDate date){ 
     this.date.set(date); 
    } 

FXMLDocumentController.java

public class FXMLDocumentController { 
    private ObservableList<ExampleTable> datos; 
    @FXML public TableView<ExampleTable> tv_example; 
    @FXML public TableColumn<ExampleTable, LocalDate> col_date; 
    @FXML public TableColumn<ExampleTable, String> col_name; 

    public void initialize(){ 
     datos = FXCollections.observableArrayList(); 
     col_date.setCellValueFactory(new PropertyValueFactory<>("date")); 
     col_name.setCellValueFactory(new PropertyValueFactory<>("name")); 

     setTable(); 
    } 

    public void setTable(){ 
     List<Map<String, String>> lmap = ExampleTable.lmap(); 

     for(Map<String, String> element : lmap){ 
      LocalDate dt = ExampleTable.toLocalDate(element.get("date")); 
      ExampleTable objEt = new ExampleTable(dt, element.get("name")); 
      datos.add(objEt); 
     } 

     tv_example.setItems(datos); 
     tv_example.getSortOrder().setAll(col_date); 
    } 
} 

這裏是「 toLocalDate「方法示例表:

public static LocalDate toLocalDate(String date){ 
     final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); 
     LocalDate dt = LocalDate.parse(date, formatter); 
     return dt; 
    } 

而且我得到這個:

Image 02

+0

使列LocalDate而不是String的數據類型(即使用'TableColumn colDate',並將'ExampleTable'中'date'的類型更改爲'ObjectProperty '等)。 –

+0

正如您所建議的那樣,我已將其更改爲「LocalDate」,但現在日期格式爲yyy-mm-dd,如圖02所示。 – Kamerad

+0

查看答案。 FWIW我會盡可能地從'String'傳播到'LocalDate',即將您的'static'方法更改爲僅返回一個'List '而不是地圖。除了當你想顯示它們(這是在實際的單元格的實現中)時,你應該基本上*總是*表示具有LocalDate而不是'String'的日期。 –

回答

0

可以更改LocalDate通過使用cellFactory顯示在表格單元格的方式(除了cellValueFactory你已經擁有):

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); 
col_date.setCellFactory(tc -> new TableCell<ExampleTable, LocalDate>() { 
    @Override 
    protected void updateItem(LocalDate date, boolean empty) { 
     super.updateItem(date, empty); 
     if (empty) { 
      setText(null); 
     } else { 
      setText(formatter.format(date)); 
     } 
    } 
}); 
+0

完美,謝謝! – Kamerad