How can I inherit a UiBinder class, or supplying a widget for a placeholder?

605 views
Skip to first unread message

membersound

unread,
Mar 15, 2013, 9:06:20 AM3/15/13
to google-we...@googlegroups.com
Hi,

hopefully you can help me getting some inheritance done with Ui-Binder.

My goal is to create a basic EditPanel. I want to define all styles, some fixed text, and some buttons there.
It should also have an area do display some errors. And also a placeholder where I could later place a FlowPanel with TextBoxes.

I then want to reuse this BaseEditPanel and want to supply it the FlowPanel with TextBoxes.
Also some logic should be written inside the extended Panel to validate the TextBoxes.

To get an idea of what I'm trying to do, I created the following example:


BaseEditPanel.ui.xml
<g:FlowPanel>
  <some kind of placeholder ui:field="placeholder" />

  <g:Button text="save" ui:field="save" />
  <g:Label ui:field="error" />
</g:FlowPanel>


class BaseEditPanel extends Composite {
   
    @UiField Button save;
    @UiLabel Label error;

    @UiHandler("save")
    void onSave() {
        boolean isValid = validate();
        if (!isValid) {
            error.setText("there were some errors");
        }
    }

    public abstract validate();
}

CustomEditPanel.ui.xml
<g:FlowPanel>
  <g:Label text="name" />
  <g:TextBox ui:field="name" />
</g:FlowPanel>

class CustomEditPanel {
    @UiField TextBox name;

    @Override
    boolean validate() {
        return name.getText().isEmpty() ? false : true;
    }   
}


Questions:

1) What could I use for a placeholder in BaseEditPanel?
2) How could I get the CustomEditPanel to be placed into the BaseEditPanel at the position of the placeholder?
3) I know I cannot have a normal BaseEditPanel class with an abstract method. What can I change? Make the BaseEditPanel also abstract, as it anyway should only be displayed when a Widget for the placeholder is provided?

Hope you could help

Jesse Hutton

unread,
Mar 15, 2013, 10:21:22 AM3/15/13
to google-we...@googlegroups.com
I don't think you can use inheritance with UiBinder like that. But you can achieve more or less what you're looking for, I think. Basically, you create a layout view that you can use in your primary view uibinders the same way the standard widgets are used there:

public interface MyBaseView {
  void setPresenter(BaseViewPresenter presenter);

  ... other methods base view requires ...
}

public interface MySubView extends MyBaseView {
  void setPresenter(MySubViewPresenter presenter;
  ...
}

public class BaseView extends Composite implements MyBaseView, HasWidgets {
  public interface BaseViewPresenter {
     void onButton1Clicked(ClickEvent event);
     ... etc ...
  }

  ... uibinder stuff...
  ... ui fields/elements of base view...

  /* the panel containing the sub-view */
  @UiField
  FlowPanel contentPanel;

  private BaseViewPresenter presenter;

  ...constructor...

  

  @Override
  public void add(Widget w) {
    contentPanel.add(w);
  }

  @Override
  public void clear() {
    contentPanel.clear();
  }

  @Override
  public Iterator<Widget> iterator() {
    return contentPanel.iterator();
  }

  @Override
  public boolean remove(Widget w) {
    return contentPanel.remove(w);
  }
}

The BaseView.ui.xml file has your buttons in the base view and of course the content panel, nothing exotic.

public class SubEditView extends Composite implements MySubView {

  public interface MySubViewPresenter {
    void onSave();
    ....
  }

  ... uibinder stuff ...
  ... ui fields/elements of sub view, sub view presenter declaration...

  /* the base view that wraps this sub view */
  @UiField
  BaseView baseView;

  ... constructor, class methods, click handlers delegating to presenter, etc ...
  
}

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
  xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:v="urn:import:com.example.app.client.ui">
  <v:BaseView ui:field="baseView">
    ... sub view xml content here ...
  </v:CatalogViewLayout>
</ui:UiBinder>

As for the validation you want to encapsulate, it would probably be better to put that in a presenter, but it could easily be done in an abstract presenter, allowing you to share the code that does validation (and tells the view to show errors) in onSave().

Jesse




--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-tool...@googlegroups.com.
To post to this group, send email to google-we...@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages