Google

Wednesday, April 25, 2007

split panel

The split panel is something that is lacking in the google web toolkit.
Although it is not included in the GWT package, one can easily make a split panel as all the necessary stuff are already there.

This split panel can be set to be vertical, or horizontal.
The two panels are extended using SimplePanel as to wrap your widget within a div element.

Use either vertical or horizontal.

Just apply some css to add some aesthetics.

Here's the code.

package GWTApplication.client;

import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.HorizontalPanel;

import com.google.gwt.user.client.DOM;
/**
*
* @author mbaricuatro
*/
public class SplitPanel extends SimplePanel implements MouseListener{

public static int VERTICAL = 1;
public static int HORIZONTAL = 2;

private static int ALIGNMENT;
private boolean isDragging = false;

private Widget mainPanel;

private SimplePanel panel1 = new SimplePanel();
private SimplePanel panel2 = new SimplePanel();

private Label divider = new Label(" ");

private int StartX, StartY;

/** Creates a new instance of SplitPanel */
public SplitPanel(int style)
{
ALIGNMENT = style;
if (style == 1)
{
mainPanel = new VerticalPanel();
VerticalPanel temp = (VerticalPanel) mainPanel;
temp.add(panel1);
temp.add(divider);
temp.add(panel2);

divider.setSize("100%","5px");
DOM.setStyleAttribute(divider.getElement(), "cursor","n-resize");
}
else if (style == 2)
{
mainPanel = new HorizontalPanel();
HorizontalPanel temp = (HorizontalPanel) mainPanel;
temp.add(panel1);
temp.add(divider);
temp.add(panel2);

divider.setSize("5px","100%");
DOM.setStyleAttribute(divider.getElement(), "cursor","e-resize");
}

setWidget(mainPanel);


DOM.setStyleAttribute(divider.getElement(), "backgroundColor","#000066");
divider.addMouseListener(this);

DOM.setStyleAttribute(panel1.getElement(), "overflow","hidden");
DOM.setStyleAttribute(panel2.getElement(), "overflow","hidden");
}

public void setFirstPanel(Widget x)
{
panel1.setWidget(x);
}

public void setSecondPanel(Widget x)
{
panel2.setWidget(x);
}

public void onMouseDown(Widget sender, int x, int y)
{
DOM.setCapture(divider.getElement());
isDragging = true;
StartX = x;
StartY = y;
}
public void onMouseEnter(Widget sender){}
public void onMouseLeave(Widget sender){}
public void onMouseMove(Widget sender, int x, int y)
{
if (isDragging)
{
if (ALIGNMENT == HORIZONTAL)
{
try
{
panel1.setWidth(panel1.getOffsetWidth()+ (StartX + x)+"px");
}
catch(Exception e){}
}
else if (ALIGNMENT == VERTICAL)
{
try
{
panel1.setHeight(panel1.getOffsetHeight()+ (StartY + y)+"px");
}
catch(Exception e){}
}
}
}

public void onMouseUp(Widget sender, int x, int y)
{
isDragging = false;
StartX = 0;
StartY = 0;
DOM.releaseCapture(divider.getElement());
}
}

Friday, April 13, 2007

I've been trying to develop a paging widget that will be used according to my needs. Paging is very important as this can organize and more importantly, minimize the amount of the fetch into blocks of 10,15, and so on depending on your situation.

In this sample, there are 3 java classes, PagingListener.java, PagingListenerCollection.java and the Paging Widget itself, pagingWidget.java.

The PagingListener.java is the listener which you need to implement in your application.
The PagingListenerCollection is the helper class that fires the event.

In this implementation, every time you recieve paging events, update the paging widget total number of inquiries by using the method, setTotalPage. This will make sure that the Total number of records will be uptodate everytime theuser clicks on a new page.

here's the code.

PagingListener.java
/*
* PagingListener.java
*
* Created on January 8, 2007, 1:12 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package shells.client.ui.customwidgets;

import com.google.gwt.user.client.ui.Widget;
import java.util.EventListener;

/**
*
* @author mbaricuatro
*/
public interface PagingListener extends EventListener{

/** Creates a new instance of PagingListener */
void onPageClicked(int page);
}

PagingListenerCollection.java

/*
* PagingListenerCollection.java
*
* Created on January 8, 2007, 1:18 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package shells.client.ui.customwidgets;

import java.util.Vector;
import java.util.Iterator;

import shells.client.ui.customwidgets.PagingListener;
/**
*
* @author mbaricuatro
*/
public class PagingListenerCollection extends Vector{

public void firePageClicked(int page)
{
for (Iterator it = iterator(); it.hasNext();)
{
PagingListener listener = (PagingListener) it.next();
listener.onPageClicked(page);
}
}
}

PagingWidget.java

/*
* PagingWidget.java
*
* Created on January 8, 2007, 10:17 AM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package shells.client.ui.customwidgets;

import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.Window;

import shells.client.ui.customwidgets.PagingListenerCollection;
import shells.client.ui.customwidgets.PagingListener;

import shells.client.ui.services.ProductService;

/**
*
* @author mbaricuatro
*/
public class PagingWidget extends HorizontalPanel
{
private int TOTALMESSAGE = -1;
private int CURRENTPAGE = 1;
private int FETCHSIZE = 5;

private Label currentPageNumberHolder = new Label("");
private Label prevPageNumberHolder = new Label("");
private Label nextPageNumberHolder = new Label("");

private Button prev = new Button("<");
private Button next = new Button(">");
private Button first = new Button("<<");
private Button last = new Button(">>");

private PagingListenerCollection pageListener;

/** Creates a new instance of PagingWidget */
public PagingWidget()
{
setStyleName("pagingWidget");
initWidgetsToPanel();
addListeners();
setVisible(false);

currentPageNumberHolder.setStyleName("currentSelectedPage");
}

public PagingWidget(int total, int fetchsize)
{

TOTALMESSAGE = total;
FETCHSIZE = fetchsize;

if (TOTALMESSAGE<=0)
setVisible(false);
else
setVisible(true);

currentPageNumberHolder.setText(""+CURRENTPAGE);
initWidgetsToPanel();
addListeners();

setPages(-1 , CURRENTPAGE , CURRENTPAGE+1);
}

public Button getPrev()
{
return prev;
}
public Button getFirst()
{
return first;
}
public Button getNext()
{
return next;
}
public Button getLast()
{
return last;
}



private void initWidgetsToPanel()
{
add(first);
add(prev);
add(prevPageNumberHolder);
add(currentPageNumberHolder );
add(nextPageNumberHolder);
add(next);
add(last);
}

private void setPages(int first, int current, int next)
{
//punan cgro nig 2 sa next, nya duha pud sa prev...
if (!(first<1))
prevPageNumberHolder.setText(""+first);
else
prevPageNumberHolder.setText(" ");

currentPageNumberHolder.setText(""+current);

int temp = 0;
if (TOTALMESSAGE%FETCHSIZE==0)
temp = 1;
if (!(next>TOTALMESSAGE/FETCHSIZE+1-temp) )
nextPageNumberHolder.setText(""+next);
else
nextPageNumberHolder.setText(" ");
}

private void addListeners()
{
currentPageNumberHolder.addClickListener(new ClickListener()
{
public void onClick(Widget sender)
{
String temp = currentPageNumberHolder.getText();
if (temp.trim().length()!=0)
{
CURRENTPAGE = Integer.parseInt(temp);
pageListener.firePageClicked(Integer.parseInt(temp));
}
}
});
prevPageNumberHolder.addClickListener(new ClickListener()
{
public void onClick(Widget sender)
{
String temp = prevPageNumberHolder.getText();

if (temp.trim().length()!=0)
{
CURRENTPAGE = Integer.parseInt(temp);
pageListener.firePageClicked(Integer.parseInt(temp));
}

}
});
nextPageNumberHolder.addClickListener(new ClickListener()
{
public void onClick(Widget sender)
{
String temp = nextPageNumberHolder.getText();
if (temp.trim().length()!=0)
{
CURRENTPAGE = Integer.parseInt(temp);
pageListener.firePageClicked(Integer.parseInt(temp));
}
}
});

first.addClickListener(new ClickListener()
{
public void onClick(Widget sender)
{
//setPages(-1 , 1 , CURRENTPAGE+1);
CURRENTPAGE = 1;
pageListener.firePageClicked(CURRENTPAGE );
}
});
prev.addClickListener(new ClickListener()
{
public void onClick(Widget sender)
{
if (CURRENTPAGE > 1 )
{
CURRENTPAGE = CURRENTPAGE-1;
pageListener.firePageClicked(CURRENTPAGE );

}
}
});
next.addClickListener(new ClickListener()
{
public void onClick(Widget sender)
{
int temp = 0;
if (TOTALMESSAGE%FETCHSIZE!=0)
temp = 1;
if (CURRENTPAGE < TOTALMESSAGE/FETCHSIZE + temp)
{
CURRENTPAGE = CURRENTPAGE+1;
pageListener.firePageClicked(CURRENTPAGE );
}
}
});
last.addClickListener(new ClickListener()
{
public void onClick(Widget sender)
{
CURRENTPAGE = TOTALMESSAGE/FETCHSIZE+1;

if (TOTALMESSAGE%FETCHSIZE==0)
CURRENTPAGE = CURRENTPAGE -1;

pageListener.firePageClicked(CURRENTPAGE );
}
});
}

public int getTotalPage()
{
return TOTALMESSAGE;
}
public void setTotalPage(int x)
{
TOTALMESSAGE = x;
if (TOTALMESSAGE > FETCHSIZE)
{
setVisible(true);
setPages(CURRENTPAGE-1 , CURRENTPAGE , CURRENTPAGE+1);
}
else
setVisible(false);
}
public int getCurrentPage()
{
return CURRENTPAGE;
}
public void setCurrentPage(int x)
{
CURRENTPAGE = x;
}
public void setFetchSize(int x)
{
FETCHSIZE = x;
}
public int getFetchSize()
{
return FETCHSIZE;
}

public void addPagingListener(PagingListener listener)
{
if (pageListener == null)
pageListener = new PagingListenerCollection();
pageListener.add(listener);
}

public void removePagingListener(PagingListener listener)
{
if (pageListener != null)
pageListener.remove(listener);
}
}




Wednesday, December 13, 2006

Here's a good source for the basics of Google Web Toolkit. see here

In this article, he discusses the basics and Also touches on JSNI and tips on server-side implementations...
He also touches on the script.aculo.us jscrip library...

The script.aculo.us is a great way to add interactivity to your site and
enhances the users experience through effects.

For more info, visit the script.aculo.us home page and see online demonstration...

There is also a sources that wraps the script.aculo.us and makes it easy to integrate
in GWT... See the GWT Component library.

Other custom widgets are also found here like the calendar widget and the auto-completion Widget.

Monday, December 11, 2006

Here's a little custom widget that is very easy to code and to implement...
A custom button with different states, Mouseh hover, Mouse down and Mouse out...

You can set different stylenames to and assign other background images to distiguish one state
from the other... here's the code... :)

MyButton.java

package MyPackage.customwidgets;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Button;

public class MyButton extends Button {
String styleName = new String();
public MyButton(String style) {
styleName = style;
}
public MyButton(String style, String label) {
setText(label);
styleName = style;
}
public void onLoad() {
setStyleName(styleName + "Normal");
sinkEvents(Event.ONCLICK | Event.MOUSEEVENTS);
}
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
switch(DOM.eventGetType(event)) {
case Event.ONMOUSEDOWN:
super.setStyleName(styleName + "Down");
break;
case Event.ONMOUSEUP:
super.setStyleName(styleName + "Hover");
break;
case Event.ONMOUSEOVER:
super.setStyleName(styleName + "Hover");
break;
case Event.ONMOUSEOUT:
super.setStyleName(styleName + "Normal");
break;
}
}
}

just add the following css to your project...

.[YOURBUTTONSTYLENAME]Hover{}
.[YOURBUTTONSTYLENAME]Down{}
.[YOURBUTTONSTYLENAME]Normal{}

[YOURBUTTON STYLENAME] REFERS TO THE SPECIFIC STYLENAME OF YOUR BUTTONS. JUST PUT THE 3 KEY WORDS AFTER WITH NO WHITE SPACE IN BETWEEN...

To create a new MyButton class, simply:

MyButton myButton = new MyButton("[YOURBUTTONSTYLENAME]", "Button TEXT");

This is a just basic code demonstrating the use of DOM and event handlers
Other eventhandlers are available... just visit the GWT documentation or the GWT forums :)

Saturday, December 9, 2006

GWT sample code... customizing widgets...

Here is an example, A flexTable or a Grid which now includes double clicks, mulitple select and right click events...

There are four classes, for FlexTable, Grid, TableListener collection, and Table listener interface...
We need to extend all this classes and overridde some methods...

Here's what i've come up so far...

GridWithDoubleClick.java

import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;

import java.util.ArrayList;

public class GridWithDoubleClick extends Grid {
private TableListenerCollectionWithDoubleClick tableListeners;
private boolean isShiftKeyDown = false;
private ArrayList selectedRows = new ArrayList();

public GridWithDoubleClick() {
super();
disableContextMenu(getElement());
setselectedhighlight(getElement());
sinkEvents(Event.ONMOUSEUP| Event.ONDBLCLICK | Event.BUTTON_RIGHT | Event.ONKEYDOWN | Event.ONKEYUP );
}

public void onBrowserEvent(Event event) {
// Find out which cell was actually clicked.
Element td = getEventTargetCell(event);
if (td == null) {
return;
}
Element tr = DOM.getParent(td);
Element body = DOM.getParent(tr);
int row = DOM.getChildIndex(body, tr);
int column = DOM.getChildIndex(tr, td);
switch (DOM.eventGetType(event)) {
case Event.ONMOUSEUP: {
switch(DOM.eventGetButton(event)){
case Event.BUTTON_LEFT:
if (this.tableListeners != null)
{
// Fire the event.
if (DOM.eventGetShiftKey(event))
{
selectedRows.add(new String().valueOf(row));
tableListeners.fireMultipleCellClicked(this, row, column);
}
else
{
tableListeners.fireCellClicked(this, row, column);
selectedRows = null;
selectedRows = new ArrayList();
}
}

break;

case Event.BUTTON_RIGHT:
if (this.tableListeners != null)
{
// Fire the event.
tableListeners.fireRightClicked(this, row, column, DOM.eventGetClientX(event), DOM.eventGetClientY(event));
//tableListeners.fireRightClicked(this, row, column);
}
break;
default:{
//do nothing
}
break;
}
break;
}
case Event.ONDBLCLICK: {
if (this.tableListeners != null && !DOM.eventGetShiftKey(event)) {
// Fire the event.
tableListeners.fireCellDblClicked(this, row, column);

}
break;
}

default: {
// Do nothing
}
break;
}
}

public ArrayList getSelectedRows()
{
return selectedRows;
}

//overide this methods pra maka fire sa atong ghimo na interface ug listener collections
public void addTableListener(TableListenerWithDoubleClick listener) {
if (tableListeners == null) {
tableListeners = new TableListenerCollectionWithDoubleClick();
}
tableListeners.add(listener);
}
public void removeTableListener(TableListenerWithDoubleClick listener)
{
if (tableListeners != null)
{
tableListeners.remove(listener);
}
}

private native void disableContextMenu(Element elem) /*-{
elem.oncontextmenu=function(a,b) {return false};
}-*/;

private native void setselectedhighlight(Element elem ) /*-{
elem.onselectstart=function(a,b) {return false};


}-*/;
}


Do the same for flexTable... you can also sink other events that you like and just add the condition in the switch...

In the code, we override the onbrowser event and sink the events needed.

TableListenerCollectionWithDoubleClick.java


import com.google.gwt.user.client.ui.SourcesTableEvents;
import java.util.Vector;
import java.util.Iterator;

public class TableListenerCollectionWithDoubleClick extends Vector {

public void fireCellClicked(SourcesTableEvents sender, int row, int cell) {
for (Iterator it = iterator(); it.hasNext();) {
TableListenerWithDoubleClick listener = (TableListenerWithDoubleClick) it.next();
listener.onCellClicked(sender, row, cell);
}
}

public void fireCellDblClicked(SourcesTableEvents sender, int row, int cell) {
for (Iterator it = iterator(); it.hasNext();) {
TableListenerWithDoubleClick listener = (TableListenerWithDoubleClick) it.next();
listener.onCellDblClicked(sender, row, cell);
}
}

public void fireMultipleCellClicked(SourcesTableEvents sender, int row, int cell) {
for (Iterator it = iterator(); it.hasNext();) {
TableListenerWithDoubleClick listener = (TableListenerWithDoubleClick) it.next();
listener.onMultipleCellClicked(sender, row, cell);
}
}
public void fireRightClicked(SourcesTableEvents sender, int row, int cell, int mouseX, int mouseY) {
for (Iterator it = iterator(); it.hasNext();) {
TableListenerWithDoubleClick listener = (TableListenerWithDoubleClick) it.next();
listener.onCellRightClicked(sender, row, cell, mouseX, mouseY);
}
}/*
public void fireRightClicked(SourcesTableEvents sender, int row, int cell) {
for (Iterator it = iterator(); it.hasNext();) {
TableListenerWithDoubleClick listener = (TableListenerWithDoubleClick) it.next();
listener.onCellRightClicked(sender, row, cell);
}
}*/
}


As you can see above, i've added fireRightClicked and . These are the methods that fire the onCellRightClicked and onMultipleCellClicked in the new TableListenerWithDoubleClick interface.

Here's the code for TableListenerWithDoubleClick interface

TableListenerWithDoubleClick.java

import com.google.gwt.user.client.ui.TableListener;
import com.google.gwt.user.client.ui.SourcesTableEvents;

public interface TableListenerWithDoubleClick extends TableListener{

public void onCellClicked(SourcesTableEvents sender, int row, int cell);
public void onCellDblClicked(SourcesTableEvents sender, int row, int cell);
public void onMultipleCellClicked(SourcesTableEvents sender, int row, int cell);
public void onCellRightClicked(SourcesTableEvents sender, int row, int cell, int mouseX, int mouseY);
//public void onCellRightClicked(SourcesTableEvents sender, int row, int cell);
}

These works the same way as the currently included implementation...
Just include all the include all the files in you class (you can name them to anything you want).
Sample:

import MyPackage.GridWithDoubleClick
import MyPackage.FlexTableWithDoubleClick
import MyPackage.TableListenerWithDoubleClick

GridWithDoubleClick mygrid = new GridWithDoubleClick();

myGrid.addTableListener(new TableListenerWithDoubleClick()
{
//implement all the methods in the tableListener with click methods...
});


this works with the latest version of GWT.



Thursday, December 7, 2006

Ajax programming using GWT.

GWT - google web toolkit basically lets you code Ajax capable web applications. GWT is basically a front end, serving as the User Interface for web Application. It can easily be integrated with servlets as backend. The remote proceedure call (RPC) included in the toolkit is also quite easy to use.

As compared to other offerings like dojo and QooxDoo, GWT is written in JAVA. This means a web developer may not know a thing about javascript and still be able to code AJAX applications. This is also convenient as servlets are also written in JAVA.


To start, download the latest Java SDK here.

You will also need Java capable IDE. You may use either Eclipse or Net beans.
If you use netbeans, you will also need this plugin. (this also containes a good tutorial on GWT)

Then download the latest GWT available here. In this writting, 1.2 is the latest released version.

Install all components then you are all set to write your first GWT application.

Wednesday, December 6, 2006

1st

The first steps are always the hardest