如何将JAXB与PropertyChangeSupport一起使用?

时间:2016-01-03 06:37:33

标签: jaxb eclipse-rcp

我正在尝试在Eclipse项目中使用JAXB。使用java.beans.PropertyChangeSupport将视图窗口小部件绑定到模型属性。这很好用。我还希望使用JAXB将模型属性绑定到磁盘上的持久XML表示。我可以将重要的状态编组为XML,并且可以在运行时将其解组为pojo / bean,但不确定如何最好地继续。

  1. 绑定到我的视图窗口小部件的bean setter需要firePropertyChange(),但XJC只生成简单的setter,this.value = value。

  2. XJC属性受到保护,所以看起来我可以将其setter重写为firePropertyChange(),但我不知道我的重写子类如何让它的unmarshaled超类在运行时神奇地改变状态(比如用户请求时)报告不同年份,即我将解组不同的XML文件。)

  3. 这样做有例子或模式吗?当然这不是新的。非常感谢。 -d

3 个答案:

答案 0 :(得分:0)

@Adam谢谢!我用这个方法找到了一个可行的解决方案:

public class MyBean extends JaxBean {
  public JaxBean getJaxBean() {
    return this;
  }
  public void setJaxBean(JaxBean jaxBean) {
    super.setThis(jaxBean.getThis());
    super.setThat(jaxBean.getThat());
    // etc...
  }
  public MyBean() {
    // etc...
  }
}

我认为我的困惑在于认为未编组的bean会以某种方式神奇地取代我的工作实例。上面的解决方案需要额外的文本,但它可以工作,并且使用JaxBean的哑设置器可以避免在加载新XML时不必要地触发事件。

您的解决方案,使用JAXB注释MyBean并使用schemagen,听起来更好。接下来我会尝试下去。这些都是非常好的技术。 -d

答案 1 :(得分:0)

我在评论中提到了另一种应用方法。

这是我们在RCP应用程序中使用的内容。除了我们通过网络编组/解组,因此我们使用JAXWS而不仅仅是JAXB。

我对这种筹码有点经验,所以这对你来说是一个很好的启动:

/**
 * Your UI POJO-s should extend this class.
 */
public abstract class UIModel<T extends UIModel> {
    protected final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);

    /**
     * This comes handy at times
    */
    public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
        //....
    }

    /**
     * And this too, trust me.
     */
    public void deepCopy(final T of) {
            removePropertyChangeListener(propertyChangeListener);

            //It's from Spring Framework but you can write your own. Spring is a fat-ass payload for a Java-SE application.
            BeanUtils.copyProperties(of, this, IGNORED_ON_CLIENT);

            addPropertyChangeListener(propertyChangeListener);
        }
    }

    public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
    }

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

/**
 * Example of a UI POJO.
 */
public class Car extends UIModel<Car> {
    private String make;
    private int numberOfWheels;
    //... etc.

    /**
     * Example of a setter
     */
    public void setMake(String make) {
        propertyChangeSupport.firePropertyChange("make", this.make, this.make = make);
    }

    public String getMake() {
        return make;
    }
    //... etc.
}

我不知道您的架构定义发生了多大变化,但有一种支持这种情况的模式;

/**
 * New application (compiled with the class below) can open a file saved by the old application.
 */
public class Car2 extends Car {
    private String fuelType; // Example of a new field

    public void setFuelType(String fuelType) {
        propertyChangeSupport.firePropertyChange("fuelType", this.fuelType, this.fuelType = fuelType);
    }

    //... etc.
}

这样旧的应用程序就可以打开新的XML输出。从这样的类源代码中删除字段将导致RuntimeException,因为JAXB仍在查找它。 如果您的客户始终是最新的,那么您根本不应该关心这一点。

当处理Java集合并过度子类化时,您将遇到JAXB问题,您可以通过Googling @XmlRootElement和@XmlSeeAlso注释来解决这些问题。

答案 2 :(得分:0)

评论不要格式化,尝试&#34;回答&#34;。需要做stackoverflow之旅。接着,

谢谢,亚当,我会将这些书签加入以供将来参考。它们看起来与我的例子类似,模式是(unmarshal New,安静,复制New to Old,吵闹)。我喜欢弯曲的递归,

class UIModel<T extends UIModel>
class Car extends UIModel<Car>

并假设您已对其进行了测试编译。 ;)

问候,-d。