Thursday, June 05, 2008

GraphicsBuilder Experimentation

This afternoon I was experimenting with GraphicsBuilder on Groovy, and I'm blown away. Andres has done an amazing job with GraphicsBuilder.

It took a bit of work to get setup because I wanted to play around with the SVG rendering support (which isn't included in the 0.5.1 package that is currently available). Once I built from the trunk, it worked like a charm. Below are the steps that I went through to set things up in case it is useful to anyone else.

1) Java 6
Make sure you have Java 6 installed for your platform. I'm on a Mac which doesn't have Java 6 support (grr...) so I went the SoyLatte route.

2) Groovy 1.5
Make sure you have Groovy installed. I ran into troubles when I tried to use the 1.6 snapshot (ClassCastExceptions) so stick with 1.5 for now.

3) Maven 2
We'll be building GraphicsBuilder from the Subversion trunk, so we need to install Maven 2.

4) Subversion
Hopefully you already have the Subversion, but if not, grab and install it for you platform.

1) Setting up some environment variables at the commandline

export GROOVY_HOME=~/Source/groovy
export JAVA_HOME=/usr/local/java1.6
export PATH=$JAVA_HOME/bin:$GROOVY_HOME/bin:~/Source/maven/bin:$PATH

Obviously your paths will differ. Once this is done, we should be able to run our java, groovy, and mvn commands without errors.

2) Download GraphicsBuilder from Subversion

svn co graphicsbuilder

3) Download the Batik 1.7 distribution
Download a copy of the Batik 1.7 distribution and unzip it into our graphicsbuilder directory.

4) Use Maven to build GraphicsBuilder

cd graphicsbuilder

If everything works for you, then proceed to the next step. For me, I ran into two problems. The first problem was that top level pom.xml referenced groovy-all-minimal as a dependency but the other pom.xml files referenced groovy-all as a dependency. This caused Maven to complain about a missing version and to fail. I fixed this by changing the top level pom.xml file to reference groovy-all:

--- pom.xml (revision 356)
+++ pom.xml (working copy)
@@ -77,7 +77,7 @@

- groovy-all-minimal
+ groovy-all

This seemed to clear up Maven's problems and the build actually proceeded.

The other problem I ran into was that the Batik 1.7 jars weren't available in the Maven repositories so the build complained of missing dependencies. Fortunately Maven will allow us to install the required jars locally:

mvn install:install-file -DgroupId=batik -DartifactId=batik-awt-util -Dversion=1.7 -Dpackaging=jar -Dfile=batik-1.7/lib/batik-awt-util.jar
mvn install:install-file -DgroupId=batik -DartifactId=batik-util -Dversion=1.7 -Dpackaging=jar -Dfile=batik-1.7/lib/batik-util.jar
mvn install:install-file -DgroupId=batik -DartifactId=batik-gui-util -Dversion=1.7 -Dpackaging=jar -Dfile=batik-1.7/lib/batik-gui-util.jar
mvn install:install-file -DgroupId=batik -DartifactId=batik-ext -Dversion=1.7 -Dpackaging=jar -Dfile=batik-1.7/lib/batik-ext.jar
mvn install:install-file -DgroupId=batik -DartifactId=batik-svggen -Dversion=1.7 -Dpackaging=jar -Dfile=batik-1.7/lib/batik-svggen.jar
mvn install:install-file -DgroupId=batik -DartifactId=batik-dom -Dversion=1.7 -Dpackaging=jar -Dfile=batik-1.7/lib/batik-dom.jar
mvn install:install-file -DgroupId=batik -DartifactId=batik-svg-dom -Dversion=1.7 -Dpackaging=jar -Dfile=batik-1.7/lib/batik-svg-dom.jar
mvn install:install-file -DgroupId=batik -DartifactId=batik-parser -Dversion=1.7 -Dpackaging=jar -Dfile=batik-1.7/lib/batik-parser.jar
mvn install:install-file -DgroupId=batik -DartifactId=batik-xml -Dversion=1.7 -Dpackaging=jar -Dfile=batik-1.7/lib/batik-xml.jar
mvn install:install-file -DgroupId=batik -DartifactId=batik-gvt -Dversion=1.7 -Dpackaging=jar -Dfile=batik-1.7/lib/batik-gvt.jar

After that, I was able to kick off mvn and build everything.

5) Install GraphicsBuilder into GROOVY_HOME
If you want to play around with GraphicsBuilder from the commandline, the easiest thing to do is to install it in your GROOVY_HOME:

cp */lib/*.jar $GROOVY_HOME/lib/
cp */target/*.jar $GROOVY_HOME/lib/
cp */src/lib/*.jar $GROOVY_HOME/lib/
cp */src/bin/* $GROOVY_HOME/bin/
chmod +x $GROOVY_HOME/bin/graphicsPad
chmod +x $GROOVY_HOME/bin/svg2groovy

You may also want to grab the build of GraphicsBuilder 0.5.1 because I think it may have included another jar or two that wasn't covered above (MultipleGradientPaint.jar, TimingFramework-1.0-groovy.jar, swing-worker.jar, and swingx-0.9.2.jar).

6) Play with it
You can either test it by running the graphicsPad application or writing a script that calls one of the renderers:

import groovy.swing.j2d.*
import groovy.swing.j2d.svg.*

def foo = {
circle(cx:0, cy:0, radius:300, borderColor:'black', borderWidth:4) {
multiPaint {
texturePaint(x:0, y:0, file:'/Users/jareed/Desktop/602.png')
transformations {
translate(x:500, y: 500)
circle(cx:300, cy:300, radius:150, borderColor:'black', borderWidth:4) {
multiPaint {
texturePaint(x:0, y:0, file:'/Users/jareed/Desktop/602.png')

def gr = new GraphicsRenderer()
def sr = new SVGRenderer()

gr.renderToFile("/Users/jareed/Desktop/test.png", 1000, 1000, foo)
sr.renderToFile("/Users/jareed/Desktop/test.svg", 1000, 1000, foo)

which generates:

Nothing earth shattering, but it will be potentially interesting once I flesh out the project I want to use it on for. The best part, though, is that the SVG rendering works exactly as advertised. I had tried to do SVG rendering in the past using Batik's Graphics2D implementation (from a SWT app) and I couldn't get the background images to show up. Sweet!


Andres Almiray said...

Thanks for the kind words! answers to some of the problems you encountered

1) jdk/jre 1.6+ required: this was due to the inability of previous versions of Gmaven to set the targetBytecode property on the compiler. the next release should have proper jdk 1.4+ binaries

2) Groovy 1.6 blows: yes I noticed that too. As it is still in beta I would recommend sticking to the latest 1.5.x
9until I figure out why it blows with g1.6)

3) batik deps: it is painful that batik 1.7 was released 2 or 3 months ago and the central maven repo has not published the artifacts yet :(

4) don't forget Filters.jar. the one provided by swingx-0.9.2 is not enough, it must be the one bundled with GraphicsBuilder 0.5.1 We will be bundling the same jar with SwingXBuilder

5) it is a matter of taste but I would recommend you place the jars in ~/.groovy/lib that way you may update your groovy version without having to move the libs again =)

6) I'll fix the master pom detail on groovy-all-minimal

Josh Reed said...

Hi Andres,

The kind words are all deserved. I left a message on one your your blog posts but would it be OK if I contacted you directly with some questions?

1) Awesome. I was hoping to be able to use it in a Java 1.5 project.

2) No worries.

3) Hopefully they'll get on the ball.

4) I thought there was a Filters.jar in graphicsbuilder-ext-swingx/src/lib? It looks to be the same size. 'cp */src/lib/*.jar' should catch that.

5) Yeah, I learned about the ~/.groovy/lib after I wrote the blog. I'll probably update it to reflect this as I had lots of dual copy statements (~/Source/groovy-1.6 and ~/Source/groovy-1.5.6). ~/.groovy/lib is much cleaner.

6) Sounds good. I didn't know if the master one needed updating or if the other ones needed updating. I took the lazy route.


Anonymous said...

Hi Josh.

The Batik 1.7 artifacts should have been in the central maven repository since just after the release:

Do you still have trouble with them?

Josh Reed said...

@heycam -
Hmm...I didn't write the original pom.xml files, but maybe I'll try updating them to use this. I think there may have been a mismatch with the naming, so that's why they weren't seen.


Andres Almiray said...

@heycam that makes sense, the group id has been renamed to 'org/apache/xmlgraphics', on the previous release (1.6-1) it was just 'batik'. I'll update the poms, thanks!

Anonymous said...

@andres: Yeah, I didn't get around to doing that trick where you make new POMs in the old groupid redirect to the new groupid, so I guess that's the problem.