当前位置: 首页 > 知识库问答 >
问题:

在JavaFX中处理派生属性

雍河
2023-03-14

我现在正在使用JavaFX,我正在跟随一个教程来学习Java的这一部分。不过,我有一个关于属性的问题:

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

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

public class User {

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

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

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

我可以在SetCellValueFactory中创建SimpleIntegerProperty,但我不认为这是一个解决方案。我还可以在User类中创建一个名为ageIntegerProperty,但我听起来不太对,因为age是从生日派生的属性。

这就产生了我的问题:如何处理JavaFX中的派生属性?

谢谢你的回复。

共有1个答案

戎志勇
2023-03-14

您可以使用前面提到的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();
});

但是,当您创建绑定时,您使用以下依赖项param.getValue().birthde,这是您知道getage()方法内部计算的标志(好吧,在本例中,很明显计算是基于生日的,但在某些情况下不是)。

因此,我会选择您提到的第二个选项来将计算封装到它所属的地方:User类中的一个附加(只读)属性,在该属性中年龄与生日绑定。

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(); }

Update:同一个User类在Age属性上使用惰性初始化。

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();
    }
}
 类似资料:
  • 我的JFrame中有一个web浏览器,我想我无法让它在退出应用程序时处理它。 以下是我试图实现这一目标的代码: 窗口关闭,但java进程保持不变,这一行总是返回false:

  • 我正在编写一个JavaFX程序,其中用户输入一个颜色的十六进制值,并将其设置为StakePane的背景颜色。代码为: 对于有效的十六进制值输入,它可以正常工作。但是当用户输入无效十六进制值时,它会在控制台出现以下错误: “需要从解析器中检测错误的应用程序可以向com.sun.javafx.css.StyleManager的errors属性添加一个侦听器。” 如何处理JavaFX中的CSS错误?

  • 我首先想到的是,一个property_a不能绑定到另一个property_b,这个property_b绑定到property_a或者依赖于属性,这些属性绑定到property_a。对吧?

  • 问题内容: 我有一个带有集合的类,它们是Hibernate管理的POJO。我也在使用 hbm.xml 文件映射我的实体。当用户转到管理屏幕时,我希望他将数据查看到表中,该表还将包含最近完成的工作。但是,只有访问可检测内容的详细信息页面,才能使用完整的修订集。 我的机会是显示最后的修订日期,该日期将作为每个实例的属性单独加载。所以我有这样的事情: detectable.hbm.xml 这是行不通的,

  • 问题内容: 我有一个带有集合的类,它们是Hibernate管理的POJO。我还使用 hbm.xml 文件映射了我的实体。当用户转到管理屏幕时,我希望他将数据查看到表中,该表还将包含最近完成的工作。但是,只有访问可检测内容的详细信息页面,才能使用完整的修订集。 我的机会是显示最后的修订日期,该日期将作为每个实例的属性单独加载。所以我有这样的事情: detectable.hbm.xml 这是行不通的,

  • 我想我的问题是:在一个我们已经将工作拆分的小组项目中,设置Eclipse直接从主存储库中提取更改并将其合并到我正在处理的内容中是一个更好的主意吗--或者--分叉存储库并在我自己的副本上独立工作,然后以某种方式将我的小组成员所做的任何更改合并到我自己的分叉中,然后在完成我的部分时推动我的更改? 这是一个个人偏好,从原始存储库直接拉到Eclipse还是‘分叉’存储库到我的on Github帐户,然后从