2012-11-12 30 views
2

比方說,我有一個對象的層次結構是這樣的:如何爲類型的子類實現GWT編輯器?

帳戶>網站>供應

的帳戶是一個真實的公司,一個網站是一個建築,他們已經和一個電源或者是一個ElecSupplyGasSupply。供應從未被實例化,理論上可能是一個抽象類。

我使用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個獨特的領域和氣體供應只有一個)

@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分別編輯編輯器,然後將它們顯示或隱藏爲編輯頁面的一部分。

我想要做的另一種方式是使用單個編輯器(對於Supply),然後根據我們正在編輯的對象類型加載不同的子編輯器。

任何燈光棚將受到感謝。

回答

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正在尋找Supply的profile,mtc,llf,area,core和mpr字段的getters,當它們在ElecSupply和GasSupply的子類中時。我該如何解決這個問題? – slugmandrew

+0

好吧,我明白了。也許OptionalFieldEditor會幫你嗎? – koma

相關問題