使用超类字段填充Tableview

问题描述 投票:0回答:1

我有几个类都从一个super类继承,这些类需要填充与其类相关的几个TableView

超类是抽象的,一些getter和setter是最终的,但仍包含填充单元格所需的数据。

为每一列编写一个新的Callback类都是可行的,但是我正在寻找一种实现此方法的方法。

示例代码

class SuperClass
{
  protected String name;
  protected double value;
  public final void setName(String name)
  {
    this.name = name;
  }
  public final void getName()
  {
    return this.name;
  }
  public final void setValue(double value)
  {
    this.value = value;
  }
  public double getValue()
  {
    return this.value;
  }
}
class SubClass1 extends SuperClass
{
  private int id;
  public void setId(int id)
  {
    this.id = id;
  }
  public int getId()
  {
    return this.id;
  }
}
class SubClass2 extends SuperClass
{
  private String location;
  public void setLocation(String location)
  {
    this.location = location;
  }
}
class SubClass3 extends SuperClass
{
  private ObservableMap<SuperClass> map;
  public ObservableMap<SuperClass> map()
  {
    return this.map;
  }
}

TableView

TableColumn<SubClass1, Integer> tc1_id;
TableColumn<SubClass1, String> tc1_name;
TableColumn<SubClass1, Double> tc1_value;
TableColumn<SubClass2, String> tc2_loc;
TableColumn<SubClass2, String> tc2_name;
TableColumn<SubClass2, Double> tc2_value;
TableColumn<SubClass3, String> tc3_name;
TableColumn<SubClass3, Double> tc3_value;

这里是我要做什么的参考...Accessing Subclass properties in a JavaFX TableView ObservableArrayList

但是仅使用示例代码,我基本上是重写2个方法,每个方法3次……而且实际程序中还有很多方法。 (还有一点点麻烦)

javafx java-8 callback tableview
1个回答
0
投票

如果我正确理解了您的问题,则您有一个表,每个表的行都由SuperClass的实例表示。这些行中至少有一些实际上可能是其中一个子类的实例,而您的某些列仅适用于特定的子类。

给定TableView<S>all行必须是S的实例,并且对于某些类型TableColumn<S,T>(可以随列而异),所有列都必须是T

因此,这里您唯一的选择是声明一个TableView<Superclass>。然后您的列将看起来像

TableColumn<Superclass, Integer> tc1Id;
TableColumn<Superclass, String> tc1Name;
TableColumn<Superclass, Double> tc1Value;
TableColumn<Superclass, String> tc2Loc;
TableColumn<Superclass, String> tc2Name;
TableColumn<Superclass, Double> tc2Value;
TableColumn<Superclass, String> tc3Name;
TableColumn<Superclass, Double> tc3Value;

并且您可以使用类似的代码来设置其单元格值工厂

tc1Id.setCellValueFactory(cellData -> {
    if (cellData.getValue() instanceof SubClass1) {
        SubClass1 value = (SubClass1) cellData.getValue();
        return new SimpleObjectProperty<>(value.getId());
    } else {
        return new SimpleObjectProperty<>(null);
    }
});

tc2Loc.setCellValueFactory(cellData -> {
    if (cellData.getValue() instanceof SubClass2) {
        SubClass2 value = (SubClass2) cellData.getValue();
        return new SimpleObjectProperty<>(value.getLocation());
    } else {
        return new SimpleObjectProperty<>(null);
    }
});

显然,您可以通过创建实现重复部分并采用表示变化部分的参数的函数来执行编程中通常要做的事情,并减少重复代码:

private <S extends Superclass, T> void createCellValueFactory(
        TableColumn<Superclass, T> col, 
        Class<S> type, 
        Function<S,T> func
) {
    col.setCellValueFactory(cellData -> {
        if (type.isInstance(cellData.getValue())) {
            S value = type.cast(cellData.getValue());
            return new SimpleObjectProperty<>(func.apply(value));
        } else return new SimpleObjectProperty<>(null);
    });
}

然后

createCellValueFactory(tc1Id, SubClass1.class, SubClass1::getId);
createCellValueFactory(tc2Loc, SubClass2.class, SubClass2::getLocation);

© www.soinside.com 2019 - 2024. All rights reserved.