Я ищу, как добавить 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
. Поэтому мне нужно, чтобы этот код работал правильно.
Может кто-нибудь мне помог?