GWT TabLayoutPanel


December 5, 2013 Maithilish

3.3. ContentPanel

ContentPanel

Next task is to design custom widgets and dock them in DockLayoutPanel of FinsShell. Let us start with ContentPanel which displays the contents of the application. GWT comes with a stock tab panel, GWT TabLayoutPanel, which can display contents in multiple tabs and it is a perfect panel for content area.

Just for convenience, place all the custom widgets in a separate package. Go ahead and create a package

in.fins.client.widget. Add ContentPanel.ui.xml and its owner class ContentPanel.java.
in.fins.client.widget/ContentPanel.ui.xml

<!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">
	
	<g:TabLayoutPanel ui:field="tab" barHeight="30" barUnit="PX" 
			  animationDuration="500"/>		

</ui:UiBinder> 

in.fins.client.widget/ContentPanel.java

package in.fins.client.widget;

import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.google.gwt.user.client.ui.Widget;

public class ContentPanel extends ResizeComposite {

	interface ContentPanelBinder extends UiBinder<Widget, ContentPanel> {
	}

	private static UiBinder<Widget, ContentPanel> binder = GWT
			.create(ContentPanelBinder.class);

	@UiField
	TabLayoutPanel tab;

	public ContentPanel() {
		initWidget(binder.createAndBindUi(this));
	}

	public void addTab(String text, Composite content) {
                tab.add(content,text);
		tab.selectTab(tab.getWidgetCount() - 1);
	}

}

In ContentPanel.ui.xml we add GWT TabLayoutPanel as the top panel. UiBinder class ContentPanel extends ResizeComposite and wraps TabLayoutPanel returned by UiBinder. To add a new tab and set a widget as the content it provides addTab() method. TabLayoutPanel.selectTab() selects the latest tab.
Expose custom widgets to UiBinder

Until now we have used GWT widgets in the template file by using prefix g:. It is not possible to access custom widgets this way, and for that we need to tie their package to a xml namespace prefix.

Modify FinsShell.ui.xml and add a new namespace in ui:UiBinder element to expose in.fins.client.widget package.
in.fins.client.content/FinsShell.ui.xml

<!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:f="urn:import:in.fins.client.widget" >

....

<g:SplitLayoutPanel ui:field="split">
   <g:west size="150">
      <g:Label>Menu Placeholder</g:Label>
   </g:west>
   <g:center>
      <f:ContentPanel ui:field="contentPanel" />
   </g:center>
</g:SplitLayoutPanel>

Namespace xmlns:f="urn:import:in.fins.client.widget" exposes custom widgets to UiBinder and with prefix f: we can refer any of our custom widgets in the template. ContentPanel is placed in the center dock of SplitLayoutPanel.
Modify FinsShell.java to add Home tab to ContentPanel.
in.fins.client.content/FinsShell.java

package in.fins.client.content;

import in.fins.client.widget.ContentPanel;

....

@UiField
ContentPanel contentPanel;

public FinsShell() {
   initWidget(binder.createAndBindUi(this));
   contentPanel.addTab("Home", new DateBox());
}

@UiField allows UiBinder to inject ContentPanel to owner class. ContentPanel.addTab() method adds the Home Tab to the ContentPanel. DateBox a GWT composite, is just a placeholder, and actual content replaces it later.
Next section looks at LogTab, a custom widget, which can be added to a tab to display client side log messages.