More action with Struts 2
In a recent review of Struts 2 in Action, JW Blogger Oleg Mikheev notes that Struts 2 is "just a collection of extensions built upon WebWork, which is ultimately the right thing to learn before starting a Struts 2 project." While Struts 2 has some architectural flaws, Oleg calls WebWork well-designed, well-tested, and reliable. What are your experiences using Struts 2 and WebWork?

Also see "Hello World the WebWork way," a JavaWorld excerpt from WebWork in Action, by Patrick Lightbody and Jason Carreira.

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Solve the date-selection problem once and for all

Implement a date-selection widget using the Decorator pattern

Date selection is a problem that pops up every few months when you build client-side graphical user interfaces (GUIs). Unfortunately, Java doesn't provide anything like a DateChooser class, and the date-selection widgets I found in a recent Web search were too heavyweight for my purposes. I wanted something clean, unobtrusive, and flexible. Figure 1 shows a few variants of this article's class, so you can see what I mean by "clean" at the display level.

Figure 1. Various ways to present a Date_selector object



The free off-the-Web solutions were great examples of the you-get-what-you-pay-for principle: amateurish code that must be completely rewritten to be useful. This article's example, in fact, started out as an off-the-Web control, but by the time I finished fixing it, not a single line of the original code remained, and the architecture had completely changed (or, I should say, I added an architecture to an amorphous Java mass). So much for "free."

My widget also provides a good Decorator design pattern demonstration and a good look at Java's Calendar class, and it shows how to implement your own title bars and frames on a Swing JDialog.

Decorators

As is the case with any complex problem, the solution is greatly simplified by breaking the big problem up into smaller problems, each of which can be easily implemented (and tested). The Decorator pattern is great for this approach.

You've seen decorators if you've used Java's input/output (I/O) classes. The complex problem is efficiently reading a compressed stream of bytes, for example. You can do this with one massive class, but it's easier to break the problem up into three distinct subproblems:

  1. Read bytes
  2. Make reads more efficient with buffering
  3. Decompress a stream of bytes


Java solves the first problem with a FileInputStream, instantiated like this:

    try
    {   InputStream in = new FileInputStream( "file.name" );
    }
    catch( IOException e )
    {   System.err.println( "Couldn't open file.name" );
        e.printStackTrace();
    }


You then add buffering with a decoration (or "wrapping") strategy. You wrap the InputStream object with another InputStream implementor that buffers bytes. You ask the wrapper for a byte; it asks the wrapped stream for many bytes and returns the first one. The decorator wrapping goes like this:

    try
    {   InputStream in = new FileInputStream( "file.name" );
        in = new BufferedInputStream( in );
    }
    catch( IOException e )
    {   System.err.println( "Couldn't open file.name" );
        e.printStackTrace();
    }


Add decompression with another decorator:

    try
    {   InputStream in = new FileInputStream( "file.name" );
        in = new BufferedInputStream( in );
        in = new GZipInputStream( in );
    }
    catch( IOException e )
    {   System.err.println( "Couldn't open file.name" );
        e.printStackTrace();
    }


You can increase filtering by adding more decorators.

This solution is very flexible. You can mix and max the decorators to get the feature mix you need. More importantly, each decorator is relatively simple because it solves only one problem. Consequently, the decorators are easy to write, debug, and modify without affecting the rest of the system. I can change the buffering algorithm by rewriting BufferedInputStream, for example, and not touch any other decorators (or any code that uses them). I can also add new filter functionality simply by implementing a new decorator. (Classes like CipherInputStream were added to Java this way.)

Discuss

Start a new discussion or jump into one of the threads below:

Subject Replies Last post
. Source
By Anonymous
7 10/29/06 05:40 AM
by Anonymous
. clock decorator
By JeanLazarou
1 10/29/06 05:38 AM
by Anonymous
. An alternative which is not amatuerish
By Anonymous
0 10/29/06 05:38 AM
by Anonymous
. casting to get the component (JPanel)
By Anonymous
4 10/28/06 08:28 PM
by Anonymous


Resources