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问题

根据 datepicker 值在控制器中运行方法

特定格式的 JavaFX DatePicker getValue

JavaFX DatePicker 与时间

JavaFX8 DatePicker 按钮大小更改