【问题标题】:JavaFX date formatting within a TableView using legacy beans使用遗留 bean 在 TableView 中的 JavaFX 日期格式
【发布时间】:2015-09-01 10:58:31
【问题描述】:

我有一个 TableView,它源自 java.util.Date 类型的遗留 Java Bean 中的一个属性。我希望将日期字符串的格式自定义为 HH:mm:ss

我正在寻找一个本机 JavaFX 实用程序,用于创建采用 java.util.DateFormatjavafx.util.StringConverter 的 ObservableValue 包装器

我发现 Bindings.format() 类可以用来包装 ObservableValue,但是这只允许 printf 格式模式,如 %04d 等,而不是任何自定义日期特定格式。

我想出的最好方法是将 Bindings.bindBidirectional(property, property, format) 与 CellFactory 返回的虚拟 StringProperty 一起使用。这可以简化吗?这会导致内存泄漏吗?

public class OldBeanTableView extends Application {
    public class OldBean {
        private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
        public static final String PROPERTY_NAME_FOO = "foo";
        private Date foo = new Date();

        public Date getFoo() {
            return foo;
        }

        public void setFoo(Date foo) {
            Date oldValue = this.foo;
            this.foo = foo;
            pcs.firePropertyChange(PROPERTY_NAME_FOO, oldValue, foo);
        }

        public void addPropertyChangeListener(PropertyChangeListener listener) {
            pcs.addPropertyChangeListener(listener);
        }

        public void removePropertyChangeListener(PropertyChangeListener listener) {
            pcs.removePropertyChangeListener(listener);
        }
    }

    private class LegacyValueFactory<T, F> implements Callback<CellDataFeatures<T, String>, ObservableValue<String>> {

        private String propertyName;
        private Format format;

        public LegacyValueFactory(String propertyName, Format format) {
            this.propertyName = propertyName;
            this.format = format;
        }

        @Override
        public ObservableValue<String> call(CellDataFeatures<T, String> param) {
            try {
                Property<String> formattedString = new SimpleStringProperty();
                Property<F> original = JavaBeanObjectPropertyBuilder.create().name(propertyName).bean(param.getValue()).build();
                Bindings.bindBidirectional(formattedString, original, format);
                return formattedString;

            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        ObservableList<OldBean> beans = FXCollections.observableArrayList();
        beans.add(new OldBean());

        TableView<OldBean> tableView = new TableView<>();
        TableColumn<OldBean, String> column = new TableColumn<OldBeanTableView.OldBean, String>();
        tableView.getColumns().add(column);

        column.setCellValueFactory(new LegacyValueFactory<OldBean, String>("foo", new SimpleDateFormat("HH:mm:ss")));

        tableView.setItems(beans);
        primaryStage.setScene(new Scene(tableView));
        primaryStage.show();
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
                () -> beans.get(0).setFoo(new Date(beans.get(0).getFoo().getTime() + 1000)), 0, 1, TimeUnit.SECONDS);
    }

    public static void main(String[] args) {
        launch(args);
    }

}

【问题讨论】:

  • 在这种情况下,我通常会使用刚刚返回 JavaBeanObjectProperty&lt;Date&gt;TableColumn&lt;OldBean, Date&gt;cellValueFactory(即使用 Date 作为列的数据类型)。然后还定义一个cellFactory 来执行格式化。这会起作用吗,还是出于某种原因您真的需要列中的数据类型为String
  • 我只将其键入为字符串,因为 Bindings.bindBindirectory(a, b, c) 迫使我走这条路。我认为 cellFactory 自定义是为了布局问题,但你是对的,我可以将它用于字符串格式化......如果你想把它写成我会接受的答案。

标签: java javafx javafx-8


【解决方案1】:

根据 James_D 的建议,这可以使用 CellFactory 而不是 CellValueFactory...

public class FormattedTableCell<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> {
    private Format format;
    public FormattedTableCell(Format format) {
        super();
        this.format = format;
    }
    @Override
    public TableCell<S, T> call(TableColumn<S, T> param) {
        return new TableCell<S, T>() {
            @Override
            protected void updateItem(T item, boolean empty) {
                super.updateItem(item, empty);
                if (item == null || empty) {
                    setText(null);
                } else {
                    setText(format.format(item));
                }
            }
        };
    }
}

用法

column.setCellFactory(new FormattedTableCell<OldBean, Date>(new SimpleDateFormat("HH:mm:ss")));

【讨论】:

    猜你喜欢
    • 2015-12-02
    • 1970-01-01
    • 2017-10-06
    • 2020-03-12
    • 2016-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多