gpt4 book ai didi

java - 处理 JavaFX 中的派生属性

转载 作者:行者123 更新时间:2023-12-01 09:09:21 24 4
gpt4 key购买 nike

我现在正在使用 JavaFX,并且正在关注 tutorial来学习Java这一部分。不过我有一个关于属性的问题:

如何正确处理JavaFX中的派生属性?

让我用一个例子来澄清。假设您有一个具有简单属性的模型:

public class User {

private final StringProperty name;
private final ObjectProperty<LocalDate> birthday;
}

(我忽略了构造函数和属性 getter :假设它们在那里)并假设您有一个带有 TableView 的 View ,其中有 2 列列出用户,其中:

  • 第一列是用户的姓名;
  • 第二列是用户的年龄

类似这样的东西(也展示了一些绘画技巧!):

View example

现在,年龄当然是生日字段的派生属性,可以通过以下方法轻松实现:

public int getAge() {
return Period.between(this.getBirthday().get(), LocalDate.now()).getYears();
}

但是 TableView 不接受整数,而只接受可观察的整数。我希望如果有人更改用户的生日,表格会自动更改。

我可以在 setCellValueFactory 内创建一个 SimpleIntegerProperty,但我认为这不是一个解决方案。我还可以在 User 类中创建一个名为 ageIntegerProperty ,但这对我来说听起来不对,因为年龄是派生的属性(property)从生日开始。

因此出现了我的问题:如何处理 JavaFX 中的派生属性?

PS:我看了这个SO answer但是,可能由于我在该领域缺乏专业知识,我无法找到令人满意的结果。

感谢您的友好回复。

最佳答案

您可以使用提到的 setCellValueFactorySimpleIntegerProperty 来完成此操作:

TableColumn<User, Integer> ageCol = new TableColumn<User, Integer>("Age");

ageCol.setCellValueFactory(param -> {
SimpleIntegerProperty prop = new SimpleIntegerProperty(param.getValue().getAge());
prop.bind(Bindings.createIntegerBinding(() -> {
return param.getValue().getAge();
}, param.getValue().birthday));
return prop.asObject();
});

但是,当您创建绑定(bind)时,您使用以下依赖项param.getValue().birthday,这是您知道getAge()的内部计算的标记> 方法(好吧,对于这种情况,很明显计算是基于生日的,但也有一些情况不是)。

因此,我会选择您提到的第二个选项,将计算封装到它所属的位置:User 类中的附加(只读)属性,其中年龄与生日绑定(bind).

public static class User {

private final StringProperty name;
private final ObjectProperty<LocalDate> birthday;

private final ReadOnlyIntegerWrapper age;

public StringProperty nameProperty() { return name; }
public ObjectProperty<LocalDate> birthdayProperty() { return birthday; }
public ReadOnlyIntegerProperty ageProperty() { return age.getReadOnlyProperty(); }

private User(String name, LocalDate bDay) {
this.name = new SimpleStringProperty(name);
birthday = new SimpleObjectProperty<LocalDate>(bDay);
this.age = new ReadOnlyIntegerWrapper();
age.bind(Bindings.createIntegerBinding(() -> Period.between(this.getBirthday(), LocalDate.now()).getYears(), birthday));
}

public String getName() { return name.get(); }
public LocalDate getBirthday() { return birthday.get(); }
public int getAge() { return ageProperty().get(); }
}

然后使用它:

TableColumn<User, Integer> ageCol = new TableColumn<User, Integer>("Age");
ageCol.setCellValueFactory(new PropertyValueFactory<User, Integer>("age"));

该示例使用 ReadOnlyIntegerWrapper (来自您链接的答案)并通过 ReadOnlyIntegerProperty 公开内部属性 age:

public ReadOnlyIntegerProperty ageProperty() { return age.getReadOnlyProperty(); }

更新:age 属性上使用延迟初始化的相同 User 类。

public static class User {

private final StringProperty name;
private final ObjectProperty<LocalDate> birthday;

private ReadOnlyIntegerWrapper age = null;

public StringProperty nameProperty() { return name; }
public ObjectProperty<LocalDate> birthdayProperty() { return birthday; }

public ReadOnlyIntegerProperty ageProperty() {
if (age == null) {
age = new ReadOnlyIntegerWrapper();
age.bind(Bindings.createIntegerBinding(() -> calculateAge(), birthday));
}

return age.getReadOnlyProperty();
}

private User(String name, LocalDate bDay) {
this.name = new SimpleStringProperty(name);
birthday = new SimpleObjectProperty<LocalDate>(bDay);
}

public String getName() { return name.get(); }

public LocalDate getBirthday() {return birthday.get(); }

public int getAge() {
return (age != null) ? age.get() : calculateAge();
}

private final int calculateAge() {
return Period.between(this.getBirthday(), LocalDate.now()).getYears();
}
}

关于java - 处理 JavaFX 中的派生属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41015673/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com