Редакторы GWT - выберите элемент из списка, используя оценочный ящик
У меня есть ValueAwareEditor, который содержит несколько подредакторов:
По сути, OfferDto состоит из TariffDto и Комиссии. Комиссия может быть одним из 4 подтипов, но есть только один. Обычно этот список возможных комиссий внутри TariffDto будет содержать только один элемент, но иногда он может содержать два.
public class OfferDto
{
private TariffDto tariff;
// selected from the list in the tariff
private Commission commission;
}
public class TariffDto extends EntityDto
{
// omitted for brevity...
protected List<Commission> commissions = new ArrayList<Commission>();
}
Когда комиссии содержат более одного элемента, я хочу отобразить раскрывающийся список с двумя вариантами, и добавить, что позволяет пользователю выбирать между ними, каждый раз сбрасывая комиссию в OfferDto и CommissionEditor.
Проблема в том, что при повторном вызове Commission.setValue() редактор не изменяется. Что мне здесь делать?
public class OfferEditor extends Composite implements ValueAwareEditor<OfferDto>
{
@UiField
TariffRenderer tariff;
@Ignore
@UiField
HTMLPanel panel;
@UiField
CommissionEditor commission;
@Override
public void setValue(final OfferDto value)
{
panel.clear();
List<Commission> commissions = value.getTariff().getCommissions();
if(commissions.size() == 1)
{
value.setCommission(commissions.get(0));
}
else
{
// multiple commissions
ValueListBox<Commission> dropdown = new ValueListBox<Commission>(new Renderer<Commission>()
{
@Override
public String render(Commission object)
{
return object == null ? "" : object.getName();
}
@Override
public void render(Commission object, Appendable appendable) throws IOException
{
appendable.append(render(object));
}
});
dropdown.setValue(value.getCommission());
dropdown.setAcceptableValues(commissions);
dropdown.addValueChangeHandler(new ValueChangeHandler<Commission>()
{
@Override
public void onValueChange(ValueChangeEvent<Commission> event)
{
Commission selected = event.getValue();
// this works, but the CommissionEditor that was first rendered remains
value.setCommission(selected);
}
});
panel.add(dropdown);
}
}
}
В настоящее время я отображаю список комиссий в ValueListBox, а затем, когда значение меняется, я помещаю это значение в OfferDto. Комиссия, кажется, настроена правильно, но subEditor не меняется.
Любая помощь с благодарностью.
РЕДАКТИРОВАТЬ:
CommissionEditor показывает соответствующий подредактор в зависимости от типа.
public class CommissionEditor extends Composite implements Editor<Commission>
{
private static CommissionEditorUiBinder uiBinder = GWT.create(CommissionEditorUiBinder.class);
interface CommissionEditorUiBinder extends UiBinder<Widget, CommissionEditor>
{
}
@UiField
Panel subEditorPanel;
public CommissionEditor()
{
initWidget(uiBinder.createAndBindUi(this));
}
@Ignore
final UnitRateCommissionEditor unitRateCommissionEditor = new UnitRateCommissionEditor();
@Path("")
final AbstractSubTypeEditor<Commission, UnitRateCommission, UnitRateCommissionEditor> unitRateCommissionEditorWrapper = new AbstractSubTypeEditor<Commission, UnitRateCommission, UnitRateCommissionEditor>(
unitRateCommissionEditor)
{
@Override
public void setValue(final Commission value)
{
if(value instanceof UnitRateCommission)
{
setValue(value, value instanceof UnitRateCommission);
System.out.println("UnitRateCommission setValue");
subEditorPanel.clear();
subEditorPanel.add(unitRateCommissionEditor);
}
}
};
@Ignore
final StandingChargeCommissionEditor standingChargeCommissionEditor = new StandingChargeCommissionEditor();
@Path("")
final AbstractSubTypeEditor<Commission, StandingChargeCommission, StandingChargeCommissionEditor> standingChargeCommissionEditorWrapper = new AbstractSubTypeEditor<Commission, StandingChargeCommission, StandingChargeCommissionEditor>(
standingChargeCommissionEditor)
{
@Override
public void setValue(final Commission value)
{
if(value instanceof StandingChargeCommission)
{
setValue(value, value instanceof StandingChargeCommission);
System.out.println("StandingChargeCommission setValue");
subEditorPanel.clear();
subEditorPanel.add(standingChargeCommissionEditor);
}
}
};
@Ignore
final PerMwhCommissionEditor perMwhCommissionEditor = new PerMwhCommissionEditor();
@Path("")
final AbstractSubTypeEditor<Commission, PerMwhCommission, PerMwhCommissionEditor> perMwhCommissionEditorWrapper = new AbstractSubTypeEditor<Commission, PerMwhCommission, PerMwhCommissionEditor>(
perMwhCommissionEditor)
{
@Override
public void setValue(final Commission value)
{
if(value instanceof PerMwhCommission)
{
setValue(value, value instanceof PerMwhCommission);
System.out.println("PerMwhCommission setValue");
subEditorPanel.clear();
subEditorPanel.add(perMwhCommissionEditor);
}
}
};
}
Возможное решение:
Я изменился OfferEditor
как так:
public class OfferEditor extends Composite implements Editor<OfferDto>
{
@UiField
TariffRenderer tariff;
@Path("tariff.commissions")
@UiField
CommissionsEditor commission;
}
Новый редактор CommissionsEditor
является CompositeEditor. Для этого необходимо взять список Тариф.commissions и установить выбранную комиссию в offer.commission:
public class CommissionsEditor extends Composite implements CompositeEditor<List<Commission>, Commission, CommissionEditor>
{
private static CommissionsEditorUiBinder uiBinder = GWT.create(CommissionsEditorUiBinder.class);
interface CommissionsEditorUiBinder extends UiBinder<Widget, CommissionsEditor>
{
}
private EditorChain<Commission, CommissionEditor> chain;
@UiField
FlowPanel dropdownPanel, subEditorPanel;
@Ignore
CommissionEditor subEditor;
public CommissionsEditor()
{
initWidget(uiBinder.createAndBindUi(this));
}
@Override
public void setValue(List<Commission> valueList)
{
// clear both panels
dropdownPanel.clear();
subEditorPanel.clear();
if(valueList.size() == 1)
{
// set the commission to the first in the list
Commission selected = valueList.get(0);
subEditor = new CommissionEditor();
subEditorPanel.add(subEditor);
chain.attach(selected, subEditor);
}
else if(valueList.size() > 1)
{
ValueListBox<Commission> dropdown = new ValueListBox<Commission>(new Renderer<Commission>()
{
@Override
public String render(Commission object)
{
return object == null ? "" : object.getName();
}
@Override
public void render(Commission object, Appendable appendable) throws IOException
{
appendable.append(render(object));
}
});
dropdownPanel.add(dropdown);
dropdown.setValue(valueList.get(0));
dropdown.setAcceptableValues(valueList);
dropdown.addValueChangeHandler(new ValueChangeHandler<Commission>()
{
@Override
public void onValueChange(ValueChangeEvent<Commission> event)
{
Commission selected = event.getValue();
subEditorPanel.clear();
CommissionEditor subEditor = new CommissionEditor();
subEditorPanel.add(subEditor);
chain.attach(selected, subEditor);
}
});
}
}
@Override
public void flush()
{
}
@Override
public void onPropertyChange(String... paths)
{
// TODO Auto-generated method stub
}
@Override
public void setDelegate(EditorDelegate<List<Commission>> delegate)
{
// TODO Auto-generated method stub
}
@Override
public CommissionEditor createEditorForTraversal()
{
return new CommissionEditor();
}
@Override
public String getPathElement(CommissionEditor subEditor)
{
return null;
}
@Override
public void setEditorChain(EditorChain<Commission, CommissionEditor> chain)
{
this.chain = chain;
}
}
Когда CommissionsEditor
делает раскрывающийся список и onValueChange()
вызывается, создается новый редактор, но значение комиссии никогда не устанавливается.
По какой-то причине значение выбранного субэдитора не помещается в offer.setCommission()
, я думал chain.attach()
будет выполнять это для меня?