Friday, August 13, 2010

A few examples of using svg2canvas

The canvas items on this page were created as SVG files, and then converted to javascript using my online service, svg2canvas.
This first one is just something I whipped up quick, using Inkscape. The text "Pow!" was converted to a path.
Next, I have a ladybug that I downloaded from www.openclipart.org, drawn by someone named "/ lemmling". You can see the original SVG here: Original SVG
Finally, I have a gauge that I drew up. This gauge is animated, which required a bit of coding, to animate only the needle.

Tuesday, August 10, 2010

HTML5 Canvas Editing

I have been experimenting for a while now with the HTML5 canvas element.
I have encountered a few drawbacks while doing so.
  • The first drawback is that there is no ellipse support!  You can draw a circle, or a circle segment / arc.  But you will have to use cubic bezier curves if you want to draw an ellipse.
  • Ever try to edit a bezier curve by hand? Ouch.
  • And finally, there isn't really any editor support out there yet.
With that in mind, let me present my solution, for all you HTML5 canvas developers:  svg2canvas.
I wrote up a bare-bones converter applet, that will accept a small svg file, and attempt to convert it to a javascript file using canvas.
As noted in the webapp, there is nowhere near full SVG support.  Text is not even supported yet!  However, you can always convert text to a path.


Here it is:
http://www.antennamap.com/svg2canvas
Note: This is currently broken.  If anyone is interested in trying it out, let me know and I'll get it working somewhere else.

Instructions:
  • Download and install Inkscape
  • Draw up a nice SVG graphic
  • Upload it to svg2canvas
  • Preview and download javascript!
  • Maybe think about posting a comment!
I make no guarantee that your SVG file will work.  Here's hoping!

Wednesday, June 30, 2010

Experimenting with HTML Canvas

I am starting to get interested in using the HTML canvas element with GWT.
I have downloaded the gwt-canvas project, which provides a very nice API wrapper.  The first thing I did was extend it to add text support.  Okay, I only added text support for browsers that support it.

Anyway, that brings me to my first pain point.  Experimenting with canvas in GWT is extremely time consuming, as you must recompile to JavaScript every time you make a change.  (Canvas is not supported in hosted mode, AFAIK!)

However, there is an extremely easy way to experiment with the canvas:
  • Get firefox, and the firebug addon.
  • Save the following text to the file canvas.html :

<html>
<body>
<canvas id="canvas" width="300" height="200" style="border: 1px solid black;">Time to upgrade!</canvas>
</body>
</html>

  • In Firefox, select "File/Open File", and open the file you just saved.
  • You should see the following:


  • Open firebug (in the bottom right corner), and select the Console tab
  • You are now ready to experiment!  Just type your javascript into the console command prompt, ">>>".
  • For example, you might go to the Mozilla Drawing Graphics with Canvas tutorial, and copy those commands, one line at a time, into the command prompt:

There you have it! A command line interface for experimenting with canvas, with things you probably had lying around the home!

Wednesday, June 2, 2010

Deleting duplicate SQL rows

I know this is not really GWT related, but I ran into a problem with one of my database tables, where I somehow managed to get duplicate rows.

I don't know how it happened, but to prevent it happening again, I wanted to add a unique constraint on the 'username' column.

Before I could do that, however, I had to delete the duplicate entries.

I searched around using Google, and found a few solutions that seemed complicated, and not quite what I wanted. They seemed to involve copying data to another table, deleting dupes, deleting the original table rows, and then copying it back.

So, here is what I think is an easier way to do it, that is a bit more flexible:

  • Find the rows you want to keep
  • Delete the other rows.

Selecting the good rows

My table in question is 'usersettings'. It has 9 columns, but all I care about are the first two, 'id', and 'username'.

To find the rows I want to keep, I am going to select the lowest id per username. To do this, I used aggregation, with the group by clause, and the 'min' operator.


select min(id) as id from usersettings group by username;

This returns the lowest id for all unique usernames. These are the rows I want to keep.
This could easily be modified to take the highest id, using max.
I am sure there are lots of other ways to implement the criteria to select the ids that you want to keep.

We can dump this result set into a temporary table, or even just use it as a subquery expression.
To maximize database compatibility, I will just use a subquery.


Deleting the bad rows

Okay, first we will just 'select' the rows to be deleted, to make sure we are deleting the proper rows:
select * from usersettings where id not in (select min(id) as id from usersettings group by username);


Sure enough, this returns a result set containing the duplicate rows that have higher ids.

So, now that we know we are selecting the correct data, I can go ahead and delete it:
delete from usersettings where id not in (select min(id) as id from usersettings group by username);

Using a temp table

If you want to use a temporary table instead, with postgres you could do the following:

select min(id) as id into temp table goodids from usersettings group by username;
delete from usersettings where id not in (select * from goodids);


As always, you should really back up your database before deleting stuff!!!

Now that my usersettings.username only contains unique data, I am able to apply the unique constraint to it.

Monday, March 29, 2010

Walkthrough: Integrating GWT with JBoss 5.1.0 & EJB3

This tutorial describes steps to easily create a JavaEE enterprise application, using the following components:

  • Google Web Toolkit (version 1.7 or 2.0)
  • Eclipse Ganymede or Galileo, Java EE version
  • GWT Eclipse Plugin
  • JBoss AS 5.1.0.GA
  • JBoss Tools plugin
Hint: Anything that is a user action will be in green.

Getting Started


If you haven’t already done so, you need to download all of those components. See ‘links’ at the end of this document for help. This tutorial requires the JavaEE version of Eclipse.

  • Unpack the JBoss distribution to wherever you would like.
  • Unpack/Install Eclipse, and start it up
  • Install the GWT Plugin for Eclipse, using the link provided for instructions
  • Install the JBoss Tools plugin for Eclipse, using the link provided.
Once you have all those components downloaded and installed, create a new empty workspace in Eclipse, and close the welcome screen.

1. Create the Server Environment


In eclipse, Open Window/Preferences and select Server/Runtime Environments
Click Add.


Select JBoss Community/JBoss 5.1 Runtime, and click Next.
(You won’t see this option unless you have installed the JBoss Tools Eclipse Plugin.)



Click Browse to configure the JBoss Home Directory. (This is wherever you unpacked it in Getting Started)
Select a server configuration; ‘default’ is fine for now.

Click Finish
Click OK to close the preferences.

2. Create an Enterprise Application Project


Select File/New/Enterprise Application Project
Enter the project name (I chose ‘tutorial_ear’ for this example.)



Click Finish

This just created an Enterprise Application aRchive Project, which will be used to jar up all the other components for easy deployment.

3. Create an EJB Project



Select File/New/EJB Project
Enter the project name (I chose tut_ejb here)
Check the Add project to an EAR setting



Click Next
Click Next again
At this point, you can choose if you want to have an EJB Client Jar or not. I left this checked, just 'cuz it's the default.

4. Create an EJB


Right click the EJB project, and select New/Session Bean(EJB3.x)
Set the Java Package and the Class name.
For this tutorial, we will only create a local interface.



Click Finish

In the ejbClient project, open the corresponding bean interface (SampleBeanLocal), and add a method. In this case, I added a method called getEJBHello(String name).



Save the file.

Go to the implementation (SampleBean.java), and implement the method:



Save the file.

5. Create the GWT Project

Click on the Google New Web Application Project icon in the toolbar
Set the project name, the package, and then configure the SDK.
Uncheck Use Google App Engine, as we’re using JBoss instead.



Click Finish.
At this point, your workspace configuration should look like this.



If you did not select the ejbClient project, then of course that project will not be here.

5.1 Modify the GWT project

Some things need to be done to the GWT project right off, before doing anything else.

5.1.1 Add Facets to the project

Open the Navigator view (Window/Show View/Navigator), open the gwt project, and double-click the .project file to open it.
Find the natures list, and add the following three items to it:

<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>


(The result is it should look like this:)


Close the .project file
Close the gwt project, by right-clicking it, and selecting Close Project.
Reopen it, by right-clicking and select Open Project.
(This will cause eclipse to accept the new natures.)

5.1.2 Configure Project Facets

Right click the project, and select Properties.
Select Project Facets.
Enable Java
Enable Dynamic Web Module



BEFORE DOING ANYTHING ELSE, Click on Further configuration available...
Click Next to get to the Web Module configuration
Change the Content directory value to “war” so it aligns with the GWT generated project.



Click OK to close the Further Configuration
Click OK to close the project facets

Note: If you click OK before changing the Content directory, eclipse will irreversibly set the content directory; you cannot click "further configuration" and change it later. (Although, you can edit its .project file!)

5.1.3 Update the web.xml

In order for EJB injection to work, we need to update the web.xml web-app version from 2.3 to 2.5.
Find the gwt app’s web.xml, and open it.
Replace the header (including the web-app node), with the folllowing:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">


Save it.
If you plan on using JNDI lookups, and not injection, then you can skip this step. For example, if you need to use Stateful beans, then you probably don’t want to use injection. (See dev tips at the end.)

5.2 Add the GWT project to the EAR

Right click the EAR project, and select Properties.
Select Java EE Module Dependecies, and check the GWT project.



Click OK

6. Call the EJB!

Open the GreetingServiceImpl class using the greatest Eclipse tool of all time: Open Type.
Click the Open Type toolbar button, or type Shift-Ctrl-T. (I like this shortcut so much, I am thinking of mapping it to the spacebar!)
Inject the EJB. In this case, my bean interface is called SampleBeanLocal.
So, to inject it, I add the code:

@EJB
SampleBeanLocal sampleBean;




At this point, the project needs to have it’s build path updated...
Hover over the red squigglies on SampleBeanLocal, and select Fix Project Setup.
That should take care of that.

Modify the GWT server code to use the EJB:



7. Compile the GWT application

Click the GWT Compiler icon, and compile your app.
Refresh the ‘war’ folder on your GWT application, so eclipse will see the changes. You can do this by right-clicking the project, and selecting refresh.

We’re almost done!!!

8. Configure the JBoss Server

Click on the Servers tab near the bottom. If you don’t see it, you can select Window/Show View/Servers.
Right click in the servers view, and select New/Server
Select JBoss AS 5.1



Click Finish
This depends on Step 1, Configuring the JBoss Runtime Environment. If you did not complete that step, then you can click on Configure runtime environments here, to set things up now.

Right click the new server, and select Add and Remove.



Add the EAR to the Configured side, and click Finished

9. Start the server!

Right-click the server, and select either Start or Debug. Debug will let you set breakpoints in your server-side code.

After a while, in the console, you should hopefully see that your apps have deployed:

12:34:26,195 INFO [EJBContainer] STARTED EJB: org.example.tutorial.ejb.SampleBean ejbName: SampleBean

12:34:26,215 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

tutorial_ear/SampleBean/local - EJB3.x Default Local Business Interface
tutorial_ear/SampleBean/local-org.example.tutorial.ejb.SampleBeanLocal - EJB3.x Local Business Interface

12:34:26,292 INFO [TomcatDeployment] deploy, ctxPath=/tut_gwtapp

12:34:26,119 INFO [JBossASKernel] Added bean(jboss.j2ee:ear=tutorial_ear.ear,jar=tut_ejb.jar,name=SampleBean,service=EJB3) to KernelDeployment of: tut_ejb.jar

12:34:26,122 INFO [EJB3EndpointDeployer] Deploy AbstractBeanMetaData@1a98d7b{name=jboss.j2ee:ear=tutorial_ear.ear,jar=tut_ejb.jar,name=SampleBean,service=EJB3_endpoint bean=org.jboss.ejb3.endpoint.deployers.impl.EndpointImpl properties=[container] constructor=null autowireCandidate=true}

12:34:26,194 INFO [SessionSpecContainer] Starting


Once it is started, you can open your browser and go to:
http://localhost:8080/tut_gwtapp
and you should see your GWT application come up!




(Note there is a missing space after the Hello. Ooops. That's a bug in the SessionBean.)


10. Source code


You can download the source files from Here. Note that I deleted the gwt-user.jar from the tut_gwtapp to reduce the size. Namely, that is file tut_gwtapp/war/WEB-INF/lib/gwt-user.jar. It is part of the standard GWT distibution.


11. Conclusion

Using these awesome, powerful tools, you can integrate these components easily, to quicky build enterprise applications.

  • Why would I want to use EJBs?
EJB3 comes with some very powerful features! I will let you know as soon as I think of any. Okay, here’s one: Many existing EA code bases are already using EJBs as their primary way of doing business logic, and they are well understood by Java architects.

Something to watch out for, however, is that a Stateful EJB session bean may not be what you think it is. You might consider using @EJB to inject a stateful bean into your servlet code. This will likely lead to problems, however, as this bean is in no way tied to the web session, and so every call to your servlet will get a new bean.
Instead, when you need a stateful bean, you will need to look up the bean as per normal, and then cache it somewhere, eg., in the http session.

One downside to using Session Beans from your code is that you can't call them directly from the client code. You must make normal GWT RPC calls, and in the server code, make the call to the EJB... Haven’t figured out a way around that yet, and I don't think there is one.

12. Dev Cycle Tips

  • GWT compilation
The GWT compiler writes to the war folder. After compiling, you need to refresh that folder, so that Eclipse knows about the changes, and will redeploy the resources.

  • JBoss Startup time
It takes a long time to start and stop JBoss. So, don’t do that!
Start the server once.
If you are running in debug mode, you typically only need to refresh your war directory, and your changes will be deployed immediately, for client code.
For server code changes, you typically only need to save the file, and it will be deployed immediately, while in debug mode.
If your server changes do require a restart, don’t restart JBoss, but rather, undeploy and then redeploy the EAR. This is lots faster.

  • Export
Once you are happy with your EAR project, you can export it using File/Export...

13. Links