DatePicker 的值在 Javafx 中 Tableview 的行中不断重置
Posted
技术标签:
【中文标题】DatePicker 的值在 Javafx 中 Tableview 的行中不断重置【英文标题】:DatePicker's value keeps resetting in Tableview's rows in Javafx 【发布时间】:2016-11-04 16:26:37 【问题描述】:我正在使用 DatePickerCell 类在 TableView 单元格中创建 Datepicker,但我无法保留它的值。
这是用于渲染单元格的 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】:终于,经过长时间的搜索,我能够实现我的目标。感谢这个person,我得到了一个带有日期选择器的工作表单元格。
下面是代码供以后参考:
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()));
希望这对将来有所帮助。
【讨论】:
以上是关于DatePicker 的值在 Javafx 中 Tableview 的行中不断重置的主要内容,如果未能解决你的问题,请参考以下文章
JavaFX 从 DatePicker 中提取日历弹出窗口/仅显示弹出窗口
JavaFX:setDisable(true)DatePicker问题