Remedial Spring Rich Pt 1, Setting up

Some of the big names in the Swing community have been talking quite a bit lately about container-managed Swing and Swing application frameworks.

The basic idea is this: developers are often complaining about the complexity of the Swing API… doing simple things is easy, but building real applications involves a very steep learning curve, and is likely to require a lot of application plumbing code (think data binding, wizard effects, registries to store common GUI actions and global references to disparate GUI components). This work is tedious and isn’t the reason you set out to develop a rich client.

Swing app frameworks and containers could solve many of these problems by providing a more high-level API for developing Swing clients, and leaving the tedium (and maybe even multi-threading) to the container or framework. Commonly needed functionality could be more easily plugged into your application. The topic is very sexy at the moment.

Today, I’m starting a series that will document my progress in learning one such framework/container: The Spring Rich Client Project.

Why Spring Rich in particular? Mainly because I’ve done a lot of reading about the Spring Framework as a whole and I’m totally sold on the benefits Spring brings to your code. Namely IoC and AOP. I won’t waste time trying to explain the benefits of Spring… I’m still learning, and others have explained much better than I can. Check out the Spring site for details.

Other than that, after digging into the Spring Rich code base, I’m pretty blown away… There’s some amazing stuff in there. For the good of the Swing community, this project needs to succeed.

I don’t claim any great knowledge about this framework… quite the opposite, I’m just learning. But in getting started with Spring Rich I’ve noticed that there is a dearth of information on the subject, and it’s incredibly hard to figure out how to get started. I’m sure this is largely due to the fact that the product is basically in the alpha stage currently, and will improve over time.

It seems that Spring Rich needs some developers to spread the word and also any small bits of knowledge they can, to get this project “out there” until the documentation is more complete.

So I’ve embarked on a small project using Spring Rich… The application is a simple uploader client for uploading xml files to a Spring-based http service available as a tomcat-based webapp (more about how to connect to the service — which Spring makes incredibly easy — later).

Today, I’ll describe the basic first steps I’ve taken to get started with Spring Rich.

  • Downloading the source.
  • Setting up my project structure.

I know that sounds like baby steps, but remember that there’s virtually no information out there (that I’ve found) about the project.

Okay, to get a copy of Spring Rich, you have to checkout the source from the Spring CVS repository, since it’s not yet available as a downloadable package of any kind. This did the trick:


cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/spring-rich-c login
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/spring-rich-c co spring-richclient

Then I cd’ed into the base directory of the project, and ran the following two ant build targets to compile the source:


ant alljars
ant sandboxjar

Those commands placed the jars for the framwork in the dist directory:


spring-richclient/dist/spring-richclient-resources.jar
spring-richclient/dist/spring-richclient-sandbox.jar
spring-richclient/dist/spring-richclient.jar

Then, I dragged those three jars (along with some other goodies) into the lib directory of my project (called Joglets). Of course, I’m using ant to build and manage the project. I have a very standard layout:


build.properties
build.xml
src/
    org/
        joglets/
            client/
                swing/
                    ...
lib/
    spring-richclient-resources.jar
    spring-richclient-sandbox.jar
    spring-richclient.jar
    ...

Below are my build.properties file and my build.xml build file. The build file has targets for compiling, jaring and running a simple application. Of course, you’ll have to change some of the property values to your own class names and directories.

Next time we’ll take a look at a few basics of the main method for a Spring Rich Client application, and set up a simple startup context and splash screen.


src.dir=src
lib.dir=lib
dist.dir=dist

build.dir=build
build.bin=${build.dir}/bin
build.classes=${build.dir}/classes

jarfile.name=${ant.project.name}.jar
jarfile.path=${build.bin}/${jarfile.name}

zipfile.name=${ant.project.name}.zip
zipfile.path=${dist.dir}/${zipfile.name}

manifestfile.name=manifest.mf
manifestfile.path=${src.dir}/${manifestfile.name}

mainclass.name=org.joglets.client.swing.Main


<?xml version='1.0' encoding='utf-8'?>
<project name='JogletsSwingClient' basedir='.' default='run'>

    <property file='build.properties'/>

    <fileset dir='${lib.dir}' id='lib.jars'>
        <include name='**/*.jar'/>
    </fileset>

    <path id='compile.classpath'>
        <fileset refid='lib.jars'/>
    </path>

    <path id='run.classpath'>
        <path refid='compile.classpath'/>
    </path>

    <target name='clean'>
        <delete dir='${build.dir}'/>
        <delete dir='${dist.dir}'/>
    </target>

    <target name='prepare' depends='clean'>
        <mkdir dir='${build.classes}'/>
        <mkdir dir='${build.bin}'/>
        <mkdir dir='${dist.dir}'/>
    </target>

    <target name='compile' depends='prepare'>
        <javac srcdir='${src.dir}'
               destdir='${build.classes}'
               includeAntRuntime='no'
               source='1.5'
               classpathref='compile.classpath'/>
    </target>

    <target name='manifest'>
        <manifest file='${manifestfile.path}'>
            <attribute name='Built-By' value='${user.name}'/>
            <attribute name='Built-On' value='${timestamp.isoformat}'/>
            <attribute name='Main-Class' value='${mainclass.name}'/>
        </manifest>
    </target>

    <target name='jar' depends='compile,manifest'>
        <jar destfile='${jarfile.path}'
             index='true'
             manifest='${manifestfile.path}'>
            <fileset dir='${build.classes}'/>
        </jar>
    </target>

    <target name='run' depends='jar'>
        <java jar='${jarfile.path}'
              classpathref='run.classpath'
              fork='true'
              failonerror='true'
              maxmemory='128m'>
            <assertions>
                <enable/>
            </assertions>
        </java>
    </target>

    <target name='dist' depends='jar'>
        <zip destfile='${zipfile.path}'>
            <fileset dir='${basedir}' includes='**/*.*'/>
        </zip>
    </target>

</project>


About this entry