Error using my own widgets with UIBinder

118 views
Skip to first unread message

spierce7

unread,
Jul 5, 2010, 1:03:20 AM7/5/10
to Google Web Toolkit
Hey, I'm getting an error using my own widgets in UIBinder. In this
I'm using the DockLayoutPanel, and everything works fine until I swap
the Label that everything was working with in <g:north> with my own
widget, WeeklyHeader. I'm getting the following error:
[ERROR] [scheduler] Unable to load module entry point class
com.spierce7.gwt.scheduler.client.Scheduler (see associated exception
for details)
com.google.gwt.user.client.ui.AttachDetachException: One or more
exceptions caught, see full set in AttachDetachException#getCauses
at
com.google.gwt.user.client.ui.AttachDetachException.tryCommand(AttachDetachException.java:
85)
at com.google.gwt.user.client.ui.Panel.doAttachChildren(Panel.java:
162)
at com.google.gwt.user.client.ui.Widget.onAttach(Widget.java:289)
(... it continues)

Here is my code. I'll separate them by dashes:
----------------------------------------------------------------------------------------------------
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:my='urn:import:com.spierce7.gwt.calendar.client'>

<g:DockLayoutPanel unit='EM'>
<g:north size='5'>
<my:WeeklyHeader />
</g:north>
<g:center size='5'>
<g:Label>Body</g:Label>
</g:center>
<g:west size='10'>
<g:HTML>
<ul>
<li>Side bar</li>
<li>Side bar</li>
<li>Side bar</li>
</ul>
</g:HTML>
</g:west>
</g:DockLayoutPanel>
</ui:UiBinder>
----------------------------------------------------------------------------------------------------
public class CalendarUI extends Composite {

private static CalendarUIUiBinder uiBinder =
GWT.create(CalendarUIUiBinder.class);
interface CalendarUIUiBinder extends UiBinder<Widget, CalendarUI> {}

public CalendarUI() {
initWidget(uiBinder.createAndBindUi(this));
RootLayoutPanel.get().add(uiBinder.createAndBindUi(this));
}
}
----------------------------------------------------------------------------------------------------
The WeeklyHeader Class extends Grid:
public class WeeklyHeader extends Grid {



The best guess I've got is that my widget is supposed to extend
something, or implement something. I can't figure it out for the life
of me. Any help is much appreciated.

Blessed Geek

unread,
Jul 7, 2010, 1:25:04 PM7/7/10
to Google Web Toolkit
There is a design deficiency in UiBinder which I am desperately hoping
GWT architects are putting top priorities at rectifying it - you
cannot, for most and practical cases, use your custom-extended
UiBinderable classes with Uibinder, unless you are willing to kludgify
your use of uibinder.

These are the apparent rules that you need to stick to when making a
class uibinderable:
* A class to be used as a parent node of GWT Widgets must implement
HasWidget,
* and any class that is its candidate child node must be an extension
of GWT Widget class.
* A class to be used as parent node of HTML contents must implement
HasHTML.
* A class to be used as a node for encapsulating text content must
implement HasText?.

These are the problems/issues:
* The GWT compiler ignores HasHTML or HasText when HasWidget is
implemented.
* Therefore, a custom UiBinder node cannot have a mix of Widget nodes
with HTML and Text node.
* Most uibinder classes that came off-the-shelf with GWT engage in
insider-trading - they are allowed to skirt around the above rules by
having their own respective parsers.
* That is why insider-traded uibinderable classes can have nodes like
north, south, top, bottom, ..., etc.
* When you extend an insider-traded class, for the most part, the GWT
compiler would consequently create a temporary java source file that
at some point performs the equivalent of.
ExtendedClass uiname = new instance of OriginalClass.
Now, in Java, you can assign variable of an original class to an
instance of its extended class but not vice versa. I do not know if
this is hard-coded in the GWT compiler or in every individual parser.
* For hierarchically related classes like TabBar - Tab or MenuBar -
Menu, the GWT compiler/uibinder parser attempts to look for the child
class from under the same package, disregarding what you declare as
the package namespace in your extension class.

These are the entry-barriers towards investing efforts to customise
your use of uibinder:
* At current state of affairs, we cannot attain the same level of
karma as the insider-traded uibinderable classes because GWT compiler
does not provide a means for us to insert our own parsers.
* More accurately, we can insert our own parsers if we are willing to
make some minor modification to the GWT compiler source and rebuild
GWT from source.

There are the kludgifications that could mitigate the current state of
affairs with uibinder. For example, you could hijack the namespace
com.google.gwt.user.client.ui when extending classes that have a
hierarchical relationship, which I demonstrate here:
http://h2g2java.blessedgeek.com/2010/04/patch-extending-insider-traded-uibinder.html.
Or hijack the original classes altogether by replacing and appending
the original source with code of your personally preferred behaviour.

However, the elegant solution is of course to rectify the behaviour
and characteristics of the GWT compiler rather than having us resort
to such neck-breaking kludgifications.

I believe the gwt-mosaic uses its own patch for the gwt compiler to
allow it to insert is own parsers: project http://code.google.com/p/gwt-mosaic/

Perhaps, and if I could beg y'all for a pardon, we should come
together and agree on a way to patch gwt compiler and set up a google
code project for this patching, while we let the gwt architects to
peacefully mull over what the best way should be to treat these
uibinder deficiencies. Which means, we would need to mirror every GWT
release with this patched GWT.
Reply all
Reply to author
Forward
0 new messages