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

Ton*_*ced 2 java user-interface javafx tableview

我知道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>();
}
Run Code Online (Sandbox Code Playgroud)

调用getter方法的速度比尝试将对象拉出SimpleProperty要快吗?

Jam*_*s_D 10

你几乎可以使用任何你喜欢的设计.

FX属性模式为您提供了许多功能:它创建了可观察,可写的属性,在许多情况下可以直接连接到控件.所以,如果你的设计使用模式,将"表豆",那么你可以使用的PropertyValueFactory为您cellValueFactory,和大量的事情发生"自动的",如更新表格单元格值更改时,反之亦然.

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

的PropertyValueFactory,不过,我觉得确实增加了一些开销,因为它依赖于反射来找到指定名称的属性.如果你更换,你会看到一些(我不承诺多少)的好处

myTableColumn.setCellValueFactory(new PropertyValueFactory<>("thing"));
Run Code Online (Sandbox Code Playgroud)

同

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

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

myTableColumn.setCellValueFactory(data -> data.getValue().thingProperty());
Run Code Online (Sandbox Code Playgroud)

).

现在,如果您不需要JavaFX属性的花里胡哨(例如,表行项中的值将不会在表中编辑外部更改,并且表中的编辑需要"难"有线"通过setOnCommit(...)无论如何",然后您可以通过省略它们并仅使用常规Javabean模型getX()和setX(...)方法来保存JavaFX属性的(小)开销.有一些,虽然我认为并不多,性能优势,显然更少的代码.

来自反射的开销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()));
Run Code Online (Sandbox Code Playgroud)

它可能和它一样高效:但是,如果你希望你的表可编辑,你需要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);
}
Run Code Online (Sandbox Code Playgroud)

请注意,不要将"属性"作为参考名称的一部分(即private StringProperty referenceNumber代替private StringProperty referenceNumberProperty)包含在其中,但当然这完全取决于您.