3

One common design I have with GWT is to create a widget which contains two children: A and B.

I declare these two widgets A and B in the uibinder file associated to my main widget.

What I want to do is to load or not widget A depending on an if statement.

Ideal approach is to set provided=true for widget A and to set widget A to null when I want to not load this widget. But GWT throws an error.

Is there a way to declare widgets in uibinder and then not loading them ?

thanks

EDIT: after a lot of discussions, an ideal approach is to declared a field "provided=true" and "optional=true" when optional=true, createAndBindUI must not throw an Exception if the field is null. This is a clean approach.

If you think that this feature must exists in GWT, please star this issue: http://code.google.com/p/google-web-toolkit/issues/detail?id=5699

EDIT 2 : using the LazyPanel as described by Thomas seems to be a better way to handle this.

Jerome Cance
  • 8,103
  • 12
  • 53
  • 106

3 Answers3

5

I stumbled on the GWT issue, which led me here, so here's my take on it, 20 months later.

Use a LazyPanel and set it to visible="false" so that it's content is not built until you need it (simply call setVisible(true) to reveal it, triggerring the lazy-initialization of its content.

LazyPanel is fully integrated with UiBinder so that you declare its content in the same UiBinder template, as if it were a SimplePanel, without even bothering creating a subclass of LazyPanel. See https://developers.google.com/web-toolkit/doc/2.4/DevGuideUiBinder#Lazy

Thomas Broyer
  • 64,353
  • 7
  • 91
  • 164
  • 1
    yep, seems to be an excellent way to do it. I think this is the best approach. 20 months later, I update my vote ;) (Thomas, you are the winner on most of my answers about gwt, if you come to Montpellier one of these days, let me know, I'll pay you a drink !) – Jerome Cance Aug 24 '12 at 08:54
  • Note that I haven't tried it with a `@UiField(provided=true)` widget in the content, and this isn't unit-tested either. – Thomas Broyer Aug 24 '12 at 09:02
  • @ThomasBroyer, why does LazyPanel allow only a single child? I don't see any reason for it not to have multiple children. Now I have to wrap children with `SimplePanel` and it makes layout too clumsy. – Konstantin Milyutin Jan 26 '15 at 13:05
1

I would revert the logic. If you don't need the widget remove it

widget.removeFromParent();

I think it's a cleaner approach, since the UIBinder automatically defines and creates them.

Carlos Tasada
  • 4,438
  • 1
  • 23
  • 26
  • I thought of this solution but there is performance problem: instanciate and remove widget: two DOM manipulations. Another problem is that if I need to provide the widget by provided=true if the constructor is not empty and in one case I don't want to provide this (I don't know what instance to provide) – Jerome Cance Dec 01 '10 at 14:54
1

Since conditionals are not allowed in a UiBinder XML I'd suggest you define placeholders (i.e., panels) in your ui.xml, have a reference to them in your view class and decide there whether a specific widget needs to be created and added or not.

This is a common approach when using MVP pattern with nested presenters.

EDIT:

Until your request has been implemented by the GWT developers you could extend the FlowPanel and overwrite the add(Widget) method to check for null as in:

public class ExtendedFlowPanel extends FlowPanel {

    public ExtendedFlowPanel() {
        super();
    }

    @Override
    public void add(Widget w) {
        if (w != null) {
            super.add(w);
        }
    }
}

This way you can use provided = true and pass null to the panel.

z00bs
  • 7,518
  • 4
  • 34
  • 53
  • the problem with this solution is we can't use the simple handler definition and we can't design the widget in uibinder – Jerome Cance Dec 01 '10 at 14:51
  • For simple event handlers: there I see no solution except doing it the 'old' way (which still works great :)). For the styling: do it in code (is a pain, I know) or style the widget (those parts that are reusable) in its UiBinder XML. Or isn't that possible? – z00bs Dec 01 '10 at 14:59
  • ...oooor (just an idea): create a new `Composite` containing those two widgets A and B and let it decide what to show when and how... – z00bs Dec 01 '10 at 15:07
  • no, I can't do it, because this is an example, this is not always the same widget A and B ;) But good try ! I think I will open an issue in GWT to provide a good and clean solution for this problem (for example, if provided=true return a null widget, do not load it) – Jerome Cance Dec 01 '10 at 15:13
  • lol I was thinking you want a vote up ;) So I ask a vote up too ! My english is not fluent, so sometimes I don't understand well ;) – Jerome Cance Dec 01 '10 at 15:37
  • 1
    :) no not really. I think the question is good and I'm trying to help finding a valid solution. Is the extended flow panel of any use? It worked in my small example. – z00bs Dec 01 '10 at 16:34
  • That's a simple and clean solution. I would love it if it runs ;) And this is not the case. I've got an error which is: Caused by: java.lang.NullPointerException: null at com.myCompany_MyModuleUiBinderImpl.createAndBindUi(MyModuleUiBinderImpl.java:34) – Jerome Cance Dec 01 '10 at 17:17
  • Give me some minutes. I'm currently on the iphone on which coding isn't that much of fun :). I'll post my example. – z00bs Dec 01 '10 at 17:28
  • Ok, I think I know what you've done: with really simple widgets it runs, but when this widget has a property or children, it does not run. Try your example by adding Label with text in your ExtendedFlowPanel. It will not run, isn't it ? The cause is that the uibinder tries to set property or add children on a null instance – Jerome Cance Dec 01 '10 at 17:30
  • Do your widgets share a common interface or superclass? I'm thinking about a 'dummy' implementation rendering minimal markup. – z00bs Dec 01 '10 at 17:49
  • No not really, these inherit Composite class. I think I will use the suggestion of Carlos but just configure them with visible false and not removing them (which is more CPU intensive I think) – Jerome Cance Dec 02 '10 at 07:59
  • Ok. Guess that's a not too bad compromise. Please post the link when you've filled in an issue for the GWT dev team. – z00bs Dec 02 '10 at 08:25