2012-11-12 4 views
2

의 나는이 같은 객체 계층 구조 있다고 가정 해 봅시다 :유형의 하위 클래스 용 GWT 편집기를 구현하는 방법은 무엇입니까?

계정> 사이트> 공급

계정이 실제 회사 사이트들이 가지고 건물이며, 공급은 어느 쪽 ElecSupply 또는 GasSupply. 공급은 결코 인스턴스화되지 않으며 이론 상 추상적 클래스 일 수 있습니다.

지속성을 위해 Objectify를 사용 중이며 ElecSupply 또는 GasSupply인지 여부에 관계없이 각 사이트의 소모품 목록을 표시하는 페이지가 있습니다.

이제 GWT Editor Framework을 구현 중이며이 다형성 엔티티의 문제가 발생했습니다. 이와 같은 객체에 대해 편집기와 하위 편집기 집합을 구현하려면 어떻게해야합니까?

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

    public Supply() 
    { 

    } 
// ... 
} 

서브 클래스 : (ElecSupply 5 개 고유의 필드를 가지고 있으며, GasSupply이 하나있다)

@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() 
    { 

    } 
// ... 
} 

그래서 사람이 종류의 어떤 경험이 있는지 알고 싶습니다 구조? ElecSupplyGasSupply에 대해 별도의 편집기를 만든 다음 편집 페이지의 일부로 표시하거나 숨기려고했습니다.

내가 생각한 다른 방법은 하나의 편집기 (공급 용)를 사용하고 편집중인 개체 유형에 따라 다른 하위 편집기를로드하는 것입니다.

모든 창고가 기꺼이 받아 들여집니다.

답변

7

이미이 경우 봤는데, 나는 다음과 같은 솔루션을 구현했습니다 : 당신이 당신의 서브 클래스 중 하나를 편집 할 때

  • 먼저 특정 편집기를 활성화 AbstractSubTypeEditor라는 일반적인 utilitary 클래스를 만듭니다 목적 :

    :

    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); 
           } 
         } 
    } 
    
  • 지금 당신이 두 개의 하위 편집자와 두 AbstractSubTypeEditor (당신의 하위 유형 각각에 대해 하나)를 포함, 공급을위한 편집기를 만들 수 있습니다

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

편집중인 하위 클래스에 따라 필드를 표시하거나 숨기고 속성을 좋은 필드에 바인딩해야합니다.

+0

지금까지 훌륭하게 작동하는 것 같습니다. 환상적인 답변 주셔서 감사합니다. – slugmandrew

2

당신의 SupplyEditor는 ValueAwareEditor<Supply>을 구현할 수 있습니다.

이렇게하면 편집기 프레임 워크가 setValue(Supply supply)에서 편집중인 실제 값을 전달합니다. setValue(Supply supply)의 구현에서 공급 유형을 검사하고 추가 관련 필드를 표시하거나 숨길 수 있습니다.

+0

도움 주셔서 감사합니다. 나는 이것을 시도하고 있지만 GWT는 ElecSupply 서브 클래스와 GasSupply 서브 클래스에있을 때 Supply, profile, mtc, llf, area, core 및 mpr 필드에 대한 getter를 찾고있다.이것을 어떻게 얻을 수 있습니까? – slugmandrew

+0

알았어. 어쩌면 OptionalFieldEditor가 도움이 될까요? – koma