Skip to main content

Architecting Applications 2: the Application class

Posted by zixle on January 30, 2006 at 3:03 PM PST

This is the second blog in a series on architecting
applications. In the first href="http://weblogs.java.net/blog/zixle/archive/2006/01/architecting_ap.html">blog I discussed the application
I'm going to develop, how it would be architected, and briefly
went over the model. In this second article I'll motivate the need
for an Application class that is suitable for typical Swing based
Apps, as well as the functionality it should provide.

Swing is an incredibly rich toolkit, but to date we haven't
provided much guidance on how to structure your app. How should
I start my app? Where should I place resource bundles in my
project? How should I use preferences? Logging? ... The list
goes on. While I'm not going to address all of these issues I'm
going to focus on the first issue. How should I start my app?
The first thing to comes to mind is something along the lines
of:

public class Main {
  public static void main(String[] args) {
    JFrame frame = new JFrame(...);
    frame.pack();
    frame.show();
  }
}

Unfortunately this code can be problematic. Swing is not thread safe
and unless otherwise mentioned in the javadoc all methods must be
invoked on the event dispatch thread. As it's name implies, the
main method is invoked on the main thread. The preceeding code
calls into Swing widgets from this thread - the main thread. As
such, it is entirely likely that wierd errors or exceptions can
occur. Why you ask? Invoking various Swing/AWT methods can result
in events getting posted to the event dispatch thread. If the
thread scheduler happens to schedule processing of those events
while the main thread is still invoking methods you'll have two
threads interacting with the same Swing component at the same
time - a definite no-no. Best case, it all works and you're fine,
worst case you get random deadlocks!

We currently recommend an approach along the following lines:

public class Main {
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }
}

But this gets to be a bit painful to remember every time
through. Ideally there would be a class that isolates you from the
various Swing threading vagaries. Furthermore, it would be great
if this class were seamlessly integrated with builders.

Here's how I would like to write main:

public class Main {
  public static void main(String[] args) {
    new MyApplication().start();
  }
}

And MyApplication would have methods intended to be overriden that
are called on the event dispatch thread. This way I don't have to
do the invokeLater everytime, it's handled for me.

Beyond handling proper initialization there are a number of other
features common across Swing apps. In no particular order they
are:

  • Registering as the uncaught exception handler such that if an
    uncaught exception is received the application alerts the user
    and exits.

  • Using a ResourceBundle for localized resources. For small to mid
    size apps putting resources into a single resource bundle is
    fine, large apps will undoubtedly want finer granularity.

  • Using a PreferencesNode for persistant information. Again, for
    small to mid size apps using the same preferences nodes is
    fine, for large apps you will undoubtedly want finer
    granularity. There are problems with using preferences in
    webstart/plugin, but that's for another day.

  • A single point to exit the app, as well as the ability for
    listeners to cancel the exit.

  • Ability to block exiting until background threads have finished as
    well as displaying a dialog to the user while this is
    happening.

Is this everything? I'm sure there is more common functionality, but this is a good start.

I suspect anyone that's developed a number of Swing apps has already
developed a similar class. You can find the version used in this
article href="http://weblogs.java.net/blog/zixle/archive/2006.01.30/Application.java">here, or peruse the doc of href="http://weblogs.java.net/blog/zixle/archive/2006.01.30/Application.html">Application and href="http://weblogs.java.net/blog/zixle/archive/2006.01.30/ApplicationListener.html">ApplicationListener.

Application itself is an abstract class, a typical subclass, and the one for this blog series, looks like:

public class PasswordStoreApplication extends Application {
    public String getName() {
        return "PasswordStore";
    }

    protected void init() {
        JFrame frame = new JFrame(getName());
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                exit();
            }
        });
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new PasswordStoreApplication().start();
    }
}

Notice main, it's now short and sweet. While not obvious, init is
invoked on the event dispatch thread and I needn't worry about
using invokeLater, it's all done for me! Similarly the look and
feel is automatically set to the system look and feel for me from
the preInit method.

Those that look at the code will notice a couple of hard code
strings. Bad Scott, bad Scott! I did this to make it easier for
folks to download the source and use, but this most definitely
needs to come from a resource bundle. You've been warned.

I've tried to keep Application simple. It doesn't know about Frame or
any other application specific components, that's up to
subclasses. In fact it probably makes sense to have a subclass
that knows about a single frame. Such a subclass would further
reduce the code of PasswordStoreApplication as registering the
window listener, packing and all that would be done for you.

One of the biggest open questions with a class like Application, is
should it do dependency injection? That is, should Application
contain meta information about your application that can be used
in configuring it. For example, database style apps need to know
what database to connect to. Does it make sense to have
Application configure your connection settings so that there is
a standard place for this meta information? I'm not sure, but
I'm certainly interested in feedback from the community.

A related issue I mentioned is how this class would work with
builders. Ideally one would be able to create a 'Swing
Application' which in turn would configure things like the name
of the application and perhaps a class to create on the EDT. In
this way developers needn't subclass Application directly, the
builders would do the wiring for you. More research is needed on
this.

Hans suggested
rather than using listeners you have the ability to register
Runnables given a name, with the Runnables processed at well
known points in the app life cycle. This would make for a more
loosely specified init sequence, but one that allows for a bit
more than listeners. I'll explore this in more detail later.

In the interest of keeping each blog short and sweet I'm going to wrap
this one up here. I had hoped to have something running by this
point, but I'll leave that to the next blog. In the next blog
I'll create a controller class along with the UI that ties the
model together and is started with the Application subclass. I
promise that by the end of the next article you'll be able to
click on a web start link to see the app running.

    -Scott

Related Topics >>