java - 动态显示 DatePicker

标签 java swing javafx datepicker javafx-8

我正在编写一个显示 StringProperty 表的 JavaFX 应用程序和 ObjectPropery<LocalDate>值。当我深入研究表的工作原理时,我似乎无法使用 DatePicker作为一个单元格,所以我打算做的是将日期显示为一个字符串,但是当用户试图编辑该单元格时,我会捕获该事件并显示动态 DatePicker它将接受新的日期值并更新单元格。

现在,我无法获取此动态 DatePicker出现。

JavaFX:

    <TableView fx:id="tableView" editable="true" GridPane.columnIndex="0" GridPane.rowIndex="1">
        <columns>
         ...
        <TableColumn fx:id="recDate" onEditStart="#handleChangeDate" prefWidth="100.0" text="Received Date">
            <cellValueFactory>
                <PropertyValueFactory property="recDate" />
                <!-- <DatePicker fx:id="recDatePicker" /> -->
            </cellValueFactory>
        </TableColumn>
         ...

Java 8:

@FXML
private void handleChangeDate(CellEditEvent<MissionItem, LocalDate> e) {
    final DatePicker dp = new DatePicker(e.getOldValue());
    dp.setDisable(false);
    dp.setOnAction(event -> {
        LocalDate date = dp.getValue();
        System.out.println("Selected date: " + date);
    });
    Platform.runLater(dp::show);
    dp.show(); //redundant. Still doesn't work.
    System.out.println("fired event");
}

我能看到 fired event然而DatePicker永远不会出现。

我的目标是:

  • 将表显示为一组 Strings/LocalDates
  • 假设单元格本身不能是 DatePicker,这是一个很好的事件处理程序,当用户想要编辑日期单元格时,动态 DatePicker 会出现,接受用户输入,然后值会更新。
  • 确保此比例适用于 1000 行。

最佳答案

要自定义列的单元格,您需要在该列的 cellFactory 中创建适当的 TableCell:

public class DatePickerTableCell<T> extends TableCell<T, LocalDate> {

    private final DatePicker datePicker;
    private boolean listening = true;

    // listener for changes in the datepicker
    private final ChangeListener<LocalDate> listener = (observable, oldValue, newValue) -> {
        if (listening) {
            listening = false;

            TableColumn<T, LocalDate> column = getTableColumn();
            EventHandler<TableColumn.CellEditEvent<T, LocalDate>> handler = column.getOnEditCommit();
            if (handler != null) {
                // use TableColumn.onEditCommit if there is a handler
                handler.handle(new TableColumn.CellEditEvent<>(
                        (TableView<T>) getTableView(),
                        new TablePosition<T, LocalDate>(getTableView(), getIndex(), column),
                        TableColumn.<T, LocalDate>editCommitEvent(),
                        newValue
                ));
            } else {
                // otherwise check if ObservableValue from cellValueFactory is
                // also writable and use in that case
                ObservableValue<LocalDate> observableValue = column.getCellObservableValue((T) getTableRow().getItem());
                if (observableValue instanceof WritableValue) {
                    ((WritableValue) observableValue).setValue(newValue);
                }
            }

            listening = true;
        }
    };

    public DatePickerTableCell() {
        this.datePicker = new DatePicker();
        this.datePicker.valueProperty().addListener(listener);
    }

    @Override
    protected void updateItem(LocalDate item, boolean empty) {
        super.updateItem(item, empty);

        if (empty) {
            listening = false;
            setGraphic(null);
        } else {
            listening = false;
            setGraphic(this.datePicker);
            this.datePicker.setValue(item);
            listening = true;
        }
    }

    public static <E> Callback<TableColumn<E, LocalDate>, TableCell<E, LocalDate>> forTableColumn() {
        return column -> new DatePickerTableCell<>();
    }

}

请注意,此类不会对“正常”编辑状态使用react。它始终处于编辑状态。但是,它会尝试调用 onEditCommit 处理程序来启用对不可观察属性的处理编辑。

可以使用 fxml 添加工厂

<TableColumn fx:id="recDate" prefWidth="100.0" text="Received Date">
    <cellValueFactory>
        <PropertyValueFactory property="recDate" />
    </cellValueFactory>
    <cellFactory>
         <DatePickerTableCell fx:factory="forTableColumn"/>
    </cellFactory>
</TableColumn>

(需要适当的导入指令包含在 fxml 中。)

关于java - 动态显示 DatePicker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48104012/

相关文章:

java - 警告 : No mapping found for HTTP request with URI [/SpringLoginApplication/] in DispatcherServlet with name 'SpringLoginApplication'

java - 我可以用 java 代码替换查询,这样更好吗?

java - 如何从日期获取时区

java - YouTube Java API。无需登录即可制作 YouTube 服务

java - 尝试将对象从固定起点移动到鼠标单击的坐标

java - 在缓冲图像上绘制油漆?

java - 可观察/列表或属性 : exception thrown in listener not "seen" by unit test

javafx-2 - 如何在 JavaFX 中实现可以处理任何 EventType 的真正自定义事件处理程序?

java - Jdatechooser 文本右对齐

java - 将小时和分钟添加到 Date 对象