An Example Gallery of GXT(Ext GWT)

After written some blogs about GXT Grid and Tree I planned for merging all those in a single application. Beside this I want to test JDO in Google App Engine. As a result of this I have made a tiny application and deployed in the Google App Engine. Ext GWT (GXT) Example Gallery. I will be very pleased if you visit the site and give your valuable comment.

You can also check out the latest code of the project from Google svn by running this command

svn checkout http://gxtexamplegallery.googlecode.com/svn/trunk/ gxtexamplegallery-read-only





Add Context Menu with GXT(Ext GWT) TreePanel

Context Menu is frequently used with tree if you want to present a very user friendly interface to user like add,delete or enable,disable a tree node. Here i show you how you can add a context menu with add and delete menu items with GXT TreePanel very easily.
Create a new project named GxtContextMenuTree and add GXT library in the project. The tree node objects must possess the functionality of BaseTreeModel of GXT. I have used the same EmployeeTreeNode and Folder class for leaf and parent nodes that i used in my previous blogs related to GXT TreePanel. And in the TestData class i have populated the data to build the tree. You will find the code for these classes here.  Create a new package model under the client package and place the EmployeeTreeNode and Folder class there.



Now remove all the auto generated code from the GxtContextMenuTree class which is the entry point class of your project.  Go to the onModuleLoad  method of the class and first create a root node of the tree. Then create a TreeStore, store and add data to this store from the root node. Now create a TreePanel, tree from this store and set some property of the tree.
final Folder rootNode = TestData.getTreeModel();

final TreeStore<ModelData> store = new TreeStore<ModelData>();
store.add((List) rootNode.getChildren(), true);

final TreePanel<ModelData> tree = new TreePanel<ModelData>(store);
tree.setDisplayProperty("name");
tree.getStyle().setLeafIcon(ICONS.user_add());
tree.setWidth(250);


Now create a gxt Menu and add two MenuItem insert and remove with the menu.
Menu contextMenu = new Menu();
contextMenu.setWidth(140);

MenuItem insert = new MenuItem();
insert.setText("Insert Item");
insert.setIcon(ICONS.add());
contextMenu.add(insert);

MenuItem remove = new MenuItem();
remove.setText("Remove Selected");
remove.setIcon(ICONS.delete());
contextMenu.add(remove);

What you want to do by clicking on these menu items, just write them in the addSelectionListener method of the MenuItem. Then set the menu to the tree as a context menu by setContextMenu method of the TreePanel.
insert.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
ModelData folder = tree.getSelectionModel().getSelectedItem();
if (folder != null) {
Folder child = new Folder("Add Child " + count++);
store.add(folder, child, false);
tree.setExpanded(folder, true);
}
}
});

remove.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
List<ModelData> selected = tree.getSelectionModel().getSelectedItems();
for (ModelData sel : selected) 
{
store.remove(sel);
}
}
});

tree.setContextMenu(contextMenu);
RootPanel.get().add(tree);

In the addSelectionListener method of the insert menu item i have written the code for adding a Folder node with the selected node and in the same method of the remove menu item code for removing a list of selected nodes. To view the live demo of this tutorial Click here.

contextMenuTree

Add Filter Functionality with GXT(Ext GWT) TreePanel

In my previous blog i have articulated how you can create a basic tree using the GXT TreePanel. In the next few blogs i will try to write about some marvelous features which can be easily integrated with TreePanel. Here i state how to add filter functionality with TreePanel.

Create a new project named GxtFilterTree and add GXT library in the project. The tree node objects must possess the functionality of BaseTreeModel of GXT. I have used the same EmployeeTreeNode and Folder class for leaf and parent nodes that i used in my previous blog. And in the TestData class i have populated the data to build the tree. You will find the code for these classes here.

Go to the onModuleLoad method of GxtFilterTree class. Remove all the auto generated code of this method. Now create a TreeLoader, loader.

TreeLoader<ModelData> loader = new BaseTreeLoader<ModelData>(
  new TreeModelReader<List<ModelData>>());

BaseTreeLoader is default implementation of the TreeLoader interface which also extends the functionality of BaseLoader. Then create TreeStore, store by using the loader and create a TreePanel, tree with the store. Pass the root of the tree to the loader.load method as a load configuration which loads data using the configuration. You can get the root node from getTreeModel method of TestData class.




TreeStore<ModelData> store = new TreeStore<ModelData>(loader);
TreePanel<ModelData> tree = new TreePanel<ModelData>(store);
tree.setAutoLoad(true);
tree.setDisplayProperty("name");
tree.setWidth(250);
tree.setIconProvider(new ModelIconProvider<ModelData>() {
  public AbstractImagePrototype getIcon(ModelData model) {
    if (((TreeModel) model).isLeaf()) {
      return ICONS.user_add();
    }
    return null;
  }
});
loader.load(TestData.getTreeModel());

setAutoLoad method sets whether all children should automatically be loaded recursively. Other setter methods of TreePanel are self explanatory.

Now the time for creating a StoreFilterField and bind this to the store.
StoreFilterField<ModelData> filter = new StoreFilterField<ModelData>() {
  @Override
  protected boolean doSelect(Store<ModelData> store,
  ModelData parent, ModelData record, String property,
  String filter) {
    // only match leaf nodes
    if (record instanceof Folder) { 
      return false;
    }
    String name = record.get("name");
    name = name.toLowerCase();
    if (name.startsWith(filter.toLowerCase())) {
      return true;
    }
    return false;
  }
};
filter.bind(store);

StoreFilterField can filter any Store implementation. You just have to implement the doSelect method this class. Here i have matched only the leaf node.

You are just one step behind to run the application. Create a panel to add the filter and the tree and add that panel to the RootPanel. That’s all. Run the application and check the filter functionality.
VerticalPanel panel = new VerticalPanel();
panel.addStyleName("x-small-editor");
panel.setSpacing(8);
panel.add(new Html("<span class=text>Enter a search string such as 'dirk'</span>"));
panel.add(filter);
panel.add(tree);
RootPanel.get().add(panel);

}
To view the live demo of this tutorial Click here.

treeWithFilterFunc

How to Create a Simple Tree Using GXT(Ext GWT) TreePanel

TreePanel is another powerful UI tools provide by GXT.  It has expand-collapse functionality. You can add context menu or can add filter functionality with the TreePanel very easily. Here i describe every steps of creating a simple basic Tree using GXT in detail.

First create a new project named GxtBasicTree and add GXT library in the project. The tree node objects must possess the functionality of BaseTreeModel of GXT. In my example the leaf node objects are of EmployeeTreeNode class and parent node objects are of Folder class. Both of the classes extend BaseTreeModel class. Here is the code for the Employee class.

package com.ratul.GxtBasicTree.client.model;

import java.util.Date;

import com.extjs.gxt.ui.client.data.BaseTreeModel;

public class EmployeeTreeNode extends BaseTreeModel {
 private static final long serialVersionUID = 1L;

public EmployeeTreeNode() {
  }

  public EmployeeTreeNode(String name, double salary, Date joiningdate) {
    set("name", name);
    set("salary", salary);
    set("joiningdate", joiningdate);
  }

  public Date getJoiningdate() {
    return (Date) get("joiningdate");
  }

  public String getName() {
    return (String) get("name");
  }

  public double getSalary() {
    Double salary = (Double) get("salary");
    return salary.doubleValue();
  }
  public String toString() {
    return getName();
  }
}
As i have said previously the objects of the Folder class can be parent node for the Tree. So this class should have the functionality of adding children nodes. The constructor with a String and an Array of BaseTreeModel object serves the purpose. Here is the code for the Folder class.



package com.ratul.GxtBasicTree.client.model;

import java.io.Serializable;

import com.extjs.gxt.ui.client.data.BaseTreeModel;

public class Folder extends BaseTreeModel implements Serializable {
 private static final long serialVersionUID = 1L;
private static int ID = 0;
  
  public Folder() {
    set("id", ID++);
  }

  public Folder(String name) {
    set("id", ID++);
    set("name", name);
  }

  public Folder(String name, BaseTreeModel[] children) {
    this(name);
    for (int i = 0; i < children.length; i++) {
      add(children[i]);
    }
  }

  public Integer getId() {
    return (Integer) get("id");
  }

  public String getName() {
    return (String) get("name");
  }

  public String toString() {
    return getName();
  }
}

Now populate a root node containing all the child nodes by using the above two classes in the getTreeModel methodh of the TestData class.
package com.ratul.GxtBasicTree.client;

import com.google.gwt.i18n.client.DateTimeFormat;
import com.ratul.GxtBasicTree.client.model.Employee;
import com.ratul.GxtBasicTree.client.model.Folder;

public class TestData {

  public static Folder getTreeModel() 
  {
     DateTimeFormat f = DateTimeFormat.getFormat("yyyy-mm-dd");
  Folder[] folders = new Folder[] {
   new Folder("General Administration", new Folder[] {
    new Folder("General Manager", new EmployeeTreeNode[] {
     new EmployeeTreeNode("Hollie Voss", 150000, f.parse("2006-05-01")),
     new EmployeeTreeNode("Heriberto Rush", 150000,f.parse("2007-08-01")), }),
    new Folder("Executive", new EmployeeTreeNode[] {
     new EmployeeTreeNode("Christina Blake", 45000,f.parse("2008-11-01")),
     new EmployeeTreeNode("Chad Andrews", 45000, f.parse("2008-07-01")), }), }),
 
   new Folder("Information Technology",new Folder[] {
    new Folder("Senior S/W Engineer",new EmployeeTreeNode[] {
     new EmployeeTreeNode("Dirk Newman", 70000,f.parse("2007-08-21")),
     new EmployeeTreeNode("Emerson Milton",72000,f.parse("2009-05-07")),
     new EmployeeTreeNode("Gail Horton", 680000,f.parse("2008-05-01")), }),
    new Folder("S/W Engineer",new EmployeeTreeNode[] {
     new EmployeeTreeNode("Claudio Engle", 50000,f.parse("2007-02-01")),
     new EmployeeTreeNode("Buster misjenou",52000,f.parse("2009-06-10")),
     new EmployeeTreeNode("Bell Snedden", 50000,f.parse("2008-12-01")),
     new EmployeeTreeNode("Benito Meeks", 55000,f.parse("2006-05-01")), }), }),
 
   new Folder("Marketing", new Folder[] { 
    new Folder("Executive",new EmployeeTreeNode[] {
     new EmployeeTreeNode("Candice Carson", 50000, f.parse("2007-08-21")),
     new EmployeeTreeNode("Mildred Starnes", 50000,f.parse("2008-05-01")),
     new EmployeeTreeNode("Claudio Engle", 50000, f.parse("2009-06-15")), }), }), 
  };

  Folder root = new Folder("root");
  for (int i = 0; i < folders.length; i++) {
   root.add((Folder) folders[i]);
  }

  return root;
  }
}
You data is now ready to create a simple Tree. Go to the onModuleLoad method of GxtBasicTree class. Remove all the auto generated code of this method. Now first create a root object named model of the Folder class from TestData.getTreeModel() method and create a TreeStore object,store from this model.
public static final ExampleIcons ICONS = GWT.create(ExampleIcons.class);
public void onModuleLoad() 
{
       Folder model = TestData.getTreeModel();  
     
       TreeStore<ModelData> store = new TreeStore<ModelData>();  
       store.add(model.getChildren(), true);  
 
Now create a TreePanel, tree from this store and set display name, width and style of the tree.
final TreePanel<ModelData> tree = new TreePanel<ModelData>(store);  
       tree.setDisplayProperty("name");  
       tree.setWidth(250);  
       tree.getStyle().setLeafIcon(ICONS.user_add());
The two button expand and collapse provide the expand and collapse functionality by simple calling the tree.expandAll() and tree.collapseAll() method.
ButtonBar buttonBar = new ButtonBar();  
       Button expand = new Button("Expand All"); 
       Button collapse = new Button("Collapse All"); 
       expand.addSelectionListener(new SelectionListener<ButtonEvent>() {  
       public void componentSelected(ButtonEvent ce) {  
           tree.expandAll();  
         }  
       });
       
       collapse.addSelectionListener(new SelectionListener<ButtonEvent>() {  
        public void componentSelected(ButtonEvent ce) {  
            tree.collapseAll();  
          }  
        });
       buttonBar.add(expand);
       buttonBar.add(collapse);
        
       RootPanel.get().add(buttonBar);
       RootPanel.get().add(tree);
       
 }


That's all. Run it and check the functionality of the simple tree. To view the live demo of this tutorial Click here.

Working with GXT(Ext GWT) Grid : Create an Editable Grid

Last week i was so busy that i can not afford to manage time on writing. And i am afraid that whether i can keep my promise on writing a series of tutorials about GXT and GWT or not. In the upcoming days i have to work in six! projects simultaneously. Good thing is that there will be a lot of new things that i can learn and surely i will share those here whenever i get time. Now i will show you how you can make a GXT Grid editable with TextField, ComboBox and Date Picker.

Create a new project named GxtEditableGrid and add GXT library in the project. As like my previous blogs about GXT Grid i have used the same Employee model and TestData class for generating data. You will find the code of these classes here. Go to the onModuleLoad method of GxtEditableGrid class and remove all the auto generated code of this method.

Starting with creating a list of ColumnConfig and a ColumnConfig instance named column. Configure this column to show and edit Employee Name first. To add the editing functionality create a TextField and a CellEditor with this TextField. Then set the CellEditor as the editor of the column.

List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
ColumnConfig column = new ColumnConfig();
column.setId("name");
column.setHeader("Employee Name");
column.setWidth(200);
TextField<String> text = new TextField<String>();  
text.setAllowBlank(false);  
text.setAutoValidate(true);  
column.setEditor(new CellEditor(text));
configs.add(column); 



For the Department column rather than using a TextField we are going to use a ComboBox to edit this field. First create a SimpleComboBox and add the possible values to it.

final SimpleComboBox<String> combo = new SimpleComboBox<String>();  
combo.setTriggerAction(TriggerAction.ALL);  
combo.add("General Administration");  
combo.add("Information Technology");  
combo.add("Marketing");  
combo.add("Accounts"); 

Then create a CellEditor with the SimpleComboBox and set it as the editor of the department column.

CellEditor editor = new CellEditor(combo) {  
@Override  
public Object preProcessValue(Object value) {  
if (value == null) {  
return value;  
}  
return combo.findModel(value.toString());  
}  

@Override  
public Object postProcessValue(Object value) {  
if (value == null) {  
return value;  
}  
return ((ModelData) value).get("value");  
}  
};  

column = new ColumnConfig("department", "Department", 150);
column.setAlignment(HorizontalAlignment.LEFT);
column.setEditor(editor);  
configs.add(column);

For the Designation column configure it like the Employee Name column and for the Salary column set a cell editor with NumberField. That is this field will only accept numeric values.

column = new ColumnConfig("designation", "Designation", 150);
column.setAlignment(HorizontalAlignment.LEFT);
TextField<String> text2 = new TextField<String>();  
text2.setAllowBlank(false);  
text2.setAutoValidate(true);  
column.setEditor(new CellEditor(text2));
configs.add(column);

column = new ColumnConfig("salary", "Slary", 100);  
column.setAlignment(HorizontalAlignment.RIGHT);  
final NumberFormat number = NumberFormat.getFormat("0.00");  
GridCellRenderer<Employee> checkSalary = new GridCellRenderer<Employee>() {  
public String render(Employee model, String property, ColumnData config, int rowIndex,  
int colIndex, ListStore<Employee> employeeList, Grid<Employee> grid) {  
double val = (Double) model.get(property);  
String style = val < 70000 ? "red" : "green";  
return "<span style='color:" + style + "'>" + number.format(val) + "</span>";
}  
};  
column.setRenderer(checkSalary); 
column.setEditor(new CellEditor(new NumberField()));  
configs.add(column);

To change date field in a Grid with date picker create a DateField, set a date fomat for the DateField and finally set this as the editor for the ColumnConfig.

DateField dateField = new DateField();  
dateField.getPropertyEditor().setFormat(DateTimeFormat.getFormat("MM/dd/y"));

column = new ColumnConfig("joiningdate", "Joining Date", 100);
column.setAlignment(HorizontalAlignment.RIGHT);
column.setEditor(new CellEditor(dateField));  
column.setDateTimeFormat(DateTimeFormat.getMediumDateFormat());
configs.add(column);

To enable the editable functionality of grid you have to create an instance of EditorGrid class instead of a Grid class now. Other things are described in my previous tutorials about GXT Grid.

ListStore<Employee> employeeList = new ListStore<Employee>();
employeeList.add(TestData.getEmployees());
ColumnModel cm = new ColumnModel(configs);

final EditorGrid<Employee> grid = new EditorGrid<Employee>(employeeList, cm);
grid.setStyleAttribute("borderTop", "none");
grid.setAutoExpandColumn("name");
grid.setBorders(true);
grid.setStripeRows(true);

ContentPanel cp = new ContentPanel();
cp.setBodyBorder(false);
cp.setHeading("Employee List");
cp.setButtonAlign(HorizontalAlignment.CENTER);
cp.setLayout(new FitLayout());
cp.setSize(700, 300);
cp.add(grid);
RootPanel.get().add(cp);

That's all. Run the application check the magic GXT. To view the live demo of this tutorial Click here.

editableGrid

Working with GXT(Ext GWT) Grid : Add Grouping Funtionality

Grouping is very helpful when you view a large set of data. It creates a more readable view for the user. GXT provides us with a very easy way of adding grouping functionality with a grid. Here i describe how to add grouping functionality with GXT grid.

Create a new project named GxtGridGrouping and add GXT library in the project. As like my previous blogs about GXT Grid i have used the same Employee model and TestData class for generating data. You will find the code of these classes here. Go to the onModuleLoad method of GxtGridGrouping class and remove all the auto generated code of this method.

First create an instance of GroupingStore, a specialized store implementation which extends the ListStore that provides for grouping models by one of the available fields.

GroupingStore<Employee> employeeList = new GroupingStore<Employee>();  
employeeList.add(TestData.getEmployees());  
employeeList.groupBy("department");   

The groupBy method takes a property of your model by which you want to group your grid. In the example i have grouped the grid by 'department' property. You can change it to 'designation' property and see how it works.

Now define a list of ColumnConfig and a ColumnModel by using this list as before.
List<Columnconfig> configs = new ArrayList<Columnconfig>();

ColumnConfig column = new ColumnConfig();  
column.setId("name");  
column.setHeader("Employee Name");  
column.setWidth(200);  
configs.add(column);

column = new ColumnConfig("department", "Department", 150);  
column.setAlignment(HorizontalAlignment.LEFT);  
configs.add(column);

column = new ColumnConfig("designation", "Designation", 150);   
column.setAlignment(HorizontalAlignment.LEFT);  
configs.add(column);

column = new ColumnConfig("salary", "Slary", 100);  
column.setAlignment(HorizontalAlignment.RIGHT);  
final NumberFormat number = NumberFormat.getFormat("0.00");  
GridCellRenderer<Employee> checkSalary = new GridCellRenderer<Employee>() {  
public String render(Employee model, String property, ColumnData config, int rowIndex,  
int colIndex, ListStore<Employee> employeeList, Grid<Employee> grid) {  
double val = (Double) model.get(property);  
String style = val < 70000 ? "red" : "green";  
return "<span style='color:" + style + "'>" + number.format(val) + "</span>"; 
}  
};  
column.setRenderer(checkSalary);  
configs.add(column);

column = new ColumnConfig("joiningdate", "Joining Date", 100);  
column.setAlignment(HorizontalAlignment.RIGHT);  
column.setDateTimeFormat(DateTimeFormat.getShortDateFormat());  
configs.add(column);

final ColumnModel cm = new ColumnModel(configs); 

Create an instance of GroupView which groups the data based on the GroupStore. Then set it as the view of the Grid.

GroupingView view = new GroupingView();  
view.setForceFit(true);  
view.setGroupRenderer(new GridGroupRenderer() {  
public String render(GroupColumnData data) {  
String f = cm.getColumnById(data.field).getHeader();  
String l = data.models.size() == 1 ? "Item" : "Items";  
return f + ": " + data.group + " (" + data.models.size() + " " + l + ")";  
}  
});  

Grid<Employee> grid = new Grid<Employee>(employeeList, cm);  
grid.setView(view);  
grid.setBorders(true);

Here setForceFit is set true to auto expand the columns to fit the grid width and setGroupRenderer is used to create a heading for the groups.

Finally add the grid to the content panel.

ContentPanel cp = new ContentPanel();  
cp.setBodyBorder(false);  
cp.setHeading("Employee List");  
cp.setButtonAlign(HorizontalAlignment.CENTER);  
cp.setLayout(new FitLayout());  
cp.setSize(700, 420); 
cp.add(grid);  
RootPanel.get().add(cp);



Run the application and see how readable the grid is now. To view the live demo of this tutorial Click here.
gxtGridGrouping

Working with GXT(Ext GWT) Grid : Add Local Pagination Functionality

In my previous blog i have described how to create a simple Grid of GXT.  I have a plan to write a series of blog about other useful functionalities which can be added to the Grid. Here i write down the way of adding local pagination functionality with the Grid.

Create a new project named GxtPagingExample and add GXT library in the project. To create a grid at first you need a base model class and have to generate data for that model. In this tutorial i have used the same Employee model and TestData class for generating data which i used in my previous blog. You will find the code of these classes there.

Now go to the onModuleLoad method of GxtPagingExample class. Remove all the auto generated code of this method. First create an instance of PagingModelMemoryProxy which is a specialized DataProxy that supports paging when the entire data set is in the memory.

PagingModelMemoryProxy proxy = new PagingModelMemoryProxy(TestData.getEmployees());
   PagingLoader loader = new BasePagingLoader(proxy);
   loader.setRemoteSort(true);
   ListStore<Employee> employeeList = new ListStore<Employee>(loader);  
BasePagingLoader is an implementation of the PagingLoader interface which loads data using the proxy.If remote sort is enable then it will allow you to sort between the whole data set otherwise the sorting will be done only between the viewable data set. Then create a ListStore of Employee type.




Now create a PagingToolBar widget then bind it with the loader. It takes the page size in the constructor.
final PagingToolBar toolBar = new PagingToolBar(5);
   toolBar.bind(loader);
   loader.load(0, 5);
The arguments of the load method of PagingLoader are the begin index and page size.

Create a list of ColumnConfig and define each column. Then create a grid and add the grid and the PagingToolBar in a panel.

List<Columnconfig> configs = new ArrayList<Columnconfig>();

ColumnConfig column = new ColumnConfig();  
column.setId("name");  
column.setHeader("Employee Name");  
column.setWidth(200);  
configs.add(column);

column = new ColumnConfig("department", "Department", 150);  
column.setAlignment(HorizontalAlignment.LEFT);  
configs.add(column);

column = new ColumnConfig("designation", "Designation", 150);  
column.setAlignment(HorizontalAlignment.LEFT);  
configs.add(column);

column = new ColumnConfig("salary", "Slary", 100);  
column.setAlignment(HorizontalAlignment.RIGHT);  
final NumberFormat number = NumberFormat.getFormat("0.00");  
GridCellRenderer<Employee> checkSalary = new GridCellRenderer<Employee>() {  
public String render(Employee model, String property, ColumnData config, int rowIndex,  
int colIndex, ListStore<Employee> employeeList, Grid<Employee> grid) {  
double val = (Double) model.get(property);  
String style = val < 70000 ? "red" : "green";  
return "<span style='color:" + style + "'>" + number.format(val) + "</span>"; 
}  
};  
column.setRenderer(checkSalary);  
configs.add(column);

column = new ColumnConfig("joiningdate", "Joining Date", 100);  
column.setAlignment(HorizontalAlignment.RIGHT);  
column.setDateTimeFormat(DateTimeFormat.getShortDateFormat());  
configs.add(column);

ColumnModel cm = new ColumnModel(configs);
Grid<Employee> grid = new Grid<Employee>(employeeList, cm); 
grid.setStyleAttribute("borderTop", "none"); 
grid.setAutoExpandColumn("name"); 
grid.setBorders(true); 
grid.setStripeRows(true);

ContentPanel cp = new ContentPanel();  
cp.setBodyBorder(false);  
cp.setHeading("Employee List");  
cp.setButtonAlign(HorizontalAlignment.CENTER);  
cp.setLayout(new FitLayout());  
cp.setSize(700, 300); 
cp.add(grid);  
cp.setBottomComponent(toolBar);
RootPanel.get().add(cp);

Explanation of the above code is written here.
That's all. Run the application and test the pagination functionality. To view the live demo of this tutorial Click here.

Total Pageviews

Tags

Twitter Updates
    follow me on Twitter

    Followers