Значение 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()));

Надеюсь, это поможет в будущем.

Другие вопросы по тегам