Add additional UI elements to myCRM
At this point, we've laid out the user interface, added some widgets and implemented event handlers that respond to mouse click events.
In this post, we'll add additional elements to the application's user interface. First, we'll add a header above the Navigation pane/Context area and then we'll add a Toolbar, a Status Bar and a Jump Bar to the Account's view.
- Select the smartGWT widgets
- Implement the smartGWT widgets
- Test the application in development mode
1. Select the smartGWT widgets
Take a look at the smartGWT Showcase, the types of widgets and how they can be used. Some of the widgets that we might find useful are the tool strip, the buttons and labels.
2. Implement the smartGWT widgets
In the area above the Navigation pane we've decided to add a header. Let's start out by creating a new class, the NavigationPaneHeader class:
package au.org.myCRM.client.ui.widgets;
import com.google.gwt.core.client.GWT;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.widgets.Label;
public class NavigationPaneHeader extends HLayout {
private static final String WEST_WIDTH = "20%";
private static final String NAVIGATION_PANE_HEADER_HEIGHT = "27px";
private static final String NAVIGATION_PANE_HEADER_LABEL_DISPLAY_NAME = "Workplace";
private static final String CONTEXT_AREA_HEADER_LABEL_DISPLAY_NAME = "Activities";
private Label navigationPaneHeaderLabel;
private Label contextAreaHeaderLabel;
public NavigationPaneHeader() {
super();
GWT.log("init NavigationPaneHeader()...", null);
// initialise the Navigation Pane Header layout container
this.addStyleName("crm-NavigationPane-Header");
this.setHeight(NAVIGATION_PANE_HEADER_HEIGHT);
// initialise the Navigation Pane Header Label
navigationPaneHeaderLabel = new Label();
navigationPaneHeaderLabel.addStyleName("crm-NavigationPane-Header-Label");
navigationPaneHeaderLabel.setWidth(WEST_WIDTH);
navigationPaneHeaderLabel.setContents(NAVIGATION_PANE_HEADER_LABEL_DISPLAY_NAME);
navigationPaneHeaderLabel.setAlign(Alignment.LEFT);
navigationPaneHeaderLabel.setOverflow(Overflow.HIDDEN);
// initialise the Context Area Header Label
contextAreaHeaderLabel = new Label();
contextAreaHeaderLabel.addStyleName("crm-ContextArea-Header-Label");
contextAreaHeaderLabel.setContents(CONTEXT_AREA_HEADER_LABEL_DISPLAY_NAME);
contextAreaHeaderLabel.setAlign(Alignment.LEFT);
contextAreaHeaderLabel.setOverflow(Overflow.HIDDEN);
// add the Labels to the Navigation Pane Header layout container
this.addMember(navigationPaneHeaderLabel);
this.addMember(contextAreaHeaderLabel);
}
public Label getNavigationPaneHeaderLabel() {
return navigationPaneHeaderLabel;
}
public Label getContextAreaHeaderLabel() {
return contextAreaHeaderLabel;
}
public void setNavigationPaneHeaderLabelContents(String contents) {
navigationPaneHeaderLabel.setContents(contents);
}
public String getNavigationPaneHeaderLabelContents() {
return navigationPaneHeaderLabel.getContents();
}
public void setContextAreaHeaderLabelContents(String contents) {
contextAreaHeaderLabel.setContents(contents);
}
public String getContextAreaHeaderLabelContents() {
return contextAreaHeaderLabel.getContents();
}
}
Then we need to update the onModuleLoad method of the application's entry point class:
...
// initialise the Navigation Pane Header
navigationPaneHeader = new NavigationPaneHeader();
// add the Application Menu and the Navigation Pane Header to the nested layout container
vLayout.addMember(applicationMenu);
vLayout.addMember(navigationPaneHeader);
// add the nested layout container to the North layout container
northLayout.addMember(vLayout);
and update the click handler in the application's entry point class:
...
private class NavigationPaneClickHandler implements RecordClickHandler {
@Override
public void onRecordClick(RecordClickEvent event) {
NavigationPaneRecord record = (NavigationPaneRecord) event.getRecord();
setContextAreaView(record);
}
}
private void setContextAreaView(NavigationPaneRecord record) {
// "Activities" or "Calendar", etc.
String name = record.getName();
navigationPaneHeader.setContextAreaHeaderLabelContents(name);
ContextAreaFactory factory = record.getFactory();
Canvas view = factory.create();
southLayout.setMembers(westLayout, view);
}
}
We also need to add the following to the applications's style sheet, myCRM.css:
...
.crm-NavigationPane-Header {
border-top: 1px solid #7598c7;
background-image: url(images/navigation_pane_header.png);
background-repeat: repeat-x;
}
.crm-NavigationPane-Header-Label {
border-right: 1px solid #7598c7;
color: #15428b;
cursor: default;
font-family: Tahoma, Verdana, sans-serif;
font-size: 14px;
font-weight: bold;
padding-left: 8px;
}
.crm-ContextArea-Header-Label {
color: #15428b;
cursor: default;
font-family: Tahoma, Verdana, sans-serif;
font-size: 14px;
font-weight: bold;
padding-left: 8px;
}
We now have a new UI element, the Navigation Pane Header:

Now, lets add a Toolbar, a Status Bar and a Jump Bar to the Account's view. First, we need to create a new class, the ToolBar class:
package au.org.myCRM.client.ui.widgets;
import com.google.gwt.core.client.GWT;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;
public class ToolBar extends HLayout {
private static final String TOOLBAR_HEIGHT = "25px";
private static final String TOOLSTRIP_WIDTH = "*";
private static final String NEW_BUTTON = "toolbar/new.png";
private static final String PRINT_PREVIEW_BUTTON = "toolbar/printpreview.png";
private static final String EXPORT_BUTTON = "toolbar/export.png";
private static final String MAIL_MERGE_BUTTON = "toolbar/mailmerge.png";
private static final String REPORTS_BUTTON = "toolbar/reports.png";
private static final String ASSIGN_BUTTON = "toolbar/assign.png";
private static final String DELETE_BUTTON = "toolbar/delete.png";
private static final String EMAIL_BUTTON = "toolbar/sendemail.png";
private static final String NEW_BUTTON_DISPLAY_NAME = "New";
public ToolBar() {
super();
GWT.log("init ToolBar()...", null);
// initialise the ToolBar layout container
this.addStyleName("crm-ToolBar");
this.setHeight(TOOLBAR_HEIGHT);
// initialise the ToolStrip
ToolStrip toolStrip = new ToolStrip();
toolStrip.setHeight(TOOLBAR_HEIGHT);
toolStrip.setWidth(TOOLSTRIP_WIDTH);
// initialise the New button
ToolStripButton newButton = new ToolStripButton();
newButton.setIcon(NEW_BUTTON);
newButton.setTitle(NEW_BUTTON_DISPLAY_NAME);
newButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
SC.say("You clicked the New button.");}
}
);
toolStrip.addButton(newButton);
toolStrip.addSeparator();
// initialise the Print Preview button
ToolStripButton printPreviewButton = new ToolStripButton();
printPreviewButton.setIcon(PRINT_PREVIEW_BUTTON);
toolStrip.addButton(printPreviewButton);
// initialise the Export button
ToolStripButton exportButton = new ToolStripButton();
exportButton.setIcon(EXPORT_BUTTON);
toolStrip.addButton(exportButton);
// initialise the Mail Merge button
ToolStripButton mailMergeButton = new ToolStripButton();
mailMergeButton.setIcon(MAIL_MERGE_BUTTON);
toolStrip.addButton(mailMergeButton);
// initialise the Reports button
ToolStripButton reportsButton = new ToolStripButton();
reportsButton.setIcon(REPORTS_BUTTON);
toolStrip.addButton(reportsButton);
toolStrip.addSeparator();
// initialise the Assign button
ToolStripButton assignButton = new ToolStripButton();
assignButton.setIcon(ASSIGN_BUTTON);
toolStrip.addButton(assignButton);
// initialise the Delete button
ToolStripButton deleteButton = new ToolStripButton();
deleteButton.setIcon(DELETE_BUTTON);
toolStrip.addButton(deleteButton);
// initialise the Email button
ToolStripButton emailButton = new ToolStripButton();
emailButton.setIcon(EMAIL_BUTTON);
toolStrip.addButton(emailButton);
// add the ToolStrip to the ToolBar layout container
this.addMember(toolStrip);
}
}
then we need to create the StatusBar class:
package au.org.myCRM.client.ui.widgets;
import com.google.gwt.core.client.GWT;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.widgets.ImgButton;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.layout.LayoutSpacer;
public class StatusBar extends HLayout {
private static final String STATUSBAR_HEIGHT = "23px";
private static final String SELECTED_LABEL_DISPLAY_NAME = "1 of 50 selected";
private static final String PAGE_NUMBER_LABEL_DISPLAY_NAME = "Page 1";
public StatusBar() {
super();
GWT.log("init StatusBar()...", null);
// initialise the StatusBar layout container
this.addStyleName("crm-StatusBar");
this.setHeight(STATUSBAR_HEIGHT);
// initialise the Selected label
Label selectedLabel = new Label();
selectedLabel.addStyleName("crm-StatusBar-Label");
selectedLabel.setContents(SELECTED_LABEL_DISPLAY_NAME);
selectedLabel.setAlign(Alignment.LEFT);
selectedLabel.setOverflow(Overflow.HIDDEN);
// initialise the Result Set First button
ImgButton resultSetFirstButton = new ImgButton();
resultSetFirstButton.setShowRollOver(false);
resultSetFirstButton.setShowDisabled(false);
resultSetFirstButton.setShowDown(false);
resultSetFirstButton.setSize(12);
resultSetFirstButton.setLayoutAlign(VerticalAlignment.CENTER);
resultSetFirstButton.setSrc("statusbar/resultsetfirst.png");
// initialise the Result Set Previous button
ImgButton resultSetPreviousButton = new ImgButton();
resultSetPreviousButton.setShowRollOver(false);
resultSetPreviousButton.setShowDisabled(false);
resultSetPreviousButton.setShowDown(false);
resultSetPreviousButton.setSize(12);
resultSetPreviousButton.setLayoutAlign(VerticalAlignment.CENTER);
resultSetPreviousButton.setSrc("statusbar/resultsetprevious.png");
// initialise the Page Number label
Label pageNumberLabel = new Label();
pageNumberLabel.addStyleName("crm-StatusBar-Label");
pageNumberLabel.setContents(PAGE_NUMBER_LABEL_DISPLAY_NAME);
pageNumberLabel.setWidth(50);
pageNumberLabel.setAlign(Alignment.RIGHT);
pageNumberLabel.setOverflow(Overflow.HIDDEN);
// initialise the Result Set Next button
ImgButton resultSetNextButton = new ImgButton();
resultSetNextButton.setShowRollOver(false);
resultSetNextButton.setShowDisabled(false);
resultSetNextButton.setShowDown(false);
resultSetNextButton.setSize(12);
resultSetNextButton.setLayoutAlign(VerticalAlignment.CENTER);
resultSetNextButton.setSrc("statusbar/resultsetnext.png");
// add the widgets to the StatusBar layout container
this.addMember(selectedLabel);
// force right alignment
Label alignRight = new Label(" ");
alignRight.setAlign(Alignment.RIGHT);
alignRight.setOverflow(Overflow.HIDDEN);
this.addMember(alignRight);
this.addMember(resultSetFirstButton);
this.addMember(resultSetPreviousButton);
this.addMember(pageNumberLabel);
this.addMember(resultSetNextButton);
// add some padding
LayoutSpacer paddingRight = new LayoutSpacer();
paddingRight.setWidth(8);
this.addMember(paddingRight);
}
}
and the JumpBar class:
package au.org.myCRM.client.ui.widgets;
import com.google.gwt.core.client.GWT;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.layout.LayoutSpacer;
public class JumpBar extends HLayout {
private static final String JUMPBAR_HEIGHT = "23px";
private static final String ALL_LABEL_DISPLAY_NAME = "All";
public JumpBar() {
super();
GWT.log("init JumpBar()...", null);
// initialise the JumpBar layout container
this.addStyleName("crm-JumpBar");
this.setHeight(JUMPBAR_HEIGHT);
// initialise the LayoutSpacer
LayoutSpacer paddingLeft = new LayoutSpacer();
paddingLeft.setWidth(8);
this.addMember(paddingLeft);
// initialise the All label
Label allLabel = new Label();
// allLabel.addStyleName("crm-JumpBar-Label");
allLabel.setBaseStyle("crm-JumpBar-Label");
allLabel.setContents(ALL_LABEL_DISPLAY_NAME);
allLabel.setAlign(Alignment.LEFT);
allLabel.setOverflow(Overflow.HIDDEN);
allLabel.setWidth(24);
this.addMember(allLabel);
// initialise the LayoutSpacer
LayoutSpacer allLabelPadding = new LayoutSpacer();
allLabelPadding.setWidth("*");
this.addMember(allLabelPadding);
String alphabet = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ#";
String labelContents = "A";
for (int i = 0; i < 27; i++ ) {
Label label = new Label();
// allLabel.addStyleName("crm-JumpBar-Label");
label.setBaseStyle("crm-JumpBar-Label");
labelContents = alphabet.substring(i, i + 1);
label.setContents(labelContents);
label.setAlign(Alignment.CENTER);
label.setOverflow(Overflow.HIDDEN);
label.setWidth(20);
this.addMember(label);
if ( i < 26) {
LayoutSpacer padding = new LayoutSpacer();
padding.setWidth("*");
this.addMember(padding);
}
}
// add the LayoutSpacer to the JumpBar layout container
LayoutSpacer paddingRight = new LayoutSpacer();
paddingRight.setWidth(8);
this.addMember(paddingRight);
}
}
We then need to update the Account's view class:
...
public class AccountsView extends VLayout {
private static final String DESCRIPTION = "AccountsView";
private static final String CONTEXT_AREA_WIDTH = "*";
public AccountsView() {
super();
GWT.log("init AccountsView()...", null);
// initialise the Accounts View layout container
this.addStyleName("crm-ContextArea");
this.setWidth(CONTEXT_AREA_WIDTH);
// add the Tool Bar, List Grid, Status Bar and Jump Bar to the Accounts View layout container
this.addMember(new ToolBar());
this.addMember(new ContextAreaListGrid());
this.addMember(new StatusBar());
this.addMember(new JumpBar());
}
We also need to add the following to the applications's style sheet, myCRM.css:
...
/*
* Context Area Status Bar
*/
.crm-StatusBar {
background-color: #f0f0f0;
border-bottom: 1px solid #999999;
font-family: Tahoma, Verdana, sans-serif;
font-size: 11px;
color: black;
cursor: pointer;
cursor: default;
}
.crm-StatusBar-Label {
font-family: Tahoma, Verdana, sans-serif;
font-size: 11px;
color: black;
cursor: pointer;
cursor: default;
padding-left: 8px;
padding-right: 8px;
}
/*
* Context Area Jump Bar
*/
.crm-JumpBar {
border-bottom: 1px solid #999999;
background-color: #f0f0f0;
font-family: Tahoma, Verdana, sans-serif;
font-size: 11px;
color: black;
cursor: pointer;
cursor: default;
/*
padding-left: 4px;
padding-right: 4px;
*/
}
.crm-JumpBar-Label {
font-family: Tahoma, Verdana, sans-serif;
font-size: 11px;
color: black;
cursor: pointer;
cursor: default;
}
.crm-JumpBar-LabelOver,
.crm-JumpBar-LabelDown {
font-weight: bold;
}
3. Test the application in development mode
Launch myCRM in development mode and it should now look like the following screen shot.

What's Next
At this point, we've built the user interface and added widgets and event handlers to the application. Next, we'll add support for multiple host pages to myCRM.
