汇总JavaFX属性和JPA实体(无混合模式)

O_T*_*O_T 3 jpa javafx

基础

我有一个由JPA(EclipseLink)管理的mysql数据库(实体和控制器+持久性单元).GUI是基于JavaFX的.

信息

我看到这篇文章:

和这个示例代码

问题

目前我正在使用我的适配器(不是真正的适配器模式)将JPAEntity转换为JavaFX Bean

public <T, S> Function<T, S> getRefactor() {
    return o -> {
        Object rtn = null;

        //adapt **o** it to JavaFX bean

        return (S) rtn;
    };
}
Run Code Online (Sandbox Code Playgroud)

我想,这不是最好的解决方案.

问题 没有混合模式!我相信在服务器端使用javafx属性是疯狂的,即使是超级懒惰的实现.

有一个灵活的解决方案可以获得JavaFX Bean的所有好处,例如双向绑定,并保留未更改的JPA实体代码?

EDITED

即目前我有JPAEntity + JPAController和FXClass,"代表"JPAEntity.

JPAEntity是一种旧式POJO,包含要写入DB的数据.

FXClass具有javafx属性,包含在FX环境中显示的数据.

所以...我正在使用一个中间层将两者进行通信.

提前致谢

Jam*_*s_D 7

我通常会主张在JPA实体中使用JavaFX属性:我真的没有明显的理由不这样做.

但是,如果您想避免这样做,可以使用JavaBeanPropertyAdapters.这些是创建包装常规JavaBean属性的JavaFX可观察属性的适配器.所以如果你有一个bean类

@Entity
public class Person {

    private String firstName ;
    private String lastName ;

    @Id
    private Integer id ;

    public String getFirstName() {
        return firstName ;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName ;
    }

    public String getLastName() {
        return lastName ;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName ;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以做类似的事情

TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setCellValueFactory(cellData -> {
    try {
        return JavaBeanStringPropertyBuilder.create()
            .bean(cellData.getValue())
            .name("firstName")
            .build();
    } catch (NoSuchMethodException exc) {
        throw new RuntimeException(exc);
    }
});
Run Code Online (Sandbox Code Playgroud)

这将创建一个在表中使用的JavaFX属性,并单向地将JavaBean属性绑定到它:即,如果更改表中的值,JavaBean将更新.此设置不会发生反向绑定,即更改bean中的值不会更新表中显示的值.

如果您想要双向绑定,您的bean将需要支持属性更改侦听器:

public class Person {
    private String firstName ;
    private String lastName ;

    private PropertyChangeSupport pcs ;

    public Person() {
        pcs = = new PropertyChangeSupport(this);
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        pcs.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        pcs.removePropertyChangeListener(listener);
    }

    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        String oldName = this.firstName ;
        this.firstName = firstName;
        pcs.firePropertyChange("firstName", oldName, this.firstName);
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        String oldName = this.lastName ;
        this.lastName = lastName;
        pcs.firePropertyChange("lastName", oldName, this.lastName);
    }

}
Run Code Online (Sandbox Code Playgroud)

现在,对bean的更改将传播到表使用的JavaFX属性,反之亦然.