javagwtgwt-editors

GWT Editors - how to add N sub-editors of the same type based on a Collection


I have an object, Supply, that can either be an ElecSupply or GasSupply (see related question).

Regardless of which subclass is being edited, they all have a list of BillingPeriods.

I now need to instantiate N number of BillingPeriodEditors based on the contents of that list, and am pretty baffled as to how I should do it.

I am using GWTP. Here is the code of the SupplyEditor I have just got working:

public class SupplyEditor extends Composite implements ValueAwareEditor<Supply>
{
    private static SupplyEditorUiBinder uiBinder = GWT.create(SupplyEditorUiBinder.class);

    interface SupplyEditorUiBinder extends UiBinder<Widget, SupplyEditor>
    {
    }

    @Ignore
    final ElecSupplyEditor elecSupplyEditor = new ElecSupplyEditor();

    @Path("")
    final AbstractSubTypeEditor<Supply, ElecSupply, ElecSupplyEditor> elecSupplyEditorWrapper = new AbstractSubTypeEditor<Supply, ElecSupply, ElecSupplyEditor>(
            elecSupplyEditor)
    {
        @Override
        public void setValue(final Supply value)
        {
            setValue(value, value instanceof ElecSupply);
            if(!(value instanceof ElecSupply))
            {
                showGasFields();
            }
            else
            {
                showElecFields();
            }
        }
    };

    @Ignore
    final GasSupplyEditor gasSupplyEditor = new GasSupplyEditor();

    @Path("")
    final AbstractSubTypeEditor<Supply, GasSupply, GasSupplyEditor> gasSupplyEditorWrapper = new AbstractSubTypeEditor<Supply, GasSupply, GasSupplyEditor>(
            gasSupplyEditor)
    {
        @Override
        public void setValue(final Supply value)
        {
            setValue(value, value instanceof GasSupply);
            if(!(value instanceof GasSupply))
            {
                showElecFields();
            }
            else
            {
                showGasFields();
            }
        }
    };

    @UiField
    Panel elecPanel, gasPanel, unitSection;

    public SupplyEditor()
    {
        initWidget(uiBinder.createAndBindUi(this));

        gasPanel.add(gasSupplyEditor);
        elecPanel.add(elecSupplyEditor);
    }

    // functions to show and hide depending on which type...

    @Override
    public void setValue(Supply value)
    {
        if(value instanceof ElecSupply)
        {
            showElecFields();
        }
        else if(value instanceof GasSupply)
        {
            showGasFields();
        }
        else
        {
            showNeither();
        }
    }
}

Now, as the list of BillingPeriods is a part of any Supply, I presume the logic for this should be in the SupplyEditor.

I got some really good help on the thread How to access PresenterWidget fields when added dynamically, but that was before I had implemented the Editor Framework at all, so I think the logic is in the wrong places.

Any help greatly appreciated. I can post more code (Presenter and View) but I didn't want to make it too hard to read and all they do is get the Supply from the datastore and call edit() on the View.

I have had a look at some examples of ListEditor but I don't really get it!


Solution

  • You need a ListEditor

    It depends of how you want to present them in your actual view, but the same idea apply:

    public class BillingPeriodListEditor implements isEditor<ListEditor<BillingPeriod,BillingPeriodEditor>>, HasRequestContext{
       private class BillingPeriodEditorSource extends EditorSource<BillingPeriodEditor>{
          @Override
          public EmailsItemEditor create(final int index) {
             // called each time u add or retrive new object on the list
             // of the @ManyToOne or @ManyToMany
          }
          @Override
          public void dispose(EmailsItemEditor subEditor) {
             // called each time you remove the object from the list
          }
          @Override
          public void setIndex(EmailsItemEditor editor, int index) {
             // i would suggest track the index of the subeditor. 
          }
       }
    
       private ListEditor<BillingPeriod, BillingPeriodEditor> listEditor = ListEditor.of(new BillingPeriodEditorSource ());
    
       // on add new one ...
       // apply or request factory 
       // you must implement the HasRequestContext to
       // call the create.(Proxy.class)
       public void createNewBillingPeriod(){
          // create a new one then add to the list
          listEditor.getList().add(...)
       }
    }
    
    public class BillingPeriodEditor implements Editor<BillingPeriod>{
        // edit you BillingPeriod object
    }
    

    Then in you actual editor edit as is in the path Example getBillingPeriods();

    BillingPeriodListEditor billingPeriods = new BillingPeriodListEditor ();
    
    
    // latter on the clickhandler
    billingPeriods.createNewBillingPeriod()
    

    You are done now.