Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
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.
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:
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.)
Archived Discussions (Read only)