Many years ago I wrote javascript application that took an image, broke it up into many pieces, then shuffled them into a puzzle for the user. It only worked in I.E. and was horribly written and hard to maintain.
I wanted to revisit this application and was trying to figure out what the best language/framework to use.
I decided that GWT (Google Web Toolkit) would be an excellent choice for this application.
To see the application go here: http://imageoverflow.appspot.com/puzzle.html?imageUrl=http://imageoverflow.appspot.com/get/3b20793dfc300d058ad04d411da152eb?f=t
Now to the code...
The code consists of the following main classes.
ImagePuzzleWidget
PuzzleGrid
ClickableImage
ImagePuzzleWidget
The ImagePuzzleWidget is the main widget that encapsulates the game. It takes no arguments and is added directly to the Root Panel in the GWT entry point.
public void onModuleLoad() {
RootPanel.get().add(new ImagePuzzleWidget());
}
PuzzleGrid
PuzzleGrid extends the Grid GWT component. Its constructor looks like this:
public PuzzleGrid(final String url,final int cols,final int rows)
This class takes the url of the image you want to scramble as well as how many rows and cols you want.
We add an onLoadHandler that will get executed after the image has been loaded:
image.addLoadHandler(new LoadHandler() {
public void onLoad(LoadEvent event) {
setWidth(image.getWidth() + "px");
setHeight(image.getHeight() + "px");
int blockWidth = image.getWidth() / cols;
int blockHeight = image.getHeight() / rows;
for (int col = 0; col <>
for (int row = 0; row <>
setWidget(row, col,
new ClickableImage(url, blockWidth * col, blockHeight * row, blockWidth, blockHeight, row, col));
}
}
shuffle();
setVisible(true);
}
});
It is this class that does most of the work by splitting the image into sub parts and making ClickableImages out of them.
The class then shuffles the images and sets it as visible.
So now we have an image displayed broken into sub parts and displayed in a grid fashion.
ClickableImage
ClickableImage class, as its name implies embodies a section of the image that can be clicked.
The class basically just extends Image and adds a ClickHandler. I add some extra convenience methods like select and unselect which I won't show for the sake of brevity.
public ClickableImage(String url, int left, int top, int width, int height, int row, int col) {
super(url, left, top, width, height);
this.row = row;
this.col = col;
this.addStyleName("unselected");
this.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
toggleSelected();
}
});
}
And that is really all there is to it. By using GWT we can focus on writing our OO style code and not worry about the browser.
Make sure you check out the app at: http://imageoverflow.appspot.com/puzzle.html?imageUrl=http://imageoverflow.appspot.com/get/3b20793dfc300d058ad04d411da152eb?f=t
This post was written hastily, if there is any interest or question leave a comment and I'll ake the time to expand.
HTH
Monday, February 8, 2010
Monday, October 5, 2009
Extend JSF Command Link
I found myself adding a Remove link throughout my JSF application. It looked like this:
<h:commandlink value="Remove" actionlistener="#{MyBean.remove}">
I wanted to add a confirm dialog. So I added this.
<h:commandlink value="Remove" actionlistener="#{MyBean.remove}" onclick="javascript return confirm('Are you sure')">
But as I copied and pasted this through 5 or 6 different pages, I got to thinking, there has to be a better way.
So I created a custom jsf component by extending Command Link.
Step 1
First step was to create my new tag. It simply wraps the default command link.
package com.acme;
import com.sun.faces.taglib.html_basic.CommandLinkTag;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlCommandLink;
import javax.faces.event.MethodExpressionActionListener;
import javax.faces.webapp.UIComponentELTag;
/**
* @author cmcintosh
*/
public class RemoveCommandLinkTag extends UIComponentELTag { // Declare a bean property for the hellomsg attribute.
CommandLinkTag commandLink = new CommandLinkTag();
ValueExpression value;
MethodExpression actionListener;
// Associate the renderer and component type.
public String getComponentType() {
return commandLink.getComponentType();
}
public String getRendererType() {
return commandLink.getRendererType();
}
@Override
protected void setProperties(UIComponent component) {
super.setProperties(component);
component.setValueExpression("value", value);
((HtmlCommandLink)component).addActionListener(new MethodExpressionActionListener(actionListener));
((HtmlCommandLink)component).setOnclick("javascript:return confirm('Are you sure you want to remove?')");
}
@Override
public void release() {
super.release();
commandLink.release();
}
public void setValue(ValueExpression value) {
this.value = value;
}
public void setActionListener(MethodExpression actionListener) {
this.actionListener = actionListener;
}
}
Step 2
Next I needed to create a tld.
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" xsi="http://www.w3.org/2001/XMLSchema-instance" schemalocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>datastore</short-name>
<uri>/WEB-INF/tlds/datastore</uri>
<tag>
<name>RemoveCommandLink</name>
<tag-class>com.acme.datastore.web.components.tags.RemoveCommandLinkTag</tag-class>
<attribute>
<name>value</name>
<deferred-value>
<type>java.lang.String</type>
</deferred-value>
</attribute>
<attribute>
<name>actionListener</name>
<required>false</required>
<deferred-method>
<method-signature>
actionListener(javax.faces.event.ActionEvent)
</method-signature>
</deferred-method>
<type>String</type>
</attribute>
</tag>
</taglib>
This was one of the hardest parts note the deferred-method and deferredvalue. I've never encountered those before.
Step 3
Add it to the web.xml:
<jsp-config>
<taglib>
<taglib-uri>http://datastore.acme.com/datastore</taglib-uri>
<taglib-location>/WEB-INF/tlds/datastore.tld</taglib-location>
</taglib>
</jsp-config>
Step 4
Finally to use it:
<%@taglib prefix="ds" uri="http://datastore.acme.com/datastore"%>
.
.
.
<ds:removecommandlink value="Remove" actionlistener="#{ViewModifyTable.removeColumn}">
<f:param name="applicationId" value="#{ViewModifyTable.applicationId}">
<f:param name="tableName" value="#{ViewModifyTable.tableName}">
</f:param></f:param></ds:removecommandlink></h:commandlink></h:commandlink>
<h:commandlink value="Remove" actionlistener="#{MyBean.remove}">
I wanted to add a confirm dialog. So I added this.
<h:commandlink value="Remove" actionlistener="#{MyBean.remove}" onclick="javascript return confirm('Are you sure')">
But as I copied and pasted this through 5 or 6 different pages, I got to thinking, there has to be a better way.
So I created a custom jsf component by extending Command Link.
Step 1
First step was to create my new tag. It simply wraps the default command link.
package com.acme;
import com.sun.faces.taglib.html_basic.CommandLinkTag;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlCommandLink;
import javax.faces.event.MethodExpressionActionListener;
import javax.faces.webapp.UIComponentELTag;
/**
* @author cmcintosh
*/
public class RemoveCommandLinkTag extends UIComponentELTag { // Declare a bean property for the hellomsg attribute.
CommandLinkTag commandLink = new CommandLinkTag();
ValueExpression value;
MethodExpression actionListener;
// Associate the renderer and component type.
public String getComponentType() {
return commandLink.getComponentType();
}
public String getRendererType() {
return commandLink.getRendererType();
}
@Override
protected void setProperties(UIComponent component) {
super.setProperties(component);
component.setValueExpression("value", value);
((HtmlCommandLink)component).addActionListener(new MethodExpressionActionListener(actionListener));
((HtmlCommandLink)component).setOnclick("javascript:return confirm('Are you sure you want to remove?')");
}
@Override
public void release() {
super.release();
commandLink.release();
}
public void setValue(ValueExpression value) {
this.value = value;
}
public void setActionListener(MethodExpression actionListener) {
this.actionListener = actionListener;
}
}
Step 2
Next I needed to create a tld.
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" xsi="http://www.w3.org/2001/XMLSchema-instance" schemalocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>datastore</short-name>
<uri>/WEB-INF/tlds/datastore</uri>
<tag>
<name>RemoveCommandLink</name>
<tag-class>com.acme.datastore.web.components.tags.RemoveCommandLinkTag</tag-class>
<attribute>
<name>value</name>
<deferred-value>
<type>java.lang.String</type>
</deferred-value>
</attribute>
<attribute>
<name>actionListener</name>
<required>false</required>
<deferred-method>
<method-signature>
actionListener(javax.faces.event.ActionEvent)
</method-signature>
</deferred-method>
<type>String</type>
</attribute>
</tag>
</taglib>
This was one of the hardest parts note the deferred-method and deferredvalue. I've never encountered those before.
Step 3
Add it to the web.xml:
<jsp-config>
<taglib>
<taglib-uri>http://datastore.acme.com/datastore</taglib-uri>
<taglib-location>/WEB-INF/tlds/datastore.tld</taglib-location>
</taglib>
</jsp-config>
Step 4
Finally to use it:
<%@taglib prefix="ds" uri="http://datastore.acme.com/datastore"%>
.
.
.
<ds:removecommandlink value="Remove" actionlistener="#{ViewModifyTable.removeColumn}">
<f:param name="applicationId" value="#{ViewModifyTable.applicationId}">
<f:param name="tableName" value="#{ViewModifyTable.tableName}">
</f:param></f:param></ds:removecommandlink></h:commandlink></h:commandlink>
Friday, September 18, 2009
Configure logging level
Here is how I disabled hibernate JPA logging level in code.
Logger.getLogger("org.hibernate").setLevel(Level.SEVERE);
Logger.getLogger("org.hibernate").setLevel(Level.SEVERE);
Tuesday, August 18, 2009
Readling List
XtraDb:
http://www.mysqlperformanceblog.com/2009/08/13/xtradb-the-top-10-enhancements/
Mysql performance blog
http://www.amazon.com/gp/product/0596101716?ie=UTF8&tag=perinc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0596101716
http://www.mysqlperformanceblog.com/2009/08/13/xtradb-the-top-10-enhancements/
Mysql performance blog
http://www.amazon.com/gp/product/0596101716?ie=UTF8&tag=perinc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0596101716
Monday, August 17, 2009
Pro JSF and Ajax by Jonas Jacobi and John R. Fallows
Read On: 8/17/09
Rating: 7 /10
Pros:
Rating: 7 /10
Pros:
- I liked this summary of other applications and which component of MVC they target: Examples of frameworks are Struts (an open source controller framework);
TopLink and Hibernate (model frameworks); and Tiles, Tapestry, XUL, and ADF UIX (so-
called view frameworks).
- Can be hard to read
- Why do so many frameworks model navigation these days?
Comparing Web Frameworks: Struts, Spring MVC, Webwork, Tapestry & JSF
Read on: 08/17/2009
Rating: 2/10
Way outdated, by the time I got my hands on it. No fault of the authors it was made in 2005.
Pros:
Rating: 2/10
Way outdated, by the time I got my hands on it. No fault of the authors it was made in 2005.
Pros:
- Concise
- Its just a bunch of slides
Subscribe to:
Posts (Atom)