GWT CompositeEditor - 动态切换的编辑器没有正确添加到链中 [英] GWT CompositeEditor - Dynamically switched editor not being added to chain properly
问题描述
我有一个值类型佣金
,它是更大的编辑器图表的一部分:
public class Commission实现Serializable
{
private CommissionType commissionType; //枚举
私人货币值; //自定义类型,由BigDecimal支持
私有整数乘法器;
private Integer contractMonths;
// ...
}
我想要什么要实现的最初只显示 commissionType
枚举的下拉菜单,然后选择一个合适的子编辑器根据所选值编辑其余字段:
),但这种情况稍有不同,因为我不编辑子类,他们都编辑相同的基本 Commissi在
类型上,出于某种原因,相同的方法似乎不适用于编辑相同具体类型的多个编辑器。
我目前有两个子编辑器(通过自定义接口 我看了这个问题,并试图创建 这是 用户选择 IsCommissionEditorWidget实现
编辑器<佣金>
和 IsWidget
),但它们本身有不同的子编辑器,因为 Money
可以是便士或英镑,乘数可以表示几天或几个月,以及其他变更。
CommissionEditor
CompositeEditor<委员会,佣金,编辑器< (注意:注释掉的部分是获得功能的黑客方法)。这是我得到的结果。我想通过实现
LeafValueEditor< Commiss在<$ c $>上手工调用
, setValue()
和 getValue()
c>金额乘数
和 contractMonths
):
public class CommissionEditor extends复合实现CompositeEditor<佣金,佣金,编辑&佣金>> ;, // LeafValueEditor<佣金>
{
interface Binder扩展了UiBinder< HTMLPanel,CommissionEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
CommissionTypeEditor commissionType;
@UiField
面板subEditorPanel;
私人EditorChain<佣金,编辑&佣金>>链;
private IsCommissionEditorWidget subEditor = null;
私人佣金价值=新佣金();
public CommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
commissionType.box.addValueChangeHandler(event - > setValue(new Commission(event.getValue())));
}
@Override
public void setValue(Commission value)
{
Log.warn(CommissionEditor - > setValue():value is + value);
chain.detach(subEditor);
commissionType.setValue(value.getCommissionType());
if(value.getCommissionType()!= null)
{
switch(value.getCommissionType())
{
case UNIT_RATE:
Log.info(UNIT_RATE);
subEditor = new UnitRateCommissionEditor();
休息;
case STANDING_CHARGE:
Log.info(STANDING_CHARGE);
subEditor = new StandingChargeCommissionEditor();
休息;
case PER_MWH:
Log.info(PER_MWH);
// TODO
break;
case SINGLE_PAYMENT:
Log.info(SINGLE_PAYMENT);
// TODO
break;
}
this.value = value;
subEditorPanel.clear();
// subEditor.setValue(value);
subEditorPanel.add(subEditor);
chain.attach(value,subEditor);
}
}
// @覆盖
// public Commission getValue()
// {
// if(subEditor!= null)
// {
// return subEditor.getValue();
//}
// else
// {
//返回值;
//}
//}
@Override
public void flush()
{
this.value = chain.getValue(副主编);
}
@Override
public void setEditorChain(EditorChain< Commission,Editor< Commission>>链)
{
this.chain = chain;
}
@Override
公共编辑器<佣金> createEditorForTraversal()
{
return subEditor;
$ b @Override
public String getPathElement(Editor& Commission> commissionEditor)
{
return;
}
@Override
public void onPropertyChange(String ... strings)
{
}
@Override
public void setDelegate(EditorDelegate< Commission> editorDelegate)
{
}
}
IsCommissionEditorWidget
界面,它定义了每个子编辑器的合同,添加到面板:
public interface IsCommissionEditorWidget extends Editor< Commission>,IsWidget
{
UnitRateCommissionEditor
CommissionType.UNIT_RATE
,我想将其添加到编辑器链中以应用于剩余的3个字段:
< pre $ $ {
interface Binder extends UiBinder< Widget,UnitRateCommissionEditor& GT;
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
MoneyPenceBox金额;
@UiField
IntegerBox乘数;
@UiField
IntegerBox contractMonths;
public UnitRateCommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
}
// @Override
// public void setValue(Commission commission)
// {
// amount.setValue(commission.getAmount ());
// multiplier.setValue(commission.getMultiplier());
// contractMonths.setValue(commission.getContractMonths());
//}
//
// @覆盖
//公共委员会getValue()
// {
//返回新委员会(CommissionType .UNIT_RATE,amount.getValue(),multiplier.getValue(),contractMonths.getValue());
//
}
StandingChargeCommissionEditor
当选择 CommissionType.STANDING_CHARGE
时,我想要这个(UiBinders也有点不同,但主要区别在于 MoneyPoundsBox
而不是 MoneyPenceBox
):
public class StandingChargeCommissionEditor扩展Composite实现IsCommissionEditorWidget
返回一个带有未定义
{
interface Binder扩展了UiBinder< Widget,StandingChargeCommissionEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
MoneyPoundsBox金额;
@UiField
IntegerBox乘数;
@UiField
IntegerBox contractMonths;
public StandingChargeCommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
}
// @Override
// public void setValue(Commission commission)
// {
// amount.setValue(commission.getAmount ());
// multiplier.setValue(commission.getMultiplier());
// contractMonths.setValue(commission.getContractMonths());
//}
//
// @覆盖
//公共委员会getValue()
// {
//返回新委员会(CommissionType .STANDING_CHARGE,amount.getValue(),multiplier.getValue(),contractMonths.getValue());
$ / code $ / pre
目前<$ c $父类型(包含Commission
的编辑类型)的c> flush()金额
,乘数
和contractMonths
。我可以将这些值传入和传出的唯一方法是在(注释代码)中手动编码它。
- 我的子编辑器是否正确连接到
EditorChain
?
编辑1:解决方案建议
我决定创建一个新的中间类,分别包装每个子类型佣金,使用 AbstractSubTypeEditor
就像我在这个问题中所做的那样。
CommissionEditor
仍然是 CompositeEditor
,但它只有一个或零个子编辑器,它只会是 CommissionSubtypeEditor
:
public class CommissionEditor extends复合实现CompositeEditor< Commission,Commission,CommissionSubtypeEditor> ;, LeafValueEditor<委员会>
{
interface Binder扩展了UiBinder< HTMLPanel,CommissionEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
@Ignore
CommissionTypeEditor commissionType;
@UiField
面板subEditorPanel;
private EditorChain<佣金,佣金子类型编辑器>链;
@Ignore
@Path()
CommissionSubtypeEditor subEditor = new CommissionSubtypeEditor();
私人佣金价值;
public CommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
commissionType.box.addValueChangeHandler(event - > setValue(new Commission(event.getValue())));
}
@Override
public void setValue(Commission value)
{
Log.warn(CommissionEditor - > setValue():value is + value);
commissionType.setValue(value.getCommissionType());
if(value.getCommissionType()!= null)
{
this.value = value;
subEditorPanel.clear();
subEditorPanel.add(subEditor);
chain.attach(value,subEditor);
$ b @Override
public Commission getValue()
{
Log.info(CommissionEditor - > ; getValue:+ value);
返回值;
}
@Override
public void flush()
{
chain.getValue(subEditor);
}
@Override
public void setEditorChain(EditorChain< Commission,CommissionSubtypeEditor>链)
{
this.chain = chain;
}
@Override
public CommissionSubtypeEditor createEditorForTraversal()
{
return subEditor;
}
@Override
public String getPathElement(CommissionSubtypeEditor commissionEditor)
{
return;
}
@Override
public void onPropertyChange(String ... strings)
{
}
@Override
public void setDelegate(EditorDelegate< Commission> editorDelegate)
{
}
}
AbstractSubTypeEditor
信用转至 Florent Bayle 。如果没有亚型是多态的,我不认为我可以使用它,但它似乎很好。基本上允许包装子编辑器,如将在 CommissionSubtypeEditor
下显示。
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;
public AbstractSubTypeEditor(E subEditor)
{
this.subEditor = subEditor;
}
@Override
public E createEditorForTraversal()
{
return subEditor;
}
@Override
public void flush()
{
currentValue = chain.getValue(subEditor);
}
@Override
public String getPathElement(E subEditor)
{
return;
}
@Override
public T getValue()
{
return currentValue;
}
@Override
public void onPropertyChange(String ... paths)
{
}
@Override
public void setDelegate(EditorDelegate< T> delegate)
{
}
@Override
public void setEditorChain(EditorChain< C,E> chain)
{
this.chain = chain;
$ b 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);
}
}
}
CommissionSubtypeEditor
public class CommissionSubtypeEditor扩展Composite implements Editor< Commission>
{
interface Binder扩展了UiBinder< HTMLPanel,CommissionSubtypeEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
面板subEditorPanel;
@Ignore
final UnitRateCommissionEditor unitRateCommissionEditor = new UnitRateCommissionEditor();
@Path()
final AbstractSubTypeEditor<佣金,佣金,UnitRateCommissionEditor> unitRateWrapper = new AbstractSubTypeEditor< Commission,Commission,
UnitRateCommissionEditor>(unitRateCommissionEditor)
{
@Override
public void setValue(Commission value)
{
if (value.getCommissionType()== CommissionType.UNIT_RATE)
{
Log.info(unitRateWrapper setValue);
setValue(value,true);
subEditorPanel.clear();
subEditorPanel.add(unitRateCommissionEditor);
}
}
};
@Ignore
Standing StandingChargeCommissionEditor standingChargeCommissionEditor = new StandingChargeCommissionEditor();
@Path()
final AbstractSubTypeEditor<佣金,佣金,StandingChargeCommissionEditor> standingChargeWrapper = new AbstractSubTypeEditor< Commission,
Commission,StandingChargeCommissionEditor>(standingChargeCommissionEditor)
{
@Override
public void setValue(Commission value)
{
if (value.getCommissionType()== CommissionType.STANDING_CHARGE)
{
Log.info(standingChargeWrapper setValue);
setValue(value,true);
subEditorPanel.clear();
subEditorPanel.add(standingChargeCommissionEditor);
}
}
};
public CommissionSubtypeEditor()
{
initWidget(uiBinder.createAndBindUi(this));
$ b UnitRateCommissionEditor和StandingChargeCommissionEditor
简单和实现编辑器<佣金>
:
public class UnitRateCommissionEditor扩展了Composite implements Editor< Commission>
{
interface Binder扩展了UiBinder< Widget,UnitRateCommissionEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
MoneyPenceBox金额;
@UiField
IntegerBox乘数;
@UiField
IntegerBox contractMonths;
public UnitRateCommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
}
}
几乎就有... p>
public class StandingChargeCommissionEditor扩展了Composite implements Editor< Commission>
{
interface Binder扩展了UiBinder< Widget,StandingChargeCommissionEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
MoneyPoundsBox金额;
@UiField
IntegerBox乘数;
@UiField
IntegerBox contractMonths;
public StandingChargeCommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
}
}
这是行得通的,与当我在 CompositeEditor
本身中有 AbstractSubtypeEditor
时,我很早就试过。我相信那里的问题是编辑器本身不能调用 setValue()
。对吗?
评论,批评和建议非常感谢。
解决方案您的复合编辑器被声明为 CompositeEditor< Commission,Commission,Editor< Commission>>< / code>,这意味着该链将被期望提供一些任意编辑与LT;委员会>
。这是一个问题,因为编译器会检查类型 Editor&Editor; Commission>
并且没有看到子编辑器,也没有其他编辑器接口( LeafValueEditor , ValueAwareEditor
等),因此不会与其绑定。
你提到你有两个不同的编辑器< Commission>
子类型 - 但代码生成器不能提前知道这一点,并且检查每个可能的子类型并构建任何可能的布线是没有意义的这可能适合。无论好坏,编辑器框架都是静态的 - 预先声明一切,然后生成器将只创建所需的内容。
两个选项我看到:
- 或者创建两个不同的CompositeEditor,每个子编辑器类型一个,并且确保一次只附加一个,或
- 从两个编辑器中提取一个通用超类型/接口,它们具有一致命名和类型化的方法,它们返回相同的编辑器类型(从不简单地返回
Editor< Foo>
出于与上述相同的原因)。这可能会很难做到,但可能你可以用 ValueAwareEditor
来包装,并使用 setValue
和 flush()
来详细描述。
I've got a value type Commission
that's part of a larger editor graph:
public class Commission implements Serializable
{
private CommissionType commissionType; // enum
private Money value; // custom type, backed by BigDecimal
private Integer multiplier;
private Integer contractMonths;
// ...
}
What I want to achieve is to initially only show the dropdown for the commissionType
enum, and then select an appropriate sub-editor to edit the rest of the fields based on the value selected:
I have previously implemented multiple subtype editors (see question here) using an AbstractSubTypeEditor
but this case is slightly different as I am not editing subclasses, they all edit the same basic Commission
type, and for some reason the same method does not seem to work with multiple editors that edit the same concrete type.
I currently have two sub-editors (both implement Editor<Commission>
and IsWidget
via a custom interface IsCommissionEditorWidget
) but they have different sub-editors themselves, as the Money
can be in either pence or pounds, and the multiplier can represent days or months, among other changes.
CommissionEditor
I have looked at the similar problem in this question and tried to create a CompositeEditor<Commission, Commission, Editor<Commission>>
.
This is what I've got so far (note the commented out parts are the hacked way of getting the functionality I want, by implementing LeafValueEditor<Commission>
and manually calling setValue()
and getValue()
on amount
, multiplier
and contractMonths
):
public class CommissionEditor extends Composite implements CompositeEditor<Commission, Commission, Editor<Commission>>, //LeafValueEditor<Commission>
{
interface Binder extends UiBinder<HTMLPanel, CommissionEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
CommissionTypeEditor commissionType;
@UiField
Panel subEditorPanel;
private EditorChain<Commission, Editor<Commission>> chain;
private IsCommissionEditorWidget subEditor = null;
private Commission value = new Commission();
public CommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
commissionType.box.addValueChangeHandler(event -> setValue(new Commission(event.getValue())));
}
@Override
public void setValue(Commission value)
{
Log.warn("CommissionEditor -> setValue(): value is " + value);
chain.detach(subEditor);
commissionType.setValue(value.getCommissionType());
if(value.getCommissionType() != null)
{
switch(value.getCommissionType())
{
case UNIT_RATE:
Log.info("UNIT_RATE");
subEditor = new UnitRateCommissionEditor();
break;
case STANDING_CHARGE:
Log.info("STANDING_CHARGE");
subEditor = new StandingChargeCommissionEditor();
break;
case PER_MWH:
Log.info("PER_MWH");
// TODO
break;
case SINGLE_PAYMENT:
Log.info("SINGLE_PAYMENT");
// TODO
break;
}
this.value = value;
subEditorPanel.clear();
// subEditor.setValue(value);
subEditorPanel.add(subEditor);
chain.attach(value, subEditor);
}
}
// @Override
// public Commission getValue()
// {
// if(subEditor != null)
// {
// return subEditor.getValue();
// }
// else
// {
// return value;
// }
// }
@Override
public void flush()
{
this.value = chain.getValue(subEditor);
}
@Override
public void setEditorChain(EditorChain<Commission, Editor<Commission>> chain)
{
this.chain = chain;
}
@Override
public Editor<Commission> createEditorForTraversal()
{
return subEditor;
}
@Override
public String getPathElement(Editor<Commission> commissionEditor)
{
return "";
}
@Override
public void onPropertyChange(String... strings)
{
}
@Override
public void setDelegate(EditorDelegate<Commission> editorDelegate)
{
}
}
This is the IsCommissionEditorWidget
interface that defines the contract of each sub-editor also being able to be added to a panel:
public interface IsCommissionEditorWidget extends Editor<Commission>, IsWidget
{
}
UnitRateCommissionEditor
When the user selects CommissionType.UNIT_RATE
, I want to add this to the editor chain to apply to the 3 remaining fields:
public class UnitRateCommissionEditor extends Composite implements IsCommissionEditorWidget
{
interface Binder extends UiBinder<Widget, UnitRateCommissionEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
MoneyPenceBox amount;
@UiField
IntegerBox multiplier;
@UiField
IntegerBox contractMonths;
public UnitRateCommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
}
// @Override
// public void setValue(Commission commission)
// {
// amount.setValue(commission.getAmount());
// multiplier.setValue(commission.getMultiplier());
// contractMonths.setValue(commission.getContractMonths());
// }
//
// @Override
// public Commission getValue()
// {
// return new Commission(CommissionType.UNIT_RATE, amount.getValue(), multiplier.getValue(), contractMonths.getValue());
// }
}
StandingChargeCommissionEditor
When CommissionType.STANDING_CHARGE
is selected I want this one (The UiBinders are also a bit different, but the main difference is the MoneyPoundsBox
instead of the MoneyPenceBox
):
public class StandingChargeCommissionEditor extends Composite implements IsCommissionEditorWidget
{
interface Binder extends UiBinder<Widget, StandingChargeCommissionEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
MoneyPoundsBox amount;
@UiField
IntegerBox multiplier;
@UiField
IntegerBox contractMonths;
public StandingChargeCommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
}
// @Override
// public void setValue(Commission commission)
// {
// amount.setValue(commission.getAmount());
// multiplier.setValue(commission.getMultiplier());
// contractMonths.setValue(commission.getContractMonths());
// }
//
// @Override
// public Commission getValue()
// {
// return new Commission(CommissionType.STANDING_CHARGE, amount.getValue(), multiplier.getValue(), contractMonths.getValue());
// }
}
Currently the flush()
of the parent type (the type being edited that contains the Commission
) returns a Commission with an undefined amount
, multiplier
and contractMonths
. The only way I can get those values to be passed in and out is to manually code it in (the commented code).
- Is my sub-editor being attached to the
EditorChain
correctly?
Edit 1: Solution Proposed
I decided to create a new intermediate class that would wrap each subtype commission separately, using AbstractSubTypeEditor
like I did in this question.
CommissionEditor
Still a CompositeEditor
, but it only ever has one or zero sub-editors, which will only ever be a CommissionSubtypeEditor
:
public class CommissionEditor extends Composite implements CompositeEditor<Commission, Commission, CommissionSubtypeEditor>, LeafValueEditor<Commission>
{
interface Binder extends UiBinder<HTMLPanel, CommissionEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
@Ignore
CommissionTypeEditor commissionType;
@UiField
Panel subEditorPanel;
private EditorChain<Commission, CommissionSubtypeEditor> chain;
@Ignore
@Path("")
CommissionSubtypeEditor subEditor = new CommissionSubtypeEditor();
private Commission value;
public CommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
commissionType.box.addValueChangeHandler(event -> setValue(new Commission(event.getValue())));
}
@Override
public void setValue(Commission value)
{
Log.warn("CommissionEditor -> setValue(): value is " + value);
commissionType.setValue(value.getCommissionType());
if(value.getCommissionType() != null)
{
this.value = value;
subEditorPanel.clear();
subEditorPanel.add(subEditor);
chain.attach(value, subEditor);
}
}
@Override
public Commission getValue()
{
Log.info("CommissionEditor -> getValue: " + value);
return value;
}
@Override
public void flush()
{
chain.getValue(subEditor);
}
@Override
public void setEditorChain(EditorChain<Commission, CommissionSubtypeEditor> chain)
{
this.chain = chain;
}
@Override
public CommissionSubtypeEditor createEditorForTraversal()
{
return subEditor;
}
@Override
public String getPathElement(CommissionSubtypeEditor commissionEditor)
{
return "";
}
@Override
public void onPropertyChange(String... strings)
{
}
@Override
public void setDelegate(EditorDelegate<Commission> editorDelegate)
{
}
}
AbstractSubTypeEditor
Credit goes to Florent Bayle for this class. I didn't think I could use it without the subtypes being polymorphic but it seems to work great. Essentially allows wrapping of sub-editors as will be show in CommissionSubtypeEditor
next.
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;
public AbstractSubTypeEditor(E subEditor)
{
this.subEditor = subEditor;
}
@Override
public E createEditorForTraversal()
{
return subEditor;
}
@Override
public void flush()
{
currentValue = chain.getValue(subEditor);
}
@Override
public String getPathElement(E subEditor)
{
return "";
}
@Override
public T getValue()
{
return currentValue;
}
@Override
public void onPropertyChange(String... paths)
{
}
@Override
public void setDelegate(EditorDelegate<T> delegate)
{
}
@Override
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);
}
}
}
CommissionSubtypeEditor
public class CommissionSubtypeEditor extends Composite implements Editor<Commission>
{
interface Binder extends UiBinder<HTMLPanel, CommissionSubtypeEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
Panel subEditorPanel;
@Ignore
final UnitRateCommissionEditor unitRateCommissionEditor = new UnitRateCommissionEditor();
@Path("")
final AbstractSubTypeEditor<Commission, Commission, UnitRateCommissionEditor> unitRateWrapper = new AbstractSubTypeEditor<Commission, Commission,
UnitRateCommissionEditor>(unitRateCommissionEditor)
{
@Override
public void setValue(Commission value)
{
if(value.getCommissionType() == CommissionType.UNIT_RATE)
{
Log.info("unitRateWrapper setValue");
setValue(value, true);
subEditorPanel.clear();
subEditorPanel.add(unitRateCommissionEditor);
}
}
};
@Ignore
final StandingChargeCommissionEditor standingChargeCommissionEditor = new StandingChargeCommissionEditor();
@Path("")
final AbstractSubTypeEditor<Commission, Commission, StandingChargeCommissionEditor> standingChargeWrapper = new AbstractSubTypeEditor<Commission,
Commission, StandingChargeCommissionEditor>(standingChargeCommissionEditor)
{
@Override
public void setValue(Commission value)
{
if(value.getCommissionType() == CommissionType.STANDING_CHARGE)
{
Log.info("standingChargeWrapper setValue");
setValue(value, true);
subEditorPanel.clear();
subEditorPanel.add(standingChargeCommissionEditor);
}
}
};
public CommissionSubtypeEditor()
{
initWidget(uiBinder.createAndBindUi(this));
}
}
UnitRateCommissionEditor and StandingChargeCommissionEditor
Both simple and implement Editor<Commission>
:
public class UnitRateCommissionEditor extends Composite implements Editor<Commission>
{
interface Binder extends UiBinder<Widget, UnitRateCommissionEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
MoneyPenceBox amount;
@UiField
IntegerBox multiplier;
@UiField
IntegerBox contractMonths;
public UnitRateCommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
}
}
almost there...
public class StandingChargeCommissionEditor extends Composite implements Editor<Commission>
{
interface Binder extends UiBinder<Widget, StandingChargeCommissionEditor>
{
}
private static Binder uiBinder = GWT.create(Binder.class);
@UiField
MoneyPoundsBox amount;
@UiField
IntegerBox multiplier;
@UiField
IntegerBox contractMonths;
public StandingChargeCommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
}
}
This does work and is similar to something I tried very early on when I had the AbstractSubtypeEditor
s in the CompositeEditor
itself. The problem there I believe was that the editor could not call setValue()
on itself. Am I right?
Comments, criticisms and advice greatly appreciated.
解决方案 Your composite editor is declared as CompositeEditor<Commission, Commission, Editor<Commission>>
, which means that the chain will be expected to provide some arbitrary Editor<Commission>
. This is a problem, since the compiler inspects the type Editor<Commission>
and sees no sub-editors, and no other editor interfaces (LeafValueEditor
, ValueAwareEditor
, etc), so binds nothing to it.
You mention that you have two different Editor<Commission>
subtypes - but the codegenerator can't know this ahead of time, and it wouldn't make sense to inspect every possible subtype and build any possible wiring that could fit. For better or worse, the editor framework is intended to be static - declare everything up-front, and then the generator will create only exactly what is needed.
Two options that I see:
- either create two different CompositeEditors, one for each sub-editor type, and just make sure you only attach one at a time, or
- extract a common supertype/interface from both editors, that have consistently named and typed methods which return the same editor types (never returning simply
Editor<Foo>
for the same reason as above). This likely will be harder to do, but its possible that you could wrap things up with ValueAwareEditor
and use setValue
and flush()
to paper over the details.
这篇关于GWT CompositeEditor - 动态切换的编辑器没有正确添加到链中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!