JavaFX TableView:我是否必须将我的字段包装在 Simple<Object/Integer/String>Property?



我知道TableViews及其列取决于所表示的对象具有XYZProperty值和适当的getter这一事实。我必须使用所有这些符号吗?我的特定类有很多字段,并且也使用了生成器模式。为什么我不能只使用原始字段变量而不是创建XProperty版本?

class ActionItem{
private String referenceNum;
private int percentComplete;
private ActionPlan actionPlans;
private LocalDate dateAssigned, dateDue, dateFinal, dateStarted,
     dateCompleted;
private String subject, description;
private Employee assignedBy, assignedToPrimary, assignedToSecondary;
private EmployeeGroup assignedToGroup;
private Criticality criticality;
private Status status;
----
private SimpleStringProperty referenceNumberProperty = new SimpleStringProperty();
private SimpleIntegerProperty percentCompleteProperty = new SimpleIntegerProperty();
private SimpleObjectProperty<ActionPlan> actionPlansProperty = new SimpleObjectProperty<ActionPlan>();
private SimpleObjectProperty<LocalDate> dateAssignedProperty = new SimpleObjectProperty<LocalDate>();
private SimpleObjectProperty<LocalDate> dateDueProperty = new SimpleObjectProperty<LocalDate>(),
     dateFinalProperty = new SimpleObjectProperty<LocalDate>(),
     dateStartedProperty = new SimpleObjectProperty<LocalDate>(),
     dateCompletedProperty = new SimpleObjectProperty<LocalDate>();
private SimpleStringProperty subjectProperty = new SimpleStringProperty(),
     descriptionProperty = new SimpleStringProperty();
private SimpleObjectProperty<Employee> assignedByProperty = new SimpleObjectProperty<Employee>(),
     assignedToPrimaryProperty = new SimpleObjectProperty<Employee>(),
     assignedToSecondaryProperty = new SimpleObjectProperty<Employee>();
private SimpleObjectProperty<EmployeeGroup> assignedToGroupProperty = new SimpleObjectProperty<EmployeeGroup>();
private SimpleObjectProperty<Criticality> criticalityProperty = new SimpleObjectProperty<ActionItem.Criticality>();
private SimpleObjectProperty<Status> statusProperty = new SimpleObjectProperty<ActionItem.Status>();
}

调用getter方法是否比尝试从SimpleProperty中拉出对象执行得更快?

您几乎可以使用任何您喜欢的设计。

FX属性模式为您提供了很多功能:它创建了可观察、可写的属性,在许多情况下,这些属性可以直接连接到控件中。因此,如果您使用该模式设计"表bean",那么您可以将PropertyValueFactory用作cellValueFactory,许多事情都会"自动"发生,例如在值更改时更新表单元格,反之亦然。

使用属性本身不会增加太多开销。有一个很好的文档概述了使用FX属性的一些良好做法。

不过,我认为PropertyValueFactory确实增加了一些开销,因为它依赖于反射从指定名称中查找属性。因此,如果你更换,你会看到一些(我不承诺有多少)好处

myTableColumn.setCellValueFactory(new PropertyValueFactory<>("thing"));

带有

myTableColumn.setCellValueFactory(new Callback<CellDataFeatures<S,T>, ObservableValue<T>>() {
    public ObservableValue<T> call(CellDataFeatures<S,T> data) {
        return data.getValue().thingProperty() ;
    }
});

(或者,在Java 8中,更简单的

myTableColumn.setCellValueFactory(data -> data.getValue().thingProperty());

)。

现在,如果您不需要JavaFX属性的铃声和口哨声(例如,表行项目中的值不会在表中编辑的外部更改,并且表中的编辑无论如何都需要通过setOnCommit(...)"硬连接"),那么您可以通过省略它们并仅使用常规Javabean模型来节省JavaFX属性(小)开销,用CCD_ 5和CCD_。虽然我认为没有太多的性能优势,但显然代码更少。

PropertyValueFactory中反射的开销(我猜)比使用JavaFX属性的开销大,所以如果出于性能原因想要这样做,我也会显式地将回调连接到get方法,而不是依赖PropertyValueFactory。正如@brian评论中的链接一样,以前的一些版本在实现这一点时效率很低(尽管现在已经修复)。所以类似的东西

class Item {
  private String name ;
  public String getName() {
    return name ;
  }
  public void setName(String name) {
    this.name = name ;
  }
}
TableColumn<Item, String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(itemData -> new ReadOnlyStringWrapper(itemData.getValue.getName()));

可能和它一样高效:不过,如果你想让你的表可编辑,你需要手动将编辑提交连接到对setName(...)的调用,并且对表外部数据的更新不会反映在表中。

一句话:如果你不想使用JavaFX属性,你就不必这样做。你错过了一些免费的功能,而且有一些方法可以自己编写,你可能会在节省一些代码的同时获得一些(轻微的)性能优势。真正难以解决的一种情况是从表编辑外部更新表中显示的属性。如果你在代码中这样做,JavaFX属性会让你的生活变得更轻松。

更新:根据您的意见,我建议您在用例中使用JavaFX属性。我强烈建议阅读上面链接的文档,幻灯片18-46,尤其是幻灯片30-43中的属性模式。

但是,特别要使用抽象类(例如StringProperty)作为属性的类型,而不是具体类型(SimpleStringProperty)。当使用属性作为对象的属性时,请使用名称和对其bean的引用来实例化它们。例如:

private StringProperty referenceNumberProperty = new SimpleStringProperty(this, "referenceNumber");
public final StringProperty referenceNumberProperty() {
    return referenceNumberProperty ;
}
public final String getReferenceNumber() {
    return referenceNumberProperty.get() ;
}
public final void setReferenceNumber(String referenceNumber) {
    this.referenceNumberProperty.set(referenceNumber);
}

请注意,不将"property"作为引用名称的一部分(即private StringProperty referenceNumber而不是private StringProperty referenceNumberProperty)稍微更为传统,但这当然完全取决于您。

相关内容

  • 没有找到相关文章

最新更新