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.

  1. Select the smartGWT widgets
  2. Implement the smartGWT widgets
  3. 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.

Add support for multiple host pages to myCRM