Как зафиксировать дату на DatePicker javafx - PullRequest
0 голосов
/ 12 января 2019

Я ищу, как добавить jdatepicker в столбце табличного представления. Я попробовал приведенный ниже код, но моя программа запускается с ошибкой, когда я изменяю тип с Monthday на Date.

класс День рождения Cell

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package model;

import java.time.LocalDate;
import java.util.Date;
import java.time.format.DateTimeFormatter;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TableCell;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.control.DateCell;
import javafx.scene.input.MouseEvent;
import javafx.beans.binding.Bindings;
import javafx.scene.control.ContentDisplay;

/**
 *
 * @author kuupie
 */
public class BirthdayCell extends TableCell<Person, Date> {

        private final DateTimeFormatter formatter ;
        private final DatePicker datePicker ;

        public BirthdayCell() {

            formatter = DateTimeFormatter.ofPattern("MMMM d") ;
            datePicker = new DatePicker() ;

            // Commit edit on Enter and cancel on Escape.
            // Note that the default behavior consumes key events, so we must 
            // register this as an event filter to capture it.
            // Consequently, with Enter, the datePicker's value won't yet have been updated, 
            // so commit will sent the wrong value. So we must update it ourselves from the
            // editor's text value.

            datePicker.addEventFilter(KeyEvent.KEY_PRESSED, (KeyEvent event) -> {
                if (event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.TAB) {
                    datePicker.setValue(datePicker.getConverter().fromString(datePicker.getEditor().getText()));
                    commitEdit(Date.from(datePicker.getValue()));
                }
                if (event.getCode() == KeyCode.ESCAPE) {
                    cancelEdit();
                }
            });

            // Modify default mouse behavior on date picker:
            // Don't hide popup on single click, just set date
            // On double-click, hide popup and commit edit for editor
            // Must consume event to prevent default hiding behavior, so
            // must update date picker value ourselves.

            // Modify key behavior so that enter on a selected cell commits the edit
            // on that cell's date.

            datePicker.setDayCellFactory(picker -> {
                DateCell cell = new DateCell();
                cell.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
                    datePicker.setValue(cell.getItem());
                    if (event.getClickCount() == 2) {
                        datePicker.hide();
                        commitEdit(Date.from(cell.getItem()));
                    }
                    event.consume();
                });
                cell.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
                    if (event.getCode() == KeyCode.ENTER) {
                        commitEdit(Date.from(datePicker.getValue()));
                    }
                });
                return cell ;
            });

            contentDisplayProperty().bind(Bindings.when(editingProperty())
                    .then(ContentDisplay.GRAPHIC_ONLY)
                    .otherwise(ContentDisplay.TEXT_ONLY));
        }

        @Override
        public void updateItem(Date birthday, boolean empty) {
            super.updateItem(birthday, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                setText(formatter.format(birthday));
                setGraphic(datePicker);
            }
        }

        @Override
        public void startEdit() {
            super.startEdit();
            if (!isEmpty()) {
                datePicker.setValue(getItem().atYear(LocalDate.now().getYear()));
            }
        }

    }

класс персонажа

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package model;

import java.util.Date;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

/**
 *
 * @author kuupie
 */
public class Person {

        private final StringProperty firstName;
        private final StringProperty lastName;
        private final StringProperty email;
        private final ObjectProperty<Date> birthday ;

        public Person(String firstName, String lastName, String email, Date birthday) {
            this.firstName = new SimpleStringProperty(this, "firstName", firstName);
            this.lastName = new SimpleStringProperty(this, "lastName", lastName);
            this.email = new SimpleStringProperty(this, "email", email);
            this.birthday = new SimpleObjectProperty<>(this, "birthday", birthday);
        }

        public String getFirstName() {
            return firstName.get();
        }

        public void setFirstName(String value) {
            firstName.set(value);
        }

        public StringProperty firstNameProperty() {
            return firstName;
        }

        public String getLastName() {
            return lastName.get();
        }

        public void setLastName(String value) {
            lastName.set(value);
        }

        public StringProperty lastNameProperty() {
            return lastName;
        }

        public String getEmail() {
            return email.get();
        }

        public void setEmail(String value) {
            email.set(value);
        }

        public StringProperty emailProperty() {
            return email;
        }

        public Date getBirthday() {
            return birthday.get();
        }

        public void setBirthday(Date birthday) {
            this.birthday.set(birthday);
        }

        public ObjectProperty<Date> birthdayProperty() {
            return birthday ;
        }

    }

класс FXMLDocumentController

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package tableviewsamplewithbirthday;

import java.net.URL;
import static java.time.Month.DECEMBER;
import static java.time.Month.MARCH;
import static java.time.Month.SEPTEMBER;
import java.util.Date;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import model.BirthdayCell;
import model.Person;

/**
 *
 * @author kuupie
 */
public class FXMLDocumentController implements Initializable {


    @FXML
    private TableView<Person> table;

    @FXML
    private TableColumn<Person, String> firstNameCol;

    @FXML
    private TableColumn<Person, String> lastNameCol;

    @FXML
    private TableColumn<Person, String> emailCol;

    @FXML
    private TableColumn<Person, Date> birthdayCol;


    @FXML
    private Button showDataButton;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        load();
        // TODO
    }    


    private void load(){
        final ObservableList<Person> data
                = FXCollections.observableArrayList(
                        new Person("Ruby", "swizz", "swizz.ruby@example.com", Date(1977-10-10)),
                        new Person("Ryan", "West", "west.ryan@example.com", "1998-09-10")
                );

        table.setItems(null);
        table.setEditable(true);

        firstNameCol.setCellValueFactory(
                new PropertyValueFactory<>("firstName"));

        lastNameCol.setCellValueFactory(
                new PropertyValueFactory<>("lastName"));

        emailCol.setCellValueFactory(
                new PropertyValueFactory<>("email"));


        birthdayCol.setCellValueFactory(new PropertyValueFactory<>("birthday"));
        birthdayCol.setCellFactory(col -> new BirthdayCell());
        birthdayCol.setEditable(true);
        birthdayCol.setOnEditCommit(event -> event.getRowValue().setBirthday(event.getNewValue()));


            table.setItems(data);


        showDataButton.setOnAction(event -> 
        table.getItems().stream()
            .map(p -> String.format("%s %s (%s) %s", p.getFirstName(), p.getLastName(), p.getEmail(), p.getBirthday()))
            .forEach(System.out::println)    
        );


    }

}

Я ищу еще один день, чтобы решить это. Как изменить на localdate или преобразовать из string в Date и затем преобразовать в экземпляр. Это все еще получает ошибку. В другой день я улучшу эту программу, чтобы она вызывала дату из моей базы данных, например, создавала, обновляла или удаляла дату на datepicker. Поэтому мне нужно, чтобы этот код работал правильно.

Может кто-нибудь мне помог?

...