Extending/embedding DialogBox

136 views
Skip to first unread message

Wulfsberg

unread,
Aug 1, 2011, 10:55:06 AM8/1/11
to Google Web Toolkit
I am a little confused over the best practice use of DialogBox when
using UIBinders.

In UIBinder xml, you can include a DialogBox element, and configure it
using, say, the caption element or text attributes. This seems to hint
that you can embed a full DialogBox definition, letting a widget carry
its own DialogBox to pop on demand.
However, doing so results in the dialog box being shown as part of the
page on load, and some comments seem to indicate that "you're not
supposed to do this".

If, on the other hand, you extend DialogBox as its own stand-alone
widget, you only get to define the *contents* of the dialog box in the
ui.xml, forcing you to set things like caption and glass pane in the
Java code, which seems to defy the purpose of a uibinder in the first
place.

What am I missing?

Derek

unread,
Aug 2, 2011, 12:25:35 PM8/2/11
to Google Web Toolkit
I generally create custom Dialogs as their own uibinders and then
instantiate them from elsewhere. So I might use the code below, and
display it with "new MyDialog().center();"

Is this best practice? I'm not sure. I think there are some who hold
to the idea that you should let your dialog's content be its own
UiBinder, but that is not precluded by the strategy below. It's the
way we do things at my organization.

<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:DialogBox modal="true">
<g:caption>Dialog!</g:caption>
<g:HTMLPanel>
<g:Button ui:field="close">Close</g:Button>
</g:HTMLPanel>
</g:DialogBox>
</ui:UiBinder>

public class MyDialog {
private static MyDialogUiBinder uiBinder =
GWT.create(MyDialogUiBinder.class);
interface MyDialogUiBinder extends UiBinder<Widget, MyDialog> {}
DialogBox box;
public MyDialog() {
box = (DialogBox) uiBinder.createAndBindUi(this);
}
public void center() { box.center(); }
@UiHandler("close") void onClose(ClickEvent event) { box.hide(); }

Brian Reilly

unread,
Aug 2, 2011, 3:25:36 PM8/2/11
to google-we...@googlegroups.com
I've found that you can add a visible="false" attribute to the g:DialogBox tag to keep it from being displayed on page load. However, I think this will cause the dialog box UI to be constructed even if it's never displayed.

I'm guessing that the "you're not supposed to do this" comment you're referring to is this comment from the PopupPanel javadocs:
A PopupPanel should not generally be added to other panels; rather, it should be shown and hidden using the show() and hide() methods.
Derek's approach is the only way I can think of to use g:DialogBox in a UI template without it being automatically added to another panel. However, I don't like that approach because the custom dialog box does not actually subclass DialogBox. This necessitates having like-named methods that proxy to the DialogBox returned from UiBinder, such as center() in Derek's example. Unlike cases where it makes sense to subclass Composite to hide the root widget's API, the custom dialog box really is a dialog box and should inherit the DialogBox API.

What I settled on was to subclass DialogBox and use UiBinder to build the widget passed to DialogBox.setWidget(). My hope is that this encourages its use from java code instead of a UI template. In reality, my custom dialogs are no more opinionated about where they're used than GWT's own DialogBox is, which has a nice harmonious feel to it.

-- Brian

Aidan O'Kelly

unread,
Aug 2, 2011, 6:24:57 PM8/2/11
to google-we...@googlegroups.com
You can actually just change your UiBinder java class to inherit from
DialogBox, and call setWidget(uiBinder.createAndBind(this)) instead of
the regular, initWidget() method of Composite.

Your UiBinder template then just looks like this:

<ui:UiBinder ... >
<g:HTMLPanel>
Stuff.
</g:HTMLPanel>
</ui:UiBinder>

// To use:
CustomDialog dialog = new CustomDialog();
// etc.

> --
> You received this message because you are subscribed to the Google Groups
> "Google Web Toolkit" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-web-toolkit/-/EuskuIZqfqkJ.
> To post to this group, send email to google-we...@googlegroups.com.
> To unsubscribe from this group, send email to
> google-web-tool...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/google-web-toolkit?hl=en.
>

Wulfsberg

unread,
Aug 3, 2011, 5:45:56 AM8/3/11
to Google Web Toolkit
Aidan, that was exactly my point: You lose UIBinder control over the
caption there, forcing you to create your dialog box from a mix of
Java parameters and UIBinder XML, which grates somewhat. In my
opinion, it should be either/or, not a mix.

I can see a point for making a fairly standardized dialog (like, say,
an OK/Cancel box) a subclass, and feed all information (caption and
lead text) through Java as a single (constructor) call, but with more
complex dialogs I'd like to be able to design them - and let other
people modify them - with the UIBinder system.

It seems to me there is a bit of a mismatch in the design here.

JWN

Brian Reilly

unread,
Aug 3, 2011, 9:48:39 AM8/3/11
to google-we...@googlegroups.com
That's exactly what I do. Use of UiBinder is then simply an implementation detail of how the UI is constructed for the custom dialog.

If you want your custom dialog to be created from UI templates, there are a few options for initializing both a caption and a widget.

1. use a text attribute in the UI template: <my:CustomDialogBox text="Caption Text"/>
2. add a setCaption(String caption) method to your dialog that proxies to setText() and use a caption attribute in the UI template: <my:CustomDialogBox caption="Caption Text"/>. This causes the caption to be _optional_.
3. add a constructor, CustomDialog(String caption), annotated with @UiConstructor and use a caption attribute in the UI template. <my:CustomDialogBox caption="Caption Text"/>. This causes the caption to be _required_.

Also, while I don't think it applies to this case, check out @UiChild for cases where you want something similar to having a custom UiBinder parser for your widget: http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/uibinder/client/UiChild.html

-- Brian
Reply all
Reply to author
Forward
0 new messages