Значение DatePicker продолжает сбрасываться в строках Tableview в Javafx
Я использую класс DatePickerCell для создания Datepicker в ячейке TableView, но я не могу сохранить его значение.
Это класс DatePickerCell, используемый для визуализации ячейки, он был взят с форума с примером дня рождения.
public class DatePickerCell<S, T> extends TableCell<T, Date> {
private DatePicker datePicker;
public DatePickerCell() {
super();
if (datePicker == null) {
createDatePicker();
}
setGraphic(datePicker);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
Platform.runLater(new Runnable() {
@Override
public void run() {
datePicker.requestFocus();
}
});
}
@Override
public void updateItem(Date item, boolean empty) {
super.updateItem(item, empty);
SimpleDateFormat smp = new SimpleDateFormat("dd/MM/yyyy");
if (null == this.datePicker) {
System.out.println("datePicker is NULL");
}
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
setContentDisplay(ContentDisplay.TEXT_ONLY);
} else {
setDatepikerDate(smp.format(new Date()));
setText(smp.format(new Date()));
setGraphic(this.datePicker);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
}
private void setDatepikerDate(String dateAsStr) {
LocalDate ld = null;
int day, month, year;
day = month = year = 0;
try {
day = Integer.parseInt(dateAsStr.substring(0, 2));
month = Integer.parseInt(dateAsStr.substring(3, 5));
year = Integer.parseInt(dateAsStr.substring(6, dateAsStr.length()));
} catch (NumberFormatException e) {
System.out.println("setDatepikerDate / unexpected error " + e);
}
ld = LocalDate.of(year, month, day);
datePicker.setValue(ld);
}
private void createDatePicker() {
this.datePicker = new DatePicker();
datePicker.setPromptText("dd/MM/yyyy");
datePicker.setEditable(true);
datePicker.setOnAction(t -> {
LocalDate date = datePicker.getValue();
int index1 = getIndex();
SimpleDateFormat smp = new SimpleDateFormat("dd/MM/yyyy");
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, date.getDayOfMonth());
cal.set(Calendar.MONTH, date.getMonthValue() - 1);
cal.set(Calendar.YEAR, date.getYear());
setText(smp.format(cal.getTime()));
commitEdit(cal.getTime());
});
setAlignment(Pos.CENTER);
}
@Override
public void startEdit() {
super.startEdit();
}
@Override
public void cancelEdit() {
super.cancelEdit();
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
public DatePicker getDatePicker() {
return datePicker;
}
public void setDatePicker(DatePicker datePicker) {
this.datePicker = datePicker;
}
}
Я хочу знать, когда я использую его в таблице и пытаюсь добавить одну или несколько строк, ранее выбранные даты в предыдущих строках устанавливаются на дату по умолчанию (системная дата), а мои выбранные значения исчезают. Я не могу понять, почему он повторно инициализирует все средства выбора даты или сбрасывает их даты.
Вот как я использую это в моем коде
@FXML private TableView<Stock> tblStock;
@FXML private TableColumn<Stock, Date> colDate;
colDate.setCellValueFactory(new PropertyValueFactory<>("date1"));
colDate.setCellFactory(cell -> new DatePickerCell());
В моем классе Stock это то, как я инициализирую date1
private Date date1 = new Date();
1 ответ
Наконец, после долгих долгих поисков я смог достичь своей цели. Благодаря этому человеку я получил ячейку рабочего стола с DatePicker.
Вот код для дальнейшего использования:
Класс DatePickerCell
public class DatePickerCell<S, T> extends TableCell<S, Date> {
private DatePicker datePicker;
public DatePickerCell() {
super();
//if you want focus on your datepicker
/*Platform.runLater(new Runnable() {
@Override
public void run() {
datePicker.requestFocus();
}
});*/
}
@Override
public void updateItem(Date item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if(datePicker != null) {
datePicker.setValue(getDate());
}
setText(null);
setGraphic(datePicker);
} else {
setText(getDate()
.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)));
setGraphic(null);
}
}
}
private void createDatePicker() {
this.datePicker = new DatePicker(getDate());
datePicker.setPromptText("dd/MM/yyyy");
datePicker.setEditable(true);
datePicker.setOnAction(t -> {
commitEdit(Date.from(datePicker.getValue().atStartOfDay(ZoneId.systemDefault())
.toInstant()));
datePicker.focusedProperty().addListener(((observable, oldValue,
newValue) -> {
if(!newValue)
commitEdit(Date.from(datePicker.getValue()
.atStartOfDay(ZoneId.systemDefault()).toInstant()));
}));
});
}
@Override
public void startEdit() {
super.startEdit();
if(!isEmpty()) {
createDatePicker();
setText(null);
setGraphic(datePicker);
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText(getDate().toString());
setGraphic(null);
}
public LocalDate getDate() {
return getItem() == null ? LocalDate.now() :
getItem().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
}
Использование в приложении
Модельный класс
private SimpleObjectProperty<Date> date = new SimpleObjectProperty<>(/*your parameter*/);
//getter
public Date getDate() {
return date.get();
}
//property getter
public SimpleObjectProperty<Date> dateProperty() {
return date;
}
//setter
public void setDate(Date date) {
this.date.set(date);
}
контроллер
@FXML private TableColumn<Stock, Date> colDate;
//because using FXML document, initialization not needed
colDate.setCellValueFactory(cell -> cell.getValue().dateProperty());
colDate.setCellFactory(cell -> new DatePickerCell<Stock, Date>());
colDate.setOnEditCommit(event -> event.getTableView().getItems()
.get(event.getTablePosition().getRow()).setDate(event.getNewValue()));
Надеюсь, это поможет в будущем.