如何为类型的子类实现GWT编辑器? [英] How to implement GWT editors for subclasses of a type?

查看:89
本文介绍了如何为类型的子类实现GWT编辑器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这样的对象层次结构:

帐户>网站>供应



一个账户是一家实际的公司,一个网站是他们拥有的一个建筑,一个供应是一个 ElecSupply GasSupply 。供应从来没有实例化,理论上可能是一个抽象类。



我使用Objectify进行持久化,并且有一个页面显示每个网站的耗材列表,无论它们是否是 ElecSupply GasSupply



现在我正在实施 GWT编辑器框架,并提出了一个问题与这个多态实体。

  @Entity 
公共类Supply实现Serializable
{
@Id
保护长ID;
@Embedded
protected List< BillingPeriod> billingPeriods = new ArrayList< BillingPeriod>();

public Supply()
{

}
// ...
}

子类:(ElecSupply有5个独特的字段,GasSupply只有一个)

pre> @Subclass
public class ElecSupply extends Supply implements Serializable
{
private String profile;
private String mtc;
private String llf;
私人字符串区域;
私有字符串核心;

public ElecSupply()
{

}
}






  @Subclass 
公共类GasSupply延伸Supply实现Serializable
{
private String mpr;

public GasSupply()
{

}
// ...
}

所以我想知道有没有人有这种结构的经验?我试图为 ElecSupply GasSupply 制作单独的编辑器,然后将它们显示或隐藏为编辑页面的一部分。

另一种方式我想这样做的方法是使用单个编辑器(对于Supply),然后根据哪种类型的对象加载不同的子编辑器我们正在编辑。



任何灯光都会受到欢迎。

解决方案

p>我已经在这种情况下,并且已经实现了以下解决方案:


  • 首先创建一个通用函数名为AbstractSubTypeEditor的类,当您编辑您的子类对象时,它将激活特定的编辑器: .client.CompositeEditor;
    import com.google.gwt.editor.client.Editor;
    import com.google.gwt.editor.client.EditorDelegate;
    import com.google.gwt.editor.client.LeafValueEditor;

    public abstract class AbstractSubTypeEditor< T,C extends T,E extends Editor< C>>实现了CompositeEditor< T,C,E> ;, LeafValueEditor< T> {
    private EditorChain< C,E>链;
    private T currentValue;
    private final E subEditor;

    / **
    *构造由给定的子编辑器支持的AbstractSubTypeEditor。
    *
    * @param subEditor将附加到编辑器的子编辑器
    *层次结构
    * /
    public AbstractSubTypeEditor(E subEditor){
    this.subEditor = subEditor;
    }

    / **
    *返回OptionalFieldEditor构造
    *的子编辑器。
    *
    * @返回类型为E
    * /
    的编辑器@E public E createEditorForTraversal(){
    return subEditor;
    }

    public void flush(){
    currentValue = chain.getValue(subEditor);
    }

    / **
    *返回一个空字符串,因为只有一个子编辑器被使用。
    * /
    public String getPathElement(E subEditor){
    return;
    }

    public T getValue(){
    return currentValue;
    }

    public void onPropertyChange(String ... paths){
    }

    public void setDelegate(EditorDelegate< T> delegate){


    public void setEditorChain(EditorChain< C,E>链){
    this.chain = chain;


    public void setValue(T value,boolean instanceOf){
    if(currentValue!= null&& value == null){
    chain。分离(副主编);
    }
    currentValue = value;
    if(value!= null&& instanceOf){
    chain.attach((C)value,subEditor);
    }
    }
    }


  • 现在你可以创建一个供应编辑器,其中包含两个子编辑器和两个AbstractSubTypeEditor(每个子类型对应一个):

      public class SupplyEditor扩展Composite implements Editor< Supply> {

    公共类ElecSupplyEditor实现了Editor< ElecSupply> {
    public final TextBox profile = new TextBox();
    public final TextBox mtc = new TextBox();
    public final TextBox llf = new TextBox();
    public final TextBox area = new TextBox();
    public final TextBox core = new TextBox();
    }
    @Ignore
    final ElecSupplyEditor elecSupplyEditor = new ElecSupplyEditor();
    @Path()
    final AbstractSubTypeEditor< Supply,ElecSupply,ElecSupplyEditor> elecSupplyEditorWrapper = new AbstractSubTypeEditor< Supply,ElecSupply,SupplyEditor.ElecSupplyEditor>(elecSupplyEditor){
    @Override
    public void setValue(final Supply value){
    setValue(value,value instanceof ElecSupply);
    if(!(value(ElecSupply)instanceof)){
    elecSupplyEditor.profile.setVisible(false);
    elecSupplyEditor.mtc.setVisible(false);
    elecSupplyEditor.llf.setVisible(false);
    elecSupplyEditor.area.setVisible(false);
    elecSupplyEditor.core.setVisible(false);
    } else {
    elecSupplyEditor.profile.setVisible(true);
    elecSupplyEditor.mtc.setVisible(true);
    elecSupplyEditor.llf.setVisible(true);
    elecSupplyEditor.area.setVisible(true);
    elecSupplyEditor.core.setVisible(true);
    }
    }
    };

    公共类GasSupplyEditor实现了Editor< GasSupply> {
    public final TextBox mpr = new TextBox();
    }
    @Ignore
    最终GasSupplyEditor gasSupplyEditor = new GasSupplyEditor();
    @Path()
    final AbstractSubTypeEditor< Supply,GasSupply,GasSupplyEditor> gasSupplyEditorWrapper = new AbstractSubTypeEditor< Supply,GasSupply,SupplyEditor.GasSupplyEditor>(gasSupplyEditor){
    @Override
    public void setValue(final Supply value){
    setValue(value,value instanceof GasSupply);
    if(!(value of instanceof GasSupply)){
    gasSupplyEditor.mpr.setVisible(false);
    } else {
    gasSupplyEditor.mpr.setVisible(true);
    }
    }
    };

    public SupplyEditor(){
    final VerticalPanel page = new VerticalPanel();
    page.add(elecSupplyEditor.profile);
    page.add(elecSupplyEditor.mtc);
    page.add(elecSupplyEditor.llf);
    page.add(elecSupplyEditor.area);
    page.add(elecSupplyEditor.code);
    page.add(gasSupplyEditor.mpr);
    initWidget(page);


    code $

    $ b $ p

    这应根据您正在编辑的子类来显示/隐藏您的字段,并将这些属性绑定到好字段。


    Let's say I have an object hierarchy like this:

    Account > Site > Supply

    An Account is an actual company, a Site is a building they have, and a Supply is either an ElecSupply or GasSupply. Supply is never instantiated and could be an abstract class in theory.

    I am using Objectify for persistence, and have a page that displays the list of Supplies for each Site, regardless of whether they are an ElecSupply or GasSupply.

    Now I am implementing the GWT Editor Framework and have come up against a problem with this polymorphic entity. How do I implement an Editor and set of sub-editors for an object like this?

    @Entity
    public class Supply implements Serializable
    {
        @Id
        protected Long id;
        @Embedded
        protected List<BillingPeriod> billingPeriods = new ArrayList<BillingPeriod>();
    
        public Supply()
        {
    
        }
    // ...
    }
    

    The subclasses: (ElecSupply has 5 unique fields and GasSupply has just one)

    @Subclass
    public class ElecSupply extends Supply implements Serializable
    {
        private String profile;
        private String mtc;
        private String llf;
        private String area;
        private String core;
    
        public ElecSupply()
        {
    
        }
    }
    


    @Subclass
    public class GasSupply extends Supply implements Serializable
    {
        private String mpr;
    
        public GasSupply()
        {
    
        }
    // ...
    }
    

    So I would like to know if anyone has any experience with this kind of structure? I have tried to make separate editors for ElecSupply and GasSupply, and then show or hide them as part of the edit page.

    The other way I was thinking about doing it would be to have a single editor (for Supply), and then load different sub-editors depending on which type of object we are editing.

    Any light shed will be gratefully received.

    解决方案

    I've already been in this case, and I've implemented the following solution :

    • First create an generic utilitary class named AbstractSubTypeEditor which will activate a specific editor when you edit one of your subclass object :

      import com.google.gwt.editor.client.CompositeEditor;
      import com.google.gwt.editor.client.Editor;
      import com.google.gwt.editor.client.EditorDelegate;
      import com.google.gwt.editor.client.LeafValueEditor;
      
      public abstract class AbstractSubTypeEditor<T, C extends T, E extends Editor<C>> implements CompositeEditor<T, C, E>, LeafValueEditor<T> {
              private EditorChain<C, E> chain;
              private T currentValue;
              private final E subEditor;
      
              /**
               * Construct an AbstractSubTypeEditor backed by the given sub-Editor.
               *
               * @param subEditor the sub-Editor that will be attached to the Editor
               *          hierarchy
               */
              public AbstractSubTypeEditor(E subEditor) {
                      this.subEditor = subEditor;
              }
      
              /**
               * Returns the sub-Editor that the OptionalFieldEditor was constructed
               * with.
               *
               * @return an {@link Editor} of type E
               */
              public E createEditorForTraversal() {
                      return subEditor;
              }
      
              public void flush() {
                      currentValue = chain.getValue(subEditor);
              }
      
              /**
               * Returns an empty string because there is only ever one sub-editor used.
               */
              public String getPathElement(E subEditor) {
                      return "";
              }
      
              public T getValue() {
                      return currentValue;
              }
      
              public void onPropertyChange(String... paths) {
              }
      
              public void setDelegate(EditorDelegate<T> delegate) {
              }
      
              public void setEditorChain(EditorChain<C, E> chain) {
                      this.chain = chain;
              }
      
              public void setValue(T value, boolean instanceOf) {
                      if (currentValue != null && value == null) {
                              chain.detach(subEditor);
                      }
                      currentValue = value;
                      if (value != null && instanceOf) {
                              chain.attach((C)value, subEditor);
                      }
              }
      }
      

    • Now you can create an Editor for Supply, containing two sub-editors and two AbstractSubTypeEditor (one for each of your subtypes) :

      public class SupplyEditor extends Composite implements Editor<Supply> {
      
              public class ElecSupplyEditor implements Editor<ElecSupply> {
                      public final TextBox profile = new TextBox();
                      public final TextBox mtc = new TextBox();
                      public final TextBox llf = new TextBox();
                      public final TextBox area = new TextBox();
                      public final TextBox core = new TextBox();
              }
              @Ignore
              final ElecSupplyEditor elecSupplyEditor = new ElecSupplyEditor();
              @Path("")
              final AbstractSubTypeEditor<Supply, ElecSupply, ElecSupplyEditor> elecSupplyEditorWrapper = new AbstractSubTypeEditor<Supply, ElecSupply, SupplyEditor.ElecSupplyEditor>(elecSupplyEditor) {
                      @Override
                      public void setValue(final Supply value) {
                              setValue(value, value instanceof ElecSupply);
                              if (!(value instanceof ElecSupply)) {
                                      elecSupplyEditor.profile.setVisible(false);
                                      elecSupplyEditor.mtc.setVisible(false);
                                      elecSupplyEditor.llf.setVisible(false);
                                      elecSupplyEditor.area.setVisible(false);
                                      elecSupplyEditor.core.setVisible(false);
                              } else {
                                      elecSupplyEditor.profile.setVisible(true);
                                      elecSupplyEditor.mtc.setVisible(true);
                                      elecSupplyEditor.llf.setVisible(true);
                                      elecSupplyEditor.area.setVisible(true);
                                      elecSupplyEditor.core.setVisible(true);
                              }
                      }
              };
      
              public class GasSupplyEditor implements Editor<GasSupply> {
                      public final TextBox mpr = new TextBox();
              }
              @Ignore
              final GasSupplyEditor gasSupplyEditor = new GasSupplyEditor();
              @Path("")
              final AbstractSubTypeEditor<Supply, GasSupply, GasSupplyEditor> gasSupplyEditorWrapper = new AbstractSubTypeEditor<Supply, GasSupply, SupplyEditor.GasSupplyEditor>(gasSupplyEditor) {
                      @Override
                      public void setValue(final Supply value) {
                              setValue(value, value instanceof GasSupply);
                              if (!(value instanceof GasSupply)) {
                                      gasSupplyEditor.mpr.setVisible(false);
                              } else {
                                      gasSupplyEditor.mpr.setVisible(true);
                              }
                      }
              };
      
              public SupplyEditor () {
                      final VerticalPanel page = new VerticalPanel();
                      page.add(elecSupplyEditor.profile);
                      page.add(elecSupplyEditor.mtc);
                      page.add(elecSupplyEditor.llf);
                      page.add(elecSupplyEditor.area);
                      page.add(elecSupplyEditor.code);
                      page.add(gasSupplyEditor.mpr);
                      initWidget(page);
              }
      }
      

    This should show/hide your fields according to the subclass you are editing, and bind the properties to the good fields.

    这篇关于如何为类型的子类实现GWT编辑器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆