Format of Date in the JavaFX.TableView
Asked Answered
H

1

5

I have ran into a problem.

I have a POJO class:

public class PatientEntity {

    private int id;
    private Date dateDoc;
    private String secondname;
    private String firstname;
    private String thirdname;

    @Id
    @Column(name = "ID")
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Basic
    @Column(name = "Date_doc")
    public Date getDateDoc() {
        return dateDoc;
    }

    public void setDateDoc(Date dateDoc) {
        this.dateDoc = dateDoc;
    }

I'm using JavaFX.TableView in such way to fill:

columnID.setCellValueFactory(new PropertyValueFactory<PatientEntity, Integer>("id"));
columnDate.setCellValueFactory(new PropertyValueFactory<PatientEntity, Date>("dateDoc"));
columnSecondname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("secondname"));
columnFirstname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("firstname"));
columnThirdname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("thirdname"));

tableView.setItems(FXCollections.observableList(patients));

In result: the result of running

It works fine, but I need another format of Date such as dd.mm.yyyy in the TableView. So how can I do that? As you can see, TableView contains objects, not simple strings.

Edited #1

private synchronized void updateTableView(List <PatientEntity> patients){

    columnID.setCellValueFactory(new PropertyValueFactory<PatientEntity, Integer>("id"));
    columnDate.setCellFactory(column -> {
        TableCell<PatientEntity, Date> cell = new TableCell<PatientEntity, Date>() {
            private SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");

            @Override
            protected void updateItem(Date item, boolean empty) {
                super.updateItem(item, empty);
                if(empty) {
                    setText(null);
                }
                else {
                    this.setText(format.format(item));

                }
            }
        };

        return cell;
    });

    columnSecondname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("secondname"));
    columnFirstname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("firstname"));
    columnThirdname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("thirdname"));
    tableView.setItems(FXCollections.observableList(patients));
}

Such result

Edited #2

private void updateTableView(){
    Thread threadConnectingToDB = new Thread(() -> {
        try {
            List <PatientEntity> patients;
            PatientDAO patientDAO = FactoryDAO.getInstance().getPatientDAO();
            if(patientDAO.getAllPatients() instanceof List){
                patients = (List) patientDAO.getAllPatients();
            } else {
                patients = new ArrayList(patientDAO.getAllPatients());
            }
            columnID.setCellValueFactory(new PropertyValueFactory<PatientEntity, Integer>("id"));
            columnDate.setCellValueFactory(new PropertyValueFactory<PatientEntity, Date>("doc_date"));
            columnDate.setCellFactory(column -> {
                TableCell<PatientEntity, Date> cell = new TableCell<PatientEntity, Date>() {
                    private SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");

                    @Override
                    protected void updateItem(Date item, boolean empty) {
                        super.updateItem(item, empty);
                        if(empty) {
                            setText(null);
                        }
                        else {
                            if(item != null)
                            this.setText(format.format(item));
                        }
                    }
                };

                return cell;
            });

            columnSecondname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("secondname"));
            columnFirstname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("firstname"));
            columnThirdname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("thirdname"));
            tableView.setItems(FXCollections.observableList(patients));


        } catch (SQLException e) {
            try {
                ErrorStage.display("Произошла ошибка при подключении к базе данных");
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
    });
    threadConnectingToDB.start();
    threadConnectingToDB.interrupt();
}

Solution

Thank to @mr mcwolf there is a solution!

We need two methods: The first method is a configuration method, which we call once during the initialization:

private void configureTableView(){
    columnID.setCellValueFactory(new PropertyValueFactory<PatientEntity, Integer>("id"));
    columnDate.setCellFactory(column -> {
        TableCell<PatientEntity, Date> cell = new TableCell<PatientEntity, Date>() {
            private SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");

            @Override
            protected void updateItem(Date item, boolean empty) {
                super.updateItem(item, empty);
                if(empty) {
                    setText(null);
                }
                else {
                    this.setText(format.format(item));

                }
            }
        };

        return cell;
    });
    columnDate.setCellValueFactory(new PropertyValueFactory<PatientEntity, Date>("dateDoc"));
    columnSecondname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("secondname"));
    columnFirstname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("firstname"));
    columnThirdname.setCellValueFactory(new PropertyValueFactory<PatientEntity, String>("thirdname"));

}

And we need a method to fill the tableView:

private synchronized void fillTableView(List <PatientEntity> patientsList){

    Thread threadConnectingToDB = new Thread(() -> {
        try {
            List<PatientEntity> patients = patientsList;
            if(patients == null) {
                PatientDAO patientDAO = FactoryDAO.getInstance().getPatientDAO();
                if (patientDAO.getAllPatients() instanceof List) {
                    patients = (List) patientDAO.getAllPatients();
                } else {
                    patients = new ArrayList(patientDAO.getAllPatients());
                }
            }
            tableView.setItems(FXCollections.observableList(patients));
        } catch (SQLException e) {
            try {
                ErrorStage.display("Error Connection");
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
    });
    threadConnectingToDB.start();
    threadConnectingToDB.interrupt();
}
Huberman answered 25/11, 2017 at 9:7 Comment(9)
did you use a Formatter ? first result : Format formatter = new SimpleDateFormat("dd/MM/yy"); then apply : formatter.format(dateDoc);Upcast
I know how SimpleDateFormat works, i dont know how to use it inside JavaFX.TableView. I feel that override is required but i dont know how to do itHuberman
you probably configure the table elsewhere. no columnDate.setCellValueFactory in the edited code, but there are data in the column.Sp
@mrmcwolf yeah, you was right. I forgot about the second method. But now it turns out that all item = null. Any ideas?Huberman
no code can not help. if cells are empty, you have not set setCellValueFactorySp
@mrmcwolf have pasted code. CellValueFactory exists but item is still null.Huberman
updateTableView just needs to change the model. calls to setCellValueFactory and setCellFactory should be removed from there. these functions are called once when initializing the table. the call to setCellValueFactory is missing in the "other" function you are talking about.Sp
@mrmcwolf, yeah man, thank you it works great. More over i refactor my code thank to you. Of course, the program will not work faster, but I got rid of the useless constant reconfiguration.Huberman
I'm glad I helped you :)Sp
S
12

try this

columnDate.setCellFactory(column -> {
    TableCell<PatientEntity, Date> cell = new TableCell<PatientEntity, Date>() {
        private SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");

        @Override
        protected void updateItem(Date item, boolean empty) {
            super.updateItem(item, empty);
            if(empty) {
                setText(null);
            }
            else {
                setText(format.format(item));
            }
        }
    };

    return cell;
});
Sp answered 25/11, 2017 at 13:15 Comment(2)
Hey man, i have edited my code, but it is still using yyyy-dd-mm format.Huberman
Topic updated. I put the breakpoint inside the lambda. Debugger dont catch that breakpoint, so i think i should do more than overriding the updateItem() method?Huberman

© 2022 - 2024 — McMap. All rights reserved.