【问题标题】:How to display objects inherited in JavaFX TableView如何显示 JavaFX TableView 中继承的对象
【发布时间】:2016-05-02 19:14:24
【问题描述】:

大家好!

我正在寻找有关如何在 Tableview 中显示从父对象继承的属性对象的日子。

让我解释一下:

  • 我有两种类型的对象 B 和 C,它们继承了 A 类型的对象。

  • A 有一个属性 a1

  • B 有一个属性 b1
  • C 有一个属性 c1

我想在 TableView 中显示 a1、b1 c1,并且我有一个可以是 A、B 或 C 类型的对象列表。

目前我这样声明我的 tableView:

TableView<A> table;

ListProperty<A> list = new SimpleListProperty<>();

TableColumn<A, a1> column_a1 = new TableColumn<A, a1>("a1 property");
column_a1.setCellValueFactory(new PropertyValueFactory<A, a1>("a1"));

TableColumn<B, b1> column_b1 = new TableColumn<B, b1>("b1 property");
column_b1.setCellValueFactory(new PropertyValueFactory<B, a1>("b1"));

TableColumn<C, c1> column_c1 = new TableColumn<C, c1>("c1 property");
column_c1.setCellValueFactory(new PropertyValueFactory<C, c1>("c1"));

table.getColumns().add((TableColumn<A, a1>) column_a1);
table.getColumns().add((TableColumn<B, b1>) column_b1);
table.getColumns().add((TableColumn<C, c1>) column_c1);

table.setItems((ObservableList<A>) list);

在此配置中,对于表格的每一行,只有一列必须是非空的。

但在向表格添加列时出现错误。

我声明了我的表:TableView 表 但显然我不能添加列 B 和 C,因为这些类型继承了 A。

我的问题是:如何查看继承JavaFX中表声明类型的对象属性?

我当然想将我的 tableView 声明为:TableView table,但这并不满足我。

还有其他方法吗?

编辑评论工作中的解决方案,但我还有另一个问题。 就我而言,B 和 C 类的属性具有相同的名称。 所以当我设置 PropertyValueFactory 我写:

TableView<A> table;

TableColumn<A, a1> column_a1 = new TableColumn<A, a1>("a1 property");
column_a1.setCellValueFactory(new PropertyValueFactory<A, a1>("a1"));

TableColumn<B, b1> column_b1 = new TableColumn<A, b1>("b1 property");
column_b1.setCellValueFactory(new PropertyValueFactory<A, b1>("sameNameOfProperty"));

TableColumn<C, c1> column_c1 = new TableColumn<A, c1>("c1 property");
column_c1.setCellValueFactory(new PropertyValueFactory<A, c1>("sameNameOfProperty"));

table.getColumns().add((TableColumn<A, a1>) column_a1);
table.getColumns().add((TableColumn<A, b1>) column_b1);
table.getColumns().add((TableColumn<A, c1>) column_c1);

table.setItems((ObservableList<A>) list)

由于属性名称相同,如果我用类型参数 A 声明所有列和属性,当我在 TableView 中添加 B 或 C 对象时,将为 B 或 C 对象的每一行设置两列 b1 和 c1 .

【问题讨论】:

  • 你试过 Table 之类的语法吗?
  • 是的,它返回一个错误。
  • 您可以拥有该表,并且所有列和属性都具有类型参数 A。如果 PropertyValueFactory 然后得到一个没有适当属性的 A,它只会返回 null。不确定这是否是最好的解决方案,但它确实有效。

标签: java inheritance javafx tableview


【解决方案1】:

我通过实现 b1 和 c1 属性的 ObservableValue 找到了答案。这给出了这样的结果:

TableView<A> table;

TableColumn<A, a1> column_a1 = new TableColumn<A, a1>("a1 property");
column_a1.setCellValueFactory(new PropertyValueFactory<A, a1>("a1"));

TableColumn<A, b1> column_b1 = new TableColumn<A, b1>("b1 property");

column_b1.setCellValueFactory(new Callback<CellDataFeatures<A, b1>, ObservableValue<b1>>() {
    public ObservableValue<b1> call(CellDataFeatures<A, b1> p) {
        if(p.getValue() instanceof B){
            return new ObservableValue<B.b1>() {
                @Override
                public void removeListener(InvalidationListener arg0) {}
                @Override
                public void addListener(InvalidationListener arg0) {}
                @Override
                public void removeListener(ChangeListener<? super b1> listener) {}

                @Override
                public b1 getValue() {
                    return ((B)p.getValue()).getSameNameOfProperty();
                }

                @Override
                public void addListener(ChangeListener<? super b1> listener) {}
                };
            }
        return null;
        }
    });

TableColumn<A, c1> column_c1 = new TableColumn<A, c1>("c1 property");

column_c1.setCellValueFactory(new Callback<CellDataFeatures<A, c1>, ObservableValue<c1>>() {
    public ObservableValue<c1> call(CellDataFeatures<A, c1> p) {
        if(p.getValue() instanceof C){
            return new ObservableValue<C.c1>() {
                @Override
                public void removeListener(InvalidationListener arg0) {}
                @Override
                public void addListener(InvalidationListener arg0) {}
                @Override
                public void removeListener(ChangeListener<? super c1> listener) {}

                @Override
                public c1 getValue() {
                    return ((C)p.getValue()).getSameNameOfProperty();
                }

                @Override
                public void addListener(ChangeListener<? super c1> listener) {}
            };
        }
        return null;
        }
   });
table.getColumns().add((TableColumn<A, a1>) column_a1);
table.getColumns().add((TableColumn<A, b1>) column_b1);
table.getColumns().add((TableColumn<A, c1>) column_c1);

table.setItems((ObservableList<A>) list);

这样,添加一个类型的对象a、b或c只填充对应的列。 我仍然需要按类型检查信息条目,但这是另一回事。

感谢您的回答!

【讨论】:

  • 一般不需要自己实现ObservableValue。您可以使用ReadOnlyObjectWrapper&lt;T&gt;,或ReadOnlyStringWrapperReadOnlyLongWrapper 等。
  • 你说得对,我返回了一个 ReadOnlyObjectWrapper,它更简单、更快捷。感谢您的回答!
  • @sillyfly , @Doremous:然而ReadOnlyObjectWrapper 不像名字所暗示的那样,实际上是modifiable。它可读可写,但允许您使用getReadOnlyProperty() 创建属性的只读视图。为不可变属性创建 a 的简洁方法是 a)new ReadOnlyObjectWrapper(myValue).getReadOnlyProperty() 或 b)Bindings.createObjectBinding(() -&gt; myValue)。 (虽然我没有对使用的内存进行分析)
  • @fabian :好的,但我忘了指定我想编辑表中的每个属性。所以在这种情况下我不需要添加 .getReadOnlyProperty() 不是吗?
  • @Doremus:在这种情况下,您应该返回项目本身的属性,或者如果您只实现 getter+setter 使用JavaBeanObjectProperty。顺便说一句:ReadOnlyObjectWrapper 不是用于普通属性的类。如果您不需要属性的只读视图,请改用SimpleObjectProperty
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多