Wednesday, October 5, 2011

RIP Mr. Jobs


Right after getting home this evening, I saw a message from AP "Apple says Steve Jobs has died". My heart skipped a beat. So long i have been in the US, I loved and cherished all the apple products. I loved my first Mac in 2007 so much that a friend once said "If I was given a chance to choose between my wife and the Mac, I would go for the Mac".

I idolise and respect Steve Jobs for his vision and along with his contributions to the technology industry. I remember reading about Steve Jobs the first time on Wikipedia and since then I have been trying to understand how a college dropout could touch so many lives with his products, and achieve so much power and recognition over the course of years. We just cannot think that apple team got a few good ideas and Jobs got the recognition. He would give his 100% to every task starting with the start of Apple, to turning around the face of Pixar to one of the best animation companies in the world, to creating magic on getting back to apple. Who would have thought that a computer company would come in to revolutionize a mobile sector in just 4 years and capture about 5% of the worlds mobile phone market.

I consider Steve to be one of the best presenters of all time. I agree that i have seen very few product announcements but watching Steve Jobs present, is absolutely fantastic. Many a times, in his keynotes and product launches, I have noticed that people do come in to watch and listen to Mr. Jobs speak more than for the actual product. I was overwhelmed to see that people gave Steve jobs a standing ovation during his WWDC keynote address (Sadly that was his last).

Rest in Peace Mr. Steve jobs.
And one more thing, Thank you for all you have to this world and  you were and will always be my role model.

Edit: A pretty good site to read more about Steve Jobs

Friday, January 14, 2011

Wikipedia spoken articles

Wow!! I might be the last one to know but Wikipedia is currently working with spoken articles for people who can understand but not read English and also to listen to articles during workouts, house work etc(WikiProject), a pretty good idea I would say, and getting them on its mobile sites would be awesome!!.


Currently (as far as I know) only a few of the articles are spoken and Wikipedia highly encourages you to generate spoken content. Articles with spoken content will have a speaker image right by the name of the article ( as in the image)..
An article that I came across is Service-oriented architecture

Tuesday, November 30, 2010

google.com/docs

Well today i was trying to open my google documents and i keyed in google.com/docs hoping that google would redirect me to documents, apparently it didnot but instead it downloaded an empty text file with the name "docs" into my downloads folder. Is google trying to do something which i didnot know about or is there something wrong with the system?

Monday, November 22, 2010

browser and the web

Learn more about the browser, and how the internet works, written for naive users by the guys at Google Chrome in 20 things I learned about Browser and the Web.

Wednesday, November 3, 2010

Managing history in GWT

Managing history is one of the important task of an AJAX application. The GWT application is mostly a single page and so the developer has to take care of what to do with the forward and back buttons. One easy but not so good step is to take out the toolbar from the browser all together, so that we don’t need to worry about it. A better approach is to preserve the history of the major changes in the application so that they are easily accessible with the back and forward buttons.

To explain more about the history I will be considering a simple login application as most of the examples do. I create a splash screen with a “SignIn” button clicking which will take you to the login page with username and password fields and demonstrate history on it.

  1: package com.snippets.client;
  2: 
  3: import com.google.gwt.core.client.EntryPoint;
  4: import com.google.gwt.event.dom.client.ClickEvent;
  5: import com.google.gwt.event.dom.client.ClickHandler;
  6: import com.google.gwt.event.logical.shared.ValueChangeEvent;
  7: import com.google.gwt.event.logical.shared.ValueChangeHandler;
  8: import com.google.gwt.user.client.History;
  9: import com.google.gwt.user.client.ui.Button;
 10: import com.google.gwt.user.client.ui.Grid;
 11: import com.google.gwt.user.client.ui.Label;
 12: import com.google.gwt.user.client.ui.PasswordTextBox;
 13: import com.google.gwt.user.client.ui.RootPanel;
 14: import com.google.gwt.user.client.ui.TextBox;
 15: import com.google.gwt.user.client.ui.VerticalPanel;
 16: 
 17: public class Snippets implements EntryPoint {
 18: 	private static final String LOGIN_PAGE = "Login";
 19: 	private static final String SPLASH_PAGE = "Splash";
 20: 
 21: 	VerticalPanel verticalPanel ;
 22: 
 23: 	public void onModuleLoad() {
 24: 		verticalPanel  = new VerticalPanel();
 25: 
 26: 		History.addValueChangeHandler(new ValueChangeHandler<String>() {
 27: 
 28: 			@Override
 29: 			public void onValueChange(ValueChangeEvent<String> event) {
 30: 				if (LOGIN_PAGE.equals(event.getValue())) 
 31: 				{
 32: 					loginPage();
 33: 				}
 34: 				else if (SPLASH_PAGE.equals(event.getValue())) 
 35: 				{
 36: 					splashPage();
 37: 				}
 38: 			}
 39: 		});
 40: 		History.newItem(SPLASH_PAGE);
 41: 		RootPanel.get().add(verticalPanel);
 42: 	}
 43: 
 44: 	private void loginPage()
 45: 	{
 46: 		final Grid grid = new Grid(3, 2);
 47: 		final Label userName = new Label("name");
 48: 		final TextBox userBox = new TextBox();
 49: 		final Label passwordLabel = new Label("password");
 50: 		final PasswordTextBox passwordBox = new PasswordTextBox();
 51: 
 52: 		final Button loginButton = new Button("login");
 53: 
 54: 		grid.setWidget(0, 0, userName);
 55: 		grid.setWidget(0, 1, userBox);
 56: 
 57: 		grid.setWidget(1, 0, passwordLabel);
 58: 		grid.setWidget(1, 1, passwordBox);
 59: 
 60: 		grid.setWidget(2, 1, loginButton);
 61: 		verticalPanel.clear();
 62: 		verticalPanel.add(grid);
 63: 	}
 64: 
 65: 	private void splashPage()
 66: 	{
 67: 		final Label message = new Label("Welcome. Please login");
 68: 
 69: 		final Button button = new Button("Take Me to login Page");
 70: 		button.addClickHandler(new ClickHandler() {
 71: 
 72: 			@Override
 73: 			public void onClick(ClickEvent event) {
 74: 				History.newItem(LOGIN_PAGE);			
 75: 			}
 76: 		});
 77: 		verticalPanel.clear();
 78: 		verticalPanel.add(message);
 79: 		verticalPanel.add(button);
 80: 	}
 81: }

Firstly, History is basically a stack. So the item first inserted will be last one to be returned. Each of the state in the history is represented with a particular string that is appended to the URL with a “#” sign.

  1. Initially on page load I am setting up the first history item as in line 40.
  2. On the button click in the first page I am going to the next one, so as the state is changed on the button click I am going to add the new page to the history stack using the newItem method again. Line 74
  3. Finally I am adding a history listener to determine what page should be retrieved when a particular token is pulled out from the stack.

GWT internally uses the “window.location.hash” to get the token and send it to the listener. Its up to the developer to determine what to do when a particular token is encountered.

PS: I never worked on managing history on a large application, so I am not quite sure how it will pan out . But I am willing to work on it if some one is interested.

Tuesday, July 20, 2010

Combobox setValue

In a combobox the selectionChangedEvent is called when a value is selected from the combobox and also when setValue method is used. There is always a requirement that the event should be called only when a value is selected from the list than when programmatically setting the value.

One idea i was given when going through Sencha forums is to disable all the events before setting the value and then enabling them back again (this is a little weird, as this requirement comes up most of the time. They should probably try to make it a little easier than that)..

But anyways it works for now.

  1: combobox.disableEvents(true);
  2: combobox.setValue();  //set a value
  3: combobox.enableEvents(true);

Editor Grid and checkboxSelectionModel

I experienced that the check box selection model and the editor grid does not go along well if we are clicking on the row rather than only the check box. The problem is that the row gets selected and deselected when the editable cells are changed.

I needed to enable the select only when we click the first 2 columns and just editable on the rest.

A solution is to override handleMouseDown

  1: @Override
  2: protected void handleMouseDown(GridEvent e) {
  3: 	if (checkBoxOnly || checkBoxSynchronized) {
  4:         	if (e.getColIndex() < 3 && e.getEvent().getButton() == NativeEvent.BUTTON_LEFT) { 
  6: 	        	M m = listStore.getAt(e.getRowIndex());
  7: 			if (m != null) {
  8: 		        	if (isSelected(m)) {
  9: 					doDeselect(Arrays.asList(m), false);
 10: 				} else {
 11: 					doSelect(Arrays.asList(m), true, false);
 12: 				}
 13: 			}
 14: 		}
 15: 	} else {
 16: 	       super.handleMouseDown(e);
 17: 	}
 18: }

Monday, July 19, 2010

changing the color of the text in the combobox’s Textbox

Haa!! extjs has changed it named to sencha. Well I might be the last one mentioning it :).

Well coming back to what i was about to write in this post. I had this requirement of coloring the text in the combobox's text box. As i searched for it, i could not find a better solution than this one.

The list values in the combobox can be color coded using the template.

combobox.setSimpleTemplate("<font color='{color}'>{name}</font>");

Now if a particular item from the list is selected that has a different color, the color changes to black in the textBox. Inorder to maintain the color of the list item, I tried something like this.

  1: combobox.addSelectionChangedListener(new SelectionChangedListener<ModelData>() {
  2: 	@Override
  3: 	public void selectionChanged(SelectionChangedEvent<ModelData> se) {
  4: 		if(deptjob.getValue() != null ) {
  5:               		ModelData md = combobox.getValue();
  6: 			combobox.el().getChild(0).setStyleAttribute("color", md.get("color").toString());
  7: 		}
  8: 	}
  9: });
Any ideas on a better way in solving this problem is appreciated.

Tuesday, April 20, 2010

Grid Row Refresh GXT

Probably most of you out there must have known how to do that. But to just put it in paper, this is how we can refresh a particular grid row instead of refreshing or reloading the entire grid.

                      GridView has a refreshRow method inbuilt but it is not publicly available for some reason. So we can extend the GridView class as shown below to create our own method of refreshRow. Using refreshRow instead of refreshing the whole grid is faster when you are working on a grid with way too much data.

import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.store.StoreEvent;
import com.extjs.gxt.ui.client.widget.grid.GridView;
public class MyGridView extends GridView{
	@Override
	public void refreshRow(int row) {
		super.refreshRow(row);
	}
}

Friday, February 19, 2010

Grouping and Sorting grid GXT

If sorting has to be applied with grouping, grouping should be done first and then sort should be applied. This is because GXT grid grouping changes the sort order based on the grouping.

Monday, February 15, 2010

Array functions in javascript

Finally my first post of the year. Coding in core javascript scared me from the beginning because it does not have a perfect IDE with intellisense as java for eclipse. Coming to the point, I decided to improve myself in javascript. I was actually going through the arrays in javascript and read about some interesting functions. So decided to jot them down for my reference later. I am not sure how popular or how efficient these functions are. Most of my work's application is developed in javascript and I dont remember seeing any of these functions.

Lets consider we created an array      

  var array = ['kolli','ravi'];

Coming to the functions:

1) Push and pop: These are the simple functions that we all know since our undergrad mostly in data structures, stacks. So in an array push adds an element to the end of the array and pop deletes an element from the end of the array.

Eg:

array.push('kanth');

This statement adds ‘kanth’ to the end of the array now the array being [‘kolli’,’ravi’,’kanth’]

array.pop();

This statement removes the last element in the array resulting in [‘kolli’,‘ravi’]

2) unshift and shift: These functions are also used to insert and remove elements from the array but from the other end (beginning of the array).

Eg:

array.unshift("hye");

This statement adds ‘Hye’ to the beginning of the array resulting in [‘hye’,’kolli’,’ravi’]

array.shift();

This statement removes the first element in the array. Result: [‘kolli’,’ravi’']

3) Splice: This is a little more complex function than the others. It can be used to add, remove, replace elements in the array.

Syntax:

splice(StartingPos, NoofItemsToDelete, Items_to_add);

Eg:

array.splice(2,0,'kanth');

This statement is going to insert ‘kanth’ at location 2 of the array, without deleting anything.

array.splice(2,1);

This statement is going to remove 1 element starting from position 2.

array.splice(1,1,'rocks');

This statement is going to replace the element in position 1 resulting in array [‘kolli’,’rocks’].

Finally one more advantage of this function is that it lets us add more than one element to the array by just separating them with a ‘,’.

Friday, November 20, 2009

chrome OS

Finally i got to install chrome OS on my Mac using virtual Box. Well installing it is not my own intelligence though. I was using this techcrunch article. Well google has almost all the basic applications that are needed for daily use and most importantly run on a browser.
Coming to the actual OS, it opens up a browser and you are going to stay in here all your time. Its a little weird in the beginning as I am used to a whole bunch of windows in my task bar.
1) Firstly it authentication is done with ur google account.
2) It has the gmail and google calendar in 2 tabs that cannot be removed.
3) Oddly enough, I am able to open multiple windows of the browser but I cannot actually see the list of all the windows as a whole to toggle between. I am not sure if I am doing something wrong but that is a required must.

I can say that on a whole it looks like working only on chrome browser on my windows machine. Nothing essentially great about it. But the actual idea of having an OS exclusively to browse the web is pretty good.

I am also not sure about how far this is going to be useful in the netbook world too, because as far as i have read, it has its own hardware requirements, which might mean that once i get a netbook with chrome OS i might not be able to change my operating system to something else if I am actually not interested in it. Well as it has been now released into the open source world and it has almost one year to go before it is released, i am positive that it will be made to something pretty awesome by then.

Monday, November 9, 2009

Changing the grid CSS

Well, most of you guys might have known this, I am just putting it in for my reference.

Problem: If my application uses multiple grids and i want to have different CSS for each of the grids. What should i do?

Solution: 1) Set the Id of the grid.

grid.setId("myGrid");

2) Lets say I want to change the cell height and add borders to the cell of the above grid, I can change it by changing the css for that particular grid.

#myGrid .x-grid3-cell-inner 
{
    HEIGHT : 30px !important;  
    border: 1px solid #C0C0C0 !important;
}

Monday, October 19, 2009

How to set the grid row style?

Well the column style can be set using the GridCellRenderer, but there is a completely different way to set the style of a row.

GridViewConfig gvc = new GridViewConfig(){
public String getRowStyle(ModelData model, int rowIndex, ListStore ds) {
    return "row-Style";  // Style to be set to a row
  }
};
grid.getView().setViewConfig(gvc);

User specific conditions can be checked in getRowStyle to set different styles to different rows.

Friday, August 21, 2009

Multi cell selection in a row using shift and control key – grid GXT

This post is an extension to this previous post. Code in the previous post is used to multi select cell in a row using the shift keys. It is updated to add functionality to select cells in a particular row using control key and also highlight the row that we are currently working on.

import java.util.ArrayList;
import java.util.List;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.widget.grid.CellSelectionModel;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
/**
 * This class is an extension of CellSelectionModel. 
 * The CellSelectionModel allows us to select only one cell at a particular time. 
 * This Class allows us to select multiple cells in a particular row in a grid.
 * Multi select is performed by pressing the shift key with the mouse click
 *  
 * @author Ravikanth Kolli
 * @version 1.0
 * 
 * 
 * @param <M>
 */
public class RowCellSelectionModel<M extends ModelData> extends CellSelectionModel<M> { 
int lastSelectedRow = -1;
int lastSelectedCol = -1;
private CellSelection selected ;
List<CellSelection> cellsSelected = new ArrayList<CellSelection>();
/**
 * Overriding the handleMouseDown event.
 * MultiSelect is done by pressing the shiftkey 
 */
@Override
protected void handleMouseDown(GridEvent e) {
super.handleMouseDown(e);
if(lastSelectedRow == -1)
{
selected = new CellSelection(listStore.getAt(e.getRowIndex()),e.getRowIndex(),e.getColIndex());
cellsSelected.add(selected);
lastSelectedRow = e.getRowIndex();
lastSelectedCol = e.getColIndex();
}else if (lastSelectedRow == e.getRowIndex() && (e.isShiftKey() || e.isControlKey())) {
// control key press adding or removing cell from the cellsSelected list. 
if(e.isShiftKey())
{
if(cellsSelected.size() > 0)
El.fly(grid.getView().getRow(cellsSelected.get(0).row)).removeStyleName("x-grid3-row-selected");
cellsSelected.clear();
for (int i = 1 ; i < e.getGrid().getColumnModel().getColumnCount(); i++) {
Element cell = grid.getView().getCell(lastSelectedRow, i);
if (cell != null) {
El.fly(cell).removeStyleName("x-grid3-cell-selected");
}
}
if(lastSelectedCol > e.getColIndex()){
for (int iter = e.getColIndex(); iter < lastSelectedCol+1 ; iter++)
{
selected = new CellSelection(listStore.getAt(e.getRowIndex()),e.getRowIndex(),iter);
cellsSelected.add(selected);
}
lastSelectedRow = e.getRowIndex();
}else
{
for (int iter = lastSelectedCol; iter < e.getColIndex() + 1 ; iter++)
{
selected = new CellSelection(listStore.getAt(e.getRowIndex()),e.getRowIndex(),iter);
cellsSelected.add(selected);
}
lastSelectedRow  = e.getRowIndex();
} 
}
// control key press adding or removing cell from the cellsSelected list. 
else if(e.isControlKey())
{
if(cellsSelected.size() > 0)
El.fly(grid.getView().getRow(cellsSelected.get(0).row)).removeStyleName("x-grid3-row-selected");
boolean isSelected = false;
for (int i =0 ; i < cellsSelected.size();i++)
{
El.fly(grid.getView().getCell(cellsSelected.get(i).row, cellsSelected.get(i).cell)).removeStyleName("x-grid3-cell-selected");
if(cellsSelected.get(i).row == e.getRowIndex() && cellsSelected.get(i).cell == e.getColIndex())
{
isSelected = true;
cellsSelected.remove(i);
}
}
if(!isSelected)
{
selected = new CellSelection(listStore.getAt(e.getRowIndex()), e.getRowIndex(), e.getColIndex());
cellsSelected.add(selected);
}
lastSelectedRow = e.getRowIndex();
}
}
else
{
if(!e.isRightClick() 
||  cellsSelected.size() == 0
|| !(cellsSelected.get(0).row == e.getRowIndex() && cellsSelected.get(0).cell <= e.getColIndex() && e.getColIndex() <= cellsSelected.get(cellsSelected.size() - 1).cell) 
||  cellsSelected.get(0).row != e.getRowIndex()){
if(cellsSelected.size() > 0)
El.fly(grid.getView().getRow(cellsSelected.get(0).row)).removeStyleName("x-grid3-row-selected");
cellsSelected.clear();
for (int i = 1 ; i < e.getGrid().getColumnModel().getColumnCount(); i++)
{
Element cell = grid.getView().getCell(lastSelectedRow, i);
if (cell != null) {
El.fly(cell).removeStyleName("x-grid3-cell-selected");
}
}
selected = new CellSelection(listStore.getAt(e.getRowIndex()),e.getRowIndex(),e.getColIndex());
cellsSelected.add(selected);
lastSelectedRow = e.getRowIndex();
lastSelectedCol = e.getColIndex();
}
}
/**
 * Add the cell selected style after all the events are handled
 */
DeferredCommand.addCommand(new Command() {
public void execute() {
      if(cellsSelected.size() > 0)
       {
El.fly(grid.getView().getRow(cellsSelected.get(0).row)).addStyleName("x-grid3-row-selected");
       }
for (int iter = 0 ; iter < cellsSelected.size() ; iter++) {
Element element = grid.getView().getCell(cellsSelected.get(iter).row,cellsSelected.get(iter).cell);
if (element != null) {
El.fly(element).addStyleName("x-grid3-cell-selected");
}
El.fly(grid.getView().getHeaderCell(cellsSelected.get(iter).cell)).setStyleName("x-setItalics");
}     
}
});
}
/**
 * Method to get the list of all the selected cells at a particular time
 * @return list of selected CellSelections.
 */
public List<CellSelection> getSelectedCells()
{
return cellsSelected;
}
/**
 * clear the selections in cellsSelected
 */
public void clearSelections()
{
cellsSelected.clear();
}
}

Thursday, August 13, 2009

Improving grid performance of an application GXT

For over a month now, I have been working on improving the performance of my application and get feedback from the clients for areas of improvement. My application was running really slow and the reason

1) IE being the only browser that our company supports, is pretty bad in handling white spaces(we do a lot of server side processing in ColdFusion which comes up with a lot white spaces)

Solution: shrink the ColdFusion file into a single line

2) JSONReader is taking a whole lot of time to extract the data and put it in a store.

Solution: After a lot of debugging, I figured out that “com.google.gwt.json.client.JSONObject” that is used in the JSONReader uses a HashMap to store the JSONValue and the get method of HashMap it the most time consuming.

GXT has FastMap which is pretty fast than HashMap. I try to override the mapping part of the JSONObject and try to generate my custom map using FastMap.

public Map<String, Object> decode(JSONObject jso) {
Map<String, Object> map = new FastMap<Object>();
for (String key : jso.keySet()) {
JSONValue j = jso.get(key);
map.put(key, j.isString().stringValue());
}
return map;
}

Whenever I try to get a single JSONValue i use the map to get the data. I tested it and is about 50-60% faster than the previous.

3) Grid rendering also takes a long time which increases with the number of rows.

Solution: I was going through the GXT blog and read about the buffered view for a grid, using which we can render only the rows in the grid that are visible, and each time the scroll bar is used previous rows are cleared from the DOM and new rows are added. This makes the rendering pretty fast and also the speed of the editing features in the grid is increased.

  1: BufferView view = new BufferView();
  2: view.setScrollDelay(10);
  3: view.setRowHeight(28);
  4: grid.setView(view);
The row height has to specified in the view and I think it is needed to decide the number of rows to be displayed.

Monday, July 20, 2009

Migration to GXT 2.0 from GXT 1.2.4

 

EXTJS released GXT 2.0 on July 6 2009.

GXT 2.0 uses GWT version of 1.6 and above. The project structure has been changed by using the WAR folder for all the configuration and public resource files. An eclipse plug-in  has been released at Google code which creates the project based on our required project structure, with the server configurations and WAR folder created for our convenience.

Coming to GXT there are a lot breaking changes in 2.0 and can be found under migration guide of your downloaded zip. some of the basic changes includes, variables that are accessed as such previously are changed to getter and setter methods, more events are added such as ButtonEvent, MessageBoxEvent etc, and also the ext-all.css that was used previously has been changed to gxt-all.css and has been placed under resources/css along with all the other images( this folder is also present within the downloaded zip).

Creating a project:

1) The eclipse plugin allows us to create a New Web Application Project that includes creating a new GWT module.

2) Copy resources/ folder from GXT into the WAR folder that was created by the wizard.

3) Add  <link rel="stylesheet" type="text/css" href="resources/css/gxt-all.css" /> to the HTML file that is also created in the WAR folder of the application.

4) The compiled code is also placed in the WAR folder

Monday, July 13, 2009

Disable the Browser’s context menu

The following lines of native JavaScript code can be used to disable the browsers context menu, when it is no more needed or if there is a user defined context menu. This method has to be called by the component that needs to have the menu disabled.

private static native void disableBrowserContextMenuJSNI() /*-{ 
         $doc.oncontextmenu = function() { return false; }; 
     }-*/; 

Tuesday, July 7, 2009

Error Messages gxt

Its been quite a while since i made a blog post. I have been working on generating a couple of reports for my application and generating those took forever. Now here i am finally done with my application and adding a few modifications to make it look good.

I was trying to get a TextField’s regex with the first character being a number. This post is mainly to change the error message we get with the little red exclamation mark beside the text field.

shiftNo.setRegex("[0-9][[0-9][a-z][A-Z]]*");
shiftNo.getMessages().setRegexText("shift number should always start with a number");

Tuesday, May 12, 2009

Grid Plugins

Additions to the grids like the Row Numberer, checkboxes, Row Expander are added as plugins to the Grid.

Adding Row Expander:

  1: XTemplate tpl = XTemplate.create("<p><b>Company:</b> {name}</p><br><p><b>Summary:</b> {desc}</p>");
  2: RowExpander expander = new RowExpander();
  3: expander.setTemplate(tpl);  

and then we need to add the plugin to the grid. We cannot apply a rowExpander to a Summary Grid.

grid.addPlugin(expander);

The XTemplate contains the information that has to be displayed when the “+” is clicked.

Adding Row Numberer:

  1: RowNumberer r = new RowNumberer();
  2: List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
  3: configs.add(r);  

and then add the plugin to the grid.

grid.addPlugin(r);
Adding Checkboxes:
  1: CheckBoxSelectionModel sm = new CheckBoxSelectionModel();
  2: configs.add(sm.getColumn());

Add the plugin to the grid

grid.addPlugin(sm);
Adding the grid plugin will provide automatic reorganization when the grid store values have changed.