在模型类中使用javafx.beans属性

在模型类中使用JavaFX bean属性是否正确?

我想知道在模型类中使用属​​性是否能够将它们与视图组件轻松绑定是否是一种好习惯。我不担心将来这些库的可用性,因为我的程序将在JRE8或更高版本上运行,但是在模型类中使用JavaFX库的性质使我持怀疑态度,并且我担心当前和将来的不兼容性,尤其是因为我想使用Hibernate来保留这些属性。

注意:我使用纯JavaFX环境,并且我的应用程序永远不需要Swing兼容性。

回答:

我将在这里提出不同意见。

正如我评论jewelsea的答案一样,只要您使用“属性访问”而不是“字段访问”,就可以在JPA中使用基于JavaFX属性的Bean。我链接到那里的博客文章对此进行了更详细的介绍,但是基本思想是任何注释都应该在get...()方法上,而不是在字段上。据我所知,这确实阻止了将任何只读JavaFX属性模式与JPA结合使用,但是我从来没有真正感觉到JPA在只读属性(即get方法和无set方法)中表现良好。

与我对jewelsea答案的评论相反,并受益于几个星期的工作(并且被安排为我面临使用JavaFX属性在JavaFX客户端上复制多个实体类的位置),我认为缺乏JavaFX属性的序列化可以解决。关键的观察结果是,您实际上只需要序列化属性的包装状态(而不是任何侦听器)。您可以通过实现java.io.ExternalizableExternalizable是的子接口Serializable,要求您填写readExternal(...)writeExternal(...)方法。可以实现这些方法以仅外部化属性包装的状态,而不是属性本身。这意味着,如果您的实体先序列化然后反序列化,您将得到一个新的属性实例,并且将不会保留任何侦听器(即,侦听器实际上变为transient),但是据我所知,这就是所需要的在任何合理的用例中。

我尝试用这种方式定义的bean,并且一切似乎都很好地工作。另外,我进行了一个小实验,使用杰克逊映射器在JSON表示形式之间进行转换,从而在客户端和静态Web服务之间传输它们。由于映射器仅依靠使用get和set方法,因此可以正常工作。

需要注意两点。与任何序列化一样,拥有无参数的构造函数也很重要。当然,由JavaFX属性包装的所有值本身必须可序列化-

再次,这与任何可序列化bean的规则相同。

关于JavaFX属性通过副作用起作用的观点已被很好地理解,并且在将这些属性(在某种程度上考虑到单线程模型的设计)移至潜在的多线程服务器时,需要格外小心。一个好的经验法则可能是,如果您使用此策略,则仅应在客户端注册侦听器(请记住,这些侦听器是暂时的,无论是通过序列化还是通过JSON表示,都可以传输回服务器)。当然,这表明在服务器端使用它们可能是一个糟糕的设计。在拥有“所有人的万事万物”的单个实体(JavaFX客户端的可观察属性,可序列化以实现持久性和/或远程访问,

最后,如果您确实使用了JPA批注,则这些批注具有运行时保留,这意味着(我认为)您的JavaFX客户端将需要在类路径上使用javax.persistence规范。

这是一个“四季皆宜的人”实体的示例:

import java.io.Externalizable;

import java.io.IOException;

import java.io.ObjectInput;

import java.io.ObjectOutput;

import java.time.MonthDay;

import javafx.beans.property.IntegerProperty;

import javafx.beans.property.ObjectProperty;

import javafx.beans.property.SimpleIntegerProperty;

import javafx.beans.property.SimpleObjectProperty;

import javafx.beans.property.SimpleStringProperty;

import javafx.beans.property.StringProperty;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

/**

* Entity implementation class for Entity: Person

*

*/

@Entity

public class Person implements Externalizable {

private static final long serialVersionUID = 1L;

public Person() {

}

public Person(String name, MonthDay birthday) {

setName(name);

setBirthday(birthday);

}

private final IntegerProperty id = new SimpleIntegerProperty(this, "id");

@Id

@GeneratedValue(strategy=GenerationType.AUTO)

public int getId() {

return id.get();

}

public void setId(int id) {

this.id.set(id);

}

public IntegerProperty idProperty() {

return id ;

}

private final StringProperty name = new SimpleStringProperty(this, "name");

// redundant, but here to indicate that annotations must be on the property accessors:

@Column(name="name")

public final String getName() {

return name.get();

}

public final void setName(String name) {

this.name.set(name);

}

public StringProperty nameProperty() {

return name ;

}

private final ObjectProperty<MonthDay> birthday = new SimpleObjectProperty<>();

public final MonthDay getBirthday() {

return birthday.get();

}

public final void setBirthday(MonthDay birthday) {

this.birthday.set(birthday);

}

public ObjectProperty<MonthDay> birthdayProperty() {

return birthday ;

}

@Override

public void writeExternal(ObjectOutput out) throws IOException {

out.writeInt(getId());

out.writeObject(getName());

out.writeObject(getBirthday());

}

@Override

public void readExternal(ObjectInput in) throws IOException,

ClassNotFoundException {

setId(in.readInt());

setName((String) in.readObject());

setBirthday((MonthDay) in.readObject());

}

}

以上是 在模型类中使用javafx.beans属性 的全部内容, 来源链接: utcz.com/qa/414289.html

回到顶部