GWT CompositeEditor - 动态切换的编辑器没有正确添加到链中 [英] GWT CompositeEditor - Dynamically switched editor not being added to chain properly

查看:169
本文介绍了GWT CompositeEditor - 动态切换的编辑器没有正确添加到链中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个值类型佣金,它是更大的编辑器图表的一部分:

  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 AbstractSubtypeEditors 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屋!

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