FlowPanel vs. HTMLPanel in GWT UiBinder - gwt

When using UiBinder what is the preferred method of creating a simple layout like this?
FlowPanel:
<!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'>
<ui:style>
.outer {
display: table;
height: 100%;
width: 100%;
}
.inner {
background: #DDD;
display: table-cell;
vertical-align: middle;
}
</ui:style>
<g:FlowPanel styleName="{style.outer}">
<g:FlowPanel styleName="{style.inner}">
<g:Label ui:field="someLabel"/>
</g:FlowPanel>
</g:FlowPanel>
</ui:UiBinder>
HTMLPanel:
<!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'>
<ui:style>
.outer {
display: table;
height: 100%;
width: 100%;
}
.inner {
background: #DDD;
display: table-cell;
vertical-align: middle;
}
</ui:style>
<g:HTMLPanel styleName="{style.outer}">
<div class="{style.inner}">
<g:Label ui:field="someLabel"/>
</div>
</g:HTMLPanel>
</ui:UiBinder>
Edit: I know they produce the same html when rendering, I'm wondering if there is any justification for using one style over the other.
The javadocs say that the FlowPanel is the simplest panel, but at what point does using an HTMLPanel become preferable. e.g.
<FlowPanel>
<FlowPanel>
<Widget>
</FlowPanel>
<FlowPanel>
<Widget>
</FlowPanel>
</FlowPanel>
vs.
<HTMLPanel>
<div>
<Widget>
</div>
<div>
<Widget>
</div>
</HTMLPanel>
Thanks.
UiBinder - HTMLPanel vs. div is a fairly similar question but asks about using a div vs. a HTMLPanel.

Actually they will render same in your case - div. There is no difference unless you start adding more elements to FlowPanel.
You can try FlowPanel behaviour here:
http://examples.roughian.com/index.htm#Panels~FlowPanel
You should use HTMLPanel in cases when you need to write your own custom HTML code on the page. It allows to write HTML code inside of HTMLPanel tag.
For example you can't do such trick with FlowPanel.

I recently read Tags First GWT Programming. It seems to me, that the technique he describes would allow you to have much better control over the ultimate rendering of your page, while maintaining the advantages of GWT.
I think the dichotomy that you're asking about between FlowPanel and HTMLPanel isn't really the right question. Instead, it is best to recognize that they're meant for different things.
HTMLPanel is capable of a lot more than FlowPanel is. When you need to dynamically add and remove widgets that are embedded in some custom html, use an HTMLPanel. If you just want some widgets to align together on the page with normal html flow (like some text and pictures) use a FlowPanel.
My personal advice would be to use the simplest thing that can do what you need it to.

I recommend the second example. If possible you should prefer using a plain HTML tag such as "div" over a widget such as "FlowPanel" because of the overhead having an unused logical widget.
This may seems trivial first but it saves you a lot of headache (memory leaks, gquery operations, ...) when you have to deal with a lot of items.

Related

How can i vertical-align & horizontal-align components inside a FlowPanel?

As stated in http://www.gwtproject.org/doc/latest/DevGuideUiPanels.html, Google said we should not use HorizontalPanel & VerticalPanel to make layouts since it can have some browser incompatibility problems. Google suggests to use FlowPanel instead.
VerticalPanel can usually be replaced by a simple FlowPanel (since block-level elements will naturally stack up vertically).
HorizontalPanel is a bit trickier. In some cases, you can simply replace it with a DockLayoutPanel, but that requires that you specify its childrens' widths explicitly. The most common alternative is to use FlowPanel, and to use the float: left; CSS property on its children. And of course, you can continue to use HorizontalPanel itself, as long as you take the caveats above into account.
However, we now run into another problem.
How to vertical-align & horizontal-align components inside a FlowPanel?
This doesn't work.
<g:FlowPanel height="100%" addStyleNames="{res.css.alignMiddle}">
.alignMiddle{
vertical-align:middle;
}
I tried myFlowPanel.getElement().getStyle().setVerticalAlign(VerticalAlign.MIDDLE); but it also doesn't work.
Also, another approach is to use <table> html tag inside a HTMLPanel, but some people said different browsers may render gui differently the widgets inside <table> causing some quirks. Google doesn't suggest to use <table> inside a HTMLPanel, so we shouldn't use.
But, then:
How to vertical-align & horizontal-align components inside a FlowPanel?
i found a solution
<g:FlowPanel addStyleNames="{res.css.outer}">
<g:FlowPanel addStyleNames="{res.css.alignMiddle}">
more widget here....
</g:FlowPanel>
</g:FlowPanel>
.outer {
display: table;
height: 100%;
width: 100%;
}
.alignMiddle{
display: table-cell;
vertical-align: middle;
text-align:center;
}

CSS selector/inheritance in GWT UiBinder when using external stylesheet

I am using GWT 2.4.0 + UiBinder.
In my ui.xml file i have referenced external style sheet using below line.
<ui:style
type="com.codelaboration.twykin.frontend.widgets.qa.client.view.QABox.QAStyle"
src="QABox.css" />
Now i have below code in the same ui.xml file
<div class="{style.imagePanel}">
<div ui:field="lblUser"/>
</div>
In QABox.css i have defined the "imagePanel" and also used CSS inheritance for applying the CSS to all divs inside the imagePanel class:
.imagePanel {float: left; width: 100px; text-align: center;}
.imagePanel div {float: right; width: 530px;}
Now the problem is GWT is obscufacting the style name, so now imagePanel will be changed to some weird name, so the ".imagePanel div" wont going to work. So basically my question is how to use CSS selector in UiBinder when external stylesheet had been declared in ui.xml only.
Thanks.
you can add external css in your gwt application.
you have to give the relative path to your style resource.
hear is the piece of code.
in your uibinder xml
<ui:style src="QAStyle/QABox.css" />
<div class="{style.imagePanel}">
<div ui:field="lblUser"/>
</div>
it will find css in the QAStyle package.
or you can also use ClientBundle that will avoid your path problems. See Using an external resource.
it will help you.

What is the proper way to align two buttons in the same row with HTMLPanel in GWT 2.4?

I'm using GWT 2.4 and uiBinder to add widgets to a page. Now I want to layout two bottom buttons in one row, but I'm not sure of the correct way to do this.
I tried adding in a horizontalPanel like this:
<tr>
<td align="center">
<g:HorizontalPanel ui:field="horizontalPanel" borderWidth="1" spacing="50">
<g:Button ui:field="cancelButton" text="Cancel"></g:Button>
<g:Button ui:field="exitButton" text="Exit"></g:Button>
</g:HorizontalPanel>
</td>
</tr>
but it's not spacing the buttons far enough apart. Increasing the spacing is adding more height to the panel and pushing everything down away another button that is above it.
What is the proper way to do this?
There are two ways you can go about doing your layout in GWT:
depend on smartgwt or gxt.
bite the bullet and learn css.
I advise people to go the 2nd path. smartgwt and gxt will seem attractive for a simple project. However, as your project gets more and more complex, the incompatibilities with all the other GWT goodies become wider and wider.
Bite the bullet and learn how to integrate css into gwt.
<!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">
<ui:style>
.trivial {
font-weight: bold;
margin-left: 50px;
margin-top: 0px;
margin-right: 50px;
margin-bottom: 0px;
}
</ui:style>
<g:HorizontalPanel>
<g:Button styleName="{style.trivial}" ui:field="button1">David Headley</g:Button>
<g:Button styleName="{style.trivial}" ui:field="button2">Debacle</g:Button>
</g:HorizontalPanel>
</ui:UiBinder>

Get UiBinder widget to display inline instead of block

I'm trying to get my UiBinder-defined widget to display inline, but I can't. My current code is:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:style>
.section {
border: 1px solid #000000;
width: 330px;
padding: 5px;
display: run-in;
}
</ui:style>
<g:HTMLPanel>
<div class="{style.section}">
<div ui:field="titleSpan" class="{style.title}" />
<div class="{style.contents}">
<g:VerticalPanel ui:field="messagesPanel" />
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
This works fine in terms of how the widget looks internally, but I want to throw a bunch of these widgets into a FlowPanel and have them flow when the window is resized. The HTMLPanel is a div, but I can't get the display attribute to assign. I can't force the style name, since the following throws an error:
<g:HTMLPanel styleNames="{style.section}">
And I can assign an additional style, but it doesn't apply the display setting.
<g:HTMLPanel addStyleNames="{style.section}">
This displays the border and sets the size, as expected, but it doesn't flow. Firebug shows the styles on the div are border, width, and padding, but no display.
Is there a way to make a widget in UiBinder so that it'll display inline instead of block? And if so, can I make it compatible with having a VerticalPanel inside (can I do it without making the entire widget pure HTML without any GWT widgets)?
PS: I saw question 2257924 but it hasn't had any answers lately, and he seems to be focused on getting a tag, not specifically getting inline layout. I don't care directly about , if I can just get the top-level tag for my widget to flow inline, I'm happy.
It seems your problem is caused by using display: run-in instead of the more "standard" display: inline. IE and Firefox don't support run-in and it seems that Firebug prunes the style upon adding.
Try changing the style to display: inline (or inline-block if you want some properties of a block, like width, but beware of the quirks of IE + inline-block).
It should be <g:HTMLPanel styleName="{style.section}">, not <g:HTMLPanel styleNames="{style.section}"> - styleNames is a typo (which appears in the UiBinder docs, so I'm sure that's where you got it from). styleName is the correct thing to use.
Also, Igor Klimer is correct that you should use display: inline or display: inline-block rather than display: run-in.
In general, you can tell the available attribute names by looking for setXXX methods on the UIObject class, and the attribute name is just the XXX. So, UIObject has a setStyleName method, which you access using the attribute called styleName.

Embeding a TabLayoutPanel inside a DockLayoutPanel

I'm trying to embed a TabLayoutPanel inside a DockLayoutPanel but the tabs are not showing up :(
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<g:DockLayoutPanel unit='PX'>
<g:north size='200'>
<g:HTML>
<h1>
My Header
</h1>
</g:HTML>
</g:north>
<g:center>
<g:TabLayoutPanel barUnit='PX' barHeight='3'>
<g:tab>
<g:header size='7'>
<b>HTML</b>
header
</g:header>
<g:Label>able</g:Label>
</g:tab>
<g:tab>
<g:customHeader size='7'>
<g:Label>Custom header</g:Label>
</g:customHeader>
<g:Label>baker</g:Label>
</g:tab>
</g:TabLayoutPanel>
</g:center>
<g:west size='192'>
<g:HTML>
<ul>
<li>Sidebar</li>
<li>Sidebar</li>
<li>Sidebar</li>
</ul>
</g:HTML>
</g:west>
</g:DockLayoutPanel>
</ui:UiBinder>
If you're seeing nothing at all, make sure that the TabLayoutPanel either (a) has an explicit size, or (b) is ultimately attached to the RootLayoutPanel (see http://code.google.com/webtoolkit/doc/latest/DevGuideUiPanels.html#Resize for more details).
If the problem is a lack of styling on the tabs (i.e., you're just seeing raw text where the tabs should be), you'll need to add some styles (the CSS rules you'll need are described in TabLayoutPanel's javadoc). There are not yet any default styles for TabLayoutPanel, but we'll be adding some soon.
The example from the JavaDoc is somewhat misleading - the bar height of 3 will hide the tab headings and a height needs to be specified for the body. Use something like:
<g:TabLayoutPanel barUnit='PX' barHeight='25' height="200px" >
or
<ui:style>
.tab {
height: 200px;
}
<g:TabLayoutPanel barUnit='PX' barHeight='25' styleName="{style.tab}" >
Also, you can find a basic CSS style for TabLayoutPanel on comment #5 in the following issue:
http://code.google.com/p/google-web-toolkit/issues/detail?id=4429
I have been having the same issue using the new TabLayoutPanel too (the tabs doesn't show up even if it's the only thing on the page). I decided to back to using the (now deprecated) TabPanel instead. Try and see if that works instead:
Example code:
<g:TabPanel width="100%" height="100%" ui:field="gwtimeTabPanel">
<g:Tab>
<g:TabHTML>Tab title</g:TabHTML>
<g:FlowPanel>
<!-- tab contents goes here -->
</g:FlowPanel>
</g:Tab>
</g:TabPanel>
For the people who mainly use Java code to define the UI.
Explenation
You should set the size of the parentpanel of the TabLayoutPanel and of the TabLayoutPanel itself. For instance I had a VerticalPanel and a TabLayoutPanel, I added this TabLayoutPanel to the VerticalPanel (which makes it the parentpanel of TabLayoutPanel) like this:
veticalPanel.add(tabLayoutPanel);
RootPanel.get().add(verticalPanel);
which did nothing...
Answer
you should declare the size of your panels like this
//set size
vertialPanel.setSize("100%","100%");
tabLayoutPanel.setSize("100%","100%")
RootPanel.get().add(verticalPanel);