假设我有一个像这样的对象层次结构:
帐户 > 站点 > 供应
帐户是一个实际的公司,站点是他们拥有的建筑物,供应是 ElecSupply
或GasSupply
。 Supply 永远不会被实例化,理论上可能是一个抽象类。
我使用 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()
{
}
// ...
}
所以我想知道是否有人有这种结构的经验?我尝试为 ElecSupply
制作单独的编辑器和GasSupply
,然后将它们显示或隐藏为编辑页面的一部分。
我考虑的另一种方法是使用一个编辑器(用于 Supply),然后根据我们正在编辑的对象类型加载不同的子编辑器。
任何光棚都将受到感激的接收。
最佳答案
我已经遇到过这种情况,并且我已经实现了以下解决方案:
首先创建一个名为 AbstractSubTypeEditor 的通用实用类,当您编辑子类对象之一时,它将激活特定的编辑器:
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); } } }
现在您可以为 Supply 创建一个编辑器,其中包含两个子编辑器和两个 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); } }
这应该根据您正在编辑的子类显示/隐藏您的字段,并将属性绑定(bind)到好的字段。
关于java - 如何为类型的子类实现 GWT 编辑器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13346308/