<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Laird Nelson&apos;s Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/ljnelson/" />
<modified>2008-07-31T18:25:17Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/ljnelson/175</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2008, ljnelson</copyright>
<entry>
<title>Nimbus and Opacity</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/ljnelson/archive/2008/07/nimbus_and_opac.html" />
<modified>2008-07-31T18:25:17Z</modified>
<issued>2008-07-31T18:25:12Z</issued>
<id>tag:weblogs.java.net,2008:/blog/ljnelson/175.10206</id>
<created>2008-07-31T18:25:12Z</created>
<summary type="text/plain">Want a text field with a non-opaque background when using Nimbus?  Read on.</summary>
<author>
<name>ljnelson</name>

<email>ljnelson@gmail.com</email>
</author>
<dc:subject>Swing</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/ljnelson/">
<![CDATA[<p>This one tripped me up, and I thought I'd post it here.  I have a case where I need to pour text into a <tt>JTextField</tt>, but have that <tt>JTextField</tt> look like a <tt>JLabel</tt>.  So as I type in one field, I need this "gray" second field to update, live, before the user's eyes.  I also need the ability for the user to cut-and-paste values out of it.  This sort of thing is reasonably common in properties panels and the like.</p>

<p>Now, normally all you have to do is something like this:<blockquote><pre>final JTextComponent previewComponent = new JTextField();
previewComponent.setBorder(null);
previewComponent.setEditable(false);
previewComponent.setOpaque(false);</pre></blockquote>...and you have what looks like a <tt>JLabel</tt> but what behaves like a <tt>JTextField</tt>.</p>

<p>Well, except under Nimbus, where the <tt>setOpaque(false)</tt> seems to have no effect.  Turns out you need to also set the background color to a transparent color as well.  Fortunately, this combination of behaviors seems to work under all the other look and feels (looks and feels?):<blockquote><pre>previewComponent.setBorder(null);
previewComponent.setEditable(false);
previewComponent.setOpaque(false);
previewComponent.setBackground(new Color(0, 0, 0, 0));</pre></blockquote></p>

<p>I hope this helps other Swing folks out.</p>]]>

</content>
</entry>
<entry>
<title>Useful Swing Thing #1</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/ljnelson/archive/2007/12/useful_swing_th.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-12-17T20:35:41Z</issued>
<id>tag:weblogs.java.net,2007:/blog/ljnelson/175.8850</id>
<created>2007-12-17T20:35:41Z</created>
<summary type="text/plain">The first of (hopefully) a series of quick, useful Swing tips.</summary>
<author>
<name>ljnelson</name>

<email>ljnelson@gmail.com</email>
</author>
<dc:subject>Swing</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/ljnelson/">
<![CDATA[<p>In Microsoft Outlook, along with probably dozens of other desktop applications, pressing <tt>ESC</tt> just about anywhere will cause the current window you're in to be cancelled.  In the case of dialogs, it is as though the <tt>Cancel</tt> button were pressed; in the case of root windows, it is as though you tried to exit the application (and you usually get a warning dialog that asks you if you're sure).</p>

<p>For one of my applications, I wanted to get this very useful UI gesture installed once, in the right way, preferably without messing with the current look and feel, without requiring tons of custom code, and without subclassing.  Here's a narrative of my journey, which also serves as a tutorial of sorts to the <tt>UIManager</tt> and <tt>UIDefaults</tt> classes.</p>

<p>For the impatient, here's the source code discussed in the article below: <a href="https://bricks.dev.java.net/source/browse/*checkout*/bricks/swing/jrootpanes/src/main/java/bricks/swing/jrootpanes/JRootPanes.java">https://bricks.dev.java.net/source/browse/*checkout*/bricks/swing/jrootpanes/src/main/java/bricks/swing/jrootpanes/JRootPanes.java</a>.</p>

<p>I started by looking into the <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/UIDefaults.html">UIDefaults</a> class, since I hadn't really done much with the <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/UIManager.hmtl">UIManager</a> class and its related classes in general.  To sum up, perhaps incorrectly, because I'm still not all that comfortable with it, you can think of the <tt>UIDefaults</tt> class as a hashtable containing all of the various UI attributes and properties that you can think of in the Java platform.  (This is wrong because really those values come from the look and feel classes, and <i>they're</i> the ones who installed them, but for the moment forget about where these values came from and focus on how you get access to them.)</p>

<p><tt>UIDefaults</tt> instances are maintained and shepherded around by the <tt>UIManager</tt> class, which has lots of useful static methods to work with those <tt>UIDefaults</tt> instances.</p>

<p>So, for example, if you want to see what the font is, by default, for the current look and feel's rendering of a <tt>JButton</tt>'s text, you would say:
<pre>final Font font = (Font)UIManager.get("Button.font");</pre>
This is really a cover for:
<pre>final Font font = UIManager.getDefaults().get("Button.font");</pre>
...but is usually the idiom you'll see (and it's a whole lot more convenient).</p>

<p>(How do you know what keys and values there are?  Well, obviously you could iterate over the results returned by <tt>UIManager.getDefaults().keys()</tt>, but failing that the only way to see what's in there is to examine the source of, for example, the <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/plaf/basic/BasicLookAndFeel.html"><tt>BasicLookAndFeel</tt></a> class.  That's probably a useful thing to look at anyhow.)</p>

<p>Picking up where we left off: if you're lucky and your JDK is normal you'll get back a non-<tt>null</tt> <tt>Font</tt> object that some <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/LookAndFeel.html"><tt>LookAndFeel</tt></a> put there for you.  That's why when you create a new <tt>JButton</tt> its font is...well, whatever that object is (usually it's the Dialog font).  That is, you didn't have to set the font on the button yourself; the value was defaulted for you by the current look and feel.</p>

<p>The <tt>UIManager</tt> exposes three levels of these defaults: the user defaults, the look and feel defaults, and the system defaults.  This happens transparently for callers: if you call <tt>UIManager.getDefaults()</tt> you get a <tt>UIDefaults</tt> object back that handles these three layers for you (in much the same way, for example, as <tt>java.util.Properties</tt> allows there to be a default <tt>Properties</tt> that is consulted in the case of a missed lookup).</p>

<p>If you never monkey with a <tt>UIDefaults</tt> object, then effectively you, the user, have never put in any user defaults, so anything you get out of that <tt>UIDefaults</tt> object is going to be either a look and feel default (i.e. the Metal or Ocean guys decided for you that teal or silver was an awesome color) or a system default (i.e. Microsoft's take on what color title bars should be).  On the other hand, if you <i>do</i> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/UIManager.html#put(java.lang.Object,%20java.lang.Object)">put</a> something into those defaults, then <i>your</i> value is the one that is returned, no matter what the current look and feel or system thinks the value should be.</p>

<p>Why is all this important?  Because if you want to do something UI-ish by <i>default</i>&mdash;as in, "affecting every future instance  of a UI class of some kind"&mdash;then you want to start here, because this is where those default values are managed.</p>

<p>Now, in this case I wasn't interested in colors or fonts or text or anything like that.  I was interested in key bindings: <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/InputMap.html"><tt>InputMap</tt>s</a> and <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/ActionMap.html"><tt>ActionMap</tt>s</a>.   <tt>ActionMap</tt>s store <tt>Action</tt>s indexed by, conventionally, <tt>Strings</tt>; <tt>InputMaps</tt> store, conventionally, <tt>String</tt>s indexed by <tt>KeyStroke</tt>s.  Well, it turns out that <tt>InputMap</tt>s are available&mdash;like fonts and colors&mdash;in the <tt>UIDefaults</tt> as well, for pretty much every component.  This would mean that if I could get my hands on, for example, the default <tt>ActionMap</tt> and the right kind of <tt>InputMap</tt> installed on <tt>JRootPane</tt> instances by default I might have a prayer of setting up a key binding for the <tt>ESCAPE</tt> key that would attempt to close the current window.</p>

<p>For the <tt>ActionMap</tt>&mdash;i.e. the place that stores an <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/Action.html"><tt>Action</tt></a> under a <tt>String</tt> key&mdash;it turns out that all <tt>JRootPane</tt> instances that have UI delegates that extend from <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/plaf/basic/BasicRootPaneUI.html"><tt>BasicRootPaneUI</tt></a> (which includes pretty much all the JDK-supplied UIs as well as a good number of third-party ones) will look for an <tt>ActionMap</tt> stored in the <tt>UIManager</tt> under the key&mdash;surprise, surprise&mdash;"<tt>RootPane.actionMap</tt>".  That means if you do this:
<pre>final ActionMap actionMap = (ActionMap)UIManager.get("RootPane.actionMap");</pre>
...you'll get back a non-<tt>null</tt> <tt>ActionMap</tt> containing all the <tt>Action</tt>s that <tt>JRootPane</tt>s will have if and when any is constructed.</p>

<p><tt>InputMap</tt>s are a little more complicated.  There are three of them for any given <tt>JComponent</tt>:
<ul>
<li>the one whose bindings are in effect when the component in question is focused</li>
<li>the one whose bindings are in effect when the component is a parent or ancestor of the focused component (and a suitable binding couldn't be found in that component's set of <tt>InputMaps</tt></li>
<li>the one whose bindings are in effect when nothing else worked, and all we know is that the component in question is in a focused <tt>Window</tt></li>
</ul>
At first glance, if you wanted an <tt>ESCAPE</tt> press to cause a <tt>Window</tt> to close, you might think to put the binding in the second location&mdash;the <tt>InputMap</tt> whose bindings are in effect when the <tt>JRootPane</tt> in question is an ancestor of a focused component.  This would mean, for example, that if you had a text field with the cursor in it, and someone pressed <tt>ESCAPE</tt>, the following logic would occur:
<ol>
<li>Does the text field have an <tt>ESCAPE</tt> binding in its <tt>WHEN_FOCUSED_COMPONENT</tt> <tt>InputMap</tt>?  No.</li>
<li>Does one of its ancestors have an <tt>ESCAPE</tt> binding in its <tt>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</tt> <tt>InputMap</tt>?  Yes (this is what would happen in the case we're describing).</li>
</ol></p>

<p>Well, we happen to be lucky in that this little sequence of code will give us the proper <tt>InputMap</tt> to work with:
<pre>final InputMap inputMap = UIManager.get("RootPane.ancestorInputMap");</pre></p>

<p>(I'll have more to say in a moment about why this isn't quite right&mdash;hint: what if there isn't a component in the window that has the focus?&mdash;but it's pretty good for now.)</p>

<p>So with these tools, we now have a place to put an <tt>Action</tt> that will close the parent <tt>Window</tt>:
<pre>  public static final void installCloseAction() {
    assert EventQueue.isDispatchThread();
    ActionMap actionMap = (ActionMap)UIManager.get("RootPane.actionMap");
    if (actionMap == null) {
      actionMap = new ActionMap();
      UIManager.put("RootPane.actionMap", actionMap);
    }
    assert actionMap != null;
    if (actionMap.get("close") == null) {
      actionMap.put("close", new AbstractAction("Close") {
          @Override public final void actionPerformed(final ActionEvent event) {
            assert event != null;
            final JRootPane rootPane = (JRootPane)event.getSource();
            assert rootPane != null;
            final Container container = SwingUtilities.getAncestorOfClass(RootPaneContainer.class, rootPane);
            if (container instanceof JInternalFrame) {
              final JInternalFrame internalFrame = (JInternalFrame)container;
              if (internalFrame.isClosable()) {
                internalFrame.doDefaultCloseAction();
              }
            } else {
              final Window window;
              if (container instanceof Window) {
                window = (Window)container;
              } else {
                window = SwingUtilities.getWindowAncestor(rootPane);
              }
              if (window != null) {
                window.dispatchEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSING));
              }          
            }
          }
        });
    }
  }</pre></p>

<p>Assuming this method is present in a class called <tt>JRootPanes</tt>, we can test this by using the following snippet of test code (this uses some <tt>JUnit</tt> assertions to help us out, and for brevity I've omitted all the cruft to get this running on the event dispatch thread):
<pre>JRootPanes.installCloseAction();
final JRootPane rootPane = new JRootPane();
final ActionMap actionMap = rootPane.getActionMap();
assertNotNull(actionMap);
final Action closeAction = actionMap.get("close");
assertNotNull(closeAction);</pre></p>

<p>Neat!  OK, so we have managed to affect the <tt>ActionMap</tt> prototype for all future <tt>JRootPane</tt> instances, regardless of look and feel.  How are we going to trigger our "<tt>close</tt>" <tt>Action</tt>?</p>

<p>One way to attempt this might be to do something like the following:
<pre>  final KeyStroke escape = KeyStroke.getKeyStroke("ESCAPE");
  assert escape != null;
  final InputMap inputMap = (InputMap)UIManager.get("RootPane.ancestorInputMap");
  if (inputMap != null && inputMap.get(escape) == null) {
    inputMap.put(escape, "close");
  }</pre>
That would non-intrusively affect the bindings stored in all <tt>JRootPane</tt> instances' <tt>InputMaps</tt> that are consulted when the <tt>JRootPane</tt> in question is the ancestor of a focused component.  But what about when the <tt>JRootPane</tt> is the ancestor of a bunch of components, <i>none of which has the focus?</i></p>

<p>Here's where things get tricky and annoying.  It turns out that there is no <tt>InputMap</tt> entry in the <tt>UIDefaults</tt> for <tt>JRootPanes</tt> for the <tt>WHEN_IN_FOCUSED_WINDOW</tt> case.  This makes a certain amount of sense: <tt>InputMaps</tt> installed in such cases actually have to be associated with their component (they must be instances of <tt>ComponentInputMap</tt>, actually) and so at "defaults time" you don't <i>have</i> a component, so it follows that you can't have a <tt>ComponentInputMap</tt>, and so it follows that you can't install one as the <tt>WHEN_IN_FOCUSED_WINDOW</tt> <tt>InputMap</tt>.  But wait a minute.  Doesn't <tt>ESCAPE</tt> close the window when you pop up a <tt>JOptionPane</tt>?  Why, yes, it sure does.  Hmmm.</p>

<p>I took a spin further down in the mammoth <tt>BasicLookAndFeel</tt> class and discovered a weird little entry for <tt>JOptionPane</tt> defaults:
<pre>// lines 1192-3 of BasicLookAndFeel.java follow:
"OptionPane.windowBindings", new Object[] {
"ESCAPE", "close" },</pre>  Without (further) boring you to tears I discovered that there is an accepted idiom for building up the raw materials for <tt>WHEN_IN_FOCUSED_WINDOW</tt> <tt>InputMap</tt>s (for <tt>BasicLookAndFeel</tt>-descending look and feel implementations).  Sure enough, if you trace the code back, you'll discover that the <tt>BasicOptionPaneUI</tt> UI delegate (the superclass of most <tt>JOptionPane</tt> UI delegates out there) grabs the key binding raw materials in here (<tt>"ESCAPE", "close"</tt>) and converts them into a <tt>WHEN_IN_FOCUSED_WINDOW</tt> <tt>InputMap</tt>.  And&mdash;oops, <tt>BasicRootPaneUI</tt> doesn't do this, which means that <tt>BasicRootPaneUI</tt> doesn't ever consult anything in the <tt>UIManager</tt>/<tt>UIDefaults</tt> machinery to make this happen or to provide an injection point.</p>

<p>(If <tt>BasicRootPaneUI</tt> were changed, it would do something like this in its implementation of <tt>createInputMap(int, JComponent)</tt>:
<ul>
<li>Get the "<tt>RootPane.windowBindings</tt>" entry out of the <tt>UIDefaults</tt>.</li>
<li>Call <tt>LookAndFeel.makeComponentInputMap(rootPane, bindings);</tt>.</li>
</ul>...but, well, it doesn't.)</p>

<p>Being the stubborn sort, I turned to the other giant cudgel thoughtfully given to us by the AWT guys&mdash;<tt>Toolkit.addAWTListener()</tt>.  The only place to "inject" an <tt>InputMap</tt> of the proper variety&mdash;since without subclassing we can't really do it at <tt>JRootPane</tt> construction time&mdash;is when a <tt>JRootPane</tt> is made displayable.  The code below monitors <tt>HierarchyEvent</tt>s for those containing <tt>JRootPane</tt>s that have just been made displayable, and, when it finds such a <tt>JRootPane</tt> it tries to non-intrusively modify or install the <tt>WHEN_IN_FOCUSED_WINDOW</tt> <tt>InputMap</tt>:
<pre>  private static final KeyStroke escape = KeyStroke.getKeyStroke("ESCAPE");

  private static final AWTEventListener awtListener = new AWTEventListener() {
      @Override public final void eventDispatched(final AWTEvent event) {
        assert EventQueue.isDispatchThread();
        assert event != null;
        if (event instanceof HierarchyEvent && event.getID() == HierarchyEvent.HIERARCHY_CHANGED) {
          // This event represents a change in the containment hierarcy.
          // Now let's figure out what kind.
          final HierarchyEvent hevent = (HierarchyEvent)event;
          final Component changed = hevent.getChanged();
          if (changed instanceof JRootPane && ((hevent.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) && changed.isDisplayable()) {
            // Aha!  A JRootPane has just been made displayable!
            final InputMap inputMap = ((JRootPane)changed).getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
            if (inputMap != null && inputMap.get(escape) == null) {
              inputMap.put(escape, "close");
            }
          }
        }
      }
    };

  public static final void makeEscapeCloseAllWindows() {
    assert EventQueue.isDispatchThread();
    final Toolkit toolkit = Toolkit.getDefaultToolkit();
    assert toolkit != null;
    toolkit.removeAWTEventListener(awtListener);
    installCloseAction(); // from before; see earlier in this article
    toolkit.addAWTEventListener(awtListener, AWTEvent.HIERARCHY_EVENT_MASK);
  }</pre></p>

<p>Sure enough, if you invoke this code before you create any <tt>JDialogs</tt> or <tt>JFrames</tt> then silently all such windows will be closeable with the <tt>ESCAPE</tt> key.</p>

<p>Thanks for reading.</p>]]>

</content>
</entry>
<entry>
<title>Objects and Strings and the Wrangling Thereof (Part 2)</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/ljnelson/archive/2007/08/objects_and_str_2.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-08-31T16:07:45Z</issued>
<id>tag:weblogs.java.net,2007:/blog/ljnelson/175.8144</id>
<created>2007-08-31T16:07:45Z</created>
<summary type="text/plain">Part two of a series, in which we look at (and recoil in horror from) the java.text.Format class.</summary>
<author>
<name>ljnelson</name>

<email>ljnelson@gmail.com</email>
</author>
<dc:subject>Swing</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/ljnelson/">
<![CDATA[<p>In the <a href="http://weblogs.java.net/blog/ljnelson/archive/2007/08/objects_and_str.html">prior entry</a>, we learned that Java ships with several tools to standardize the conversion between <tt>String</tt>s and <tt>Object</tt>s.  We covered the text conversion methods of <tt>java.beans.PropertyEditor</tt>.  We will most definitely come back to <tt>PropertyEditor</tt>s, because they're about a heck of a lot more than just converting text, but let's take a detour into the dank recesses of the <tt>java.text</tt> package.</p>

<p>Do you smell that?  That's all the dust left over from when this package was <a href="http://www.ibm.com/developerworks/java/library/j-sun-ibm-java.html">deposited by IBM and Taligent</a> into the official Java runtime platform 'round about 1997.  <tt>java.text</tt> was put in, as I understand it, primarily for internationalization (I18N) purposes, and one of the bits that landed there was the <tt>java.text.Format</tt> class, which, although described as a way to format <tt>Locale</tt>-specific information, has nothing whatsoever to do with <tt>Locale</tt>s or internationalization at all.  Go figure.  It does, however, have lots to do with converting <tt>Object</tt>s into <tt>String</tt>s and vice versa.</p>
<h3>Format</h3>
<p>The <tt>Format</tt> class is responsible for formatting <tt>Object</tt>s into <tt>String</tt>s, and taking <tt>String</tt>s and parsing them back into <tt>Object</tt>s.  Unlike <tt>PropertyEditor</tt>, whose API seems to have more plumbing and rebar and wiring than my house, a <tt>Format</tt> is a relatively simple thing.  Want to parse a <tt>String</tt> into an <tt>Object</tt>?  Call the stateless <tt>parseObject(String)</tt> method.  Want to do the reverse?  Call the <tt>format(Object)</tt> method.  Easy and simple.  And stateless.</p>

<p><tt>java.text.Format</tt> also supports lots of substring parsing and formatting, via the <tt>ParsePosition</tt> and <tt>FieldPosition</tt> classes.  In general, I've found the use cases for these to be pretty thin, except where <tt>Date</tt>s are concerned, and for that someone has already written the <tt>SimpleDateFormat</tt> class, so we'll pretty much deal with them only where necessary.</p>

<p>Let's pick up on our previous example and write a <tt>URIFormat</tt> class:<blockquote><pre>public class URIFormat extends Format {
  public URIFormat() {
    super();
  }

  // 1
  public StringBuffer format(final Object object, final StringBuffer buffer, final FieldPosition fieldPosition) {
    // 2
    if (buffer == null) {
      throw new NullPointerException("buffer == null");
    }

    // 3
    if (fieldPosition == null) {
      throw new NullPointerException("fieldPosition == null");
    }

    // 4
    if (object == null) {
      return buffer;
    }

    // 5
    if (!(object instanceof URI)) {
      throw new IllegalArgumentException(object + " is not a URI instance");
    }

    return buffer.append(object.toString());

  }
}</pre></blockquote>This method is relatively simple to implement properly and fully defensively.  Here are the details (once again, numbers below correspond to numbers in the code comments above):<ol><li><tt>java.text.Format</tt>'s <tt>format(Object)</tt> method calls through to this one, which subclasses must implement.  The general idea here is to sanity check our arguments, then investigate the <tt>FieldPosition</tt> to see what portion of the incoming object we should format, attempt the convert-it-to-a-<tt>String</tt> operation, and return the result.  For our purposes we can skip the <tt>FieldPosition</tt> argument entirely (it's conceivable that you might want to implement a <tt>URIFormat</tt> that formats, for example, only the "authority" field of a given <tt>URI</tt> but we're not going to do that here).</li><li>Note that the contract of this method requires us to throw a <tt>NullPointerException</tt> if <tt>buffer</tt> is <tt>null</tt>.  I don't like this, but that's our contract.  I'd prefer to simply return <tt>null</tt>, since it's obvious that what you put into this method comes out the back of it, but I didn't write the contract.  Why not just let the <tt>NullPointerException</tt> happen naturally instead of proactively throwing it?  Because there is no message that gets output by automatic <tt>NullPointerException</tt>s at all, and that is just evil.</li><li>Continuing through the forest of <tt>NullPointerException</tt>s, we are required to throw one as well if the <tt>fieldPosition</tt> is <tt>null</tt>.  Even though in the vast majority of cases you won't ever use this parameter.</li><li>Now, what does the contract say about a <tt>null</tt> <tt>Object</tt> parameter?  Fortunately, and correctly, it says nothing.  That could be valid input for you.  Since the contract is open here, I choose to practice leave-no-trace programming, and I simply return the buffer that was handed to me.  That is, hey, I chose to "format" the <tt>null</tt> URI by doing exactly nothing.  You could choose to do something different here.  (If you choose to follow my example here, you'll reap the benefits later on, because we will be able to pass this value straight into a <tt>PropertyEditor</tt> implementation and honor its contract as a convenient side effect.)</li><li>Next, we need to handle the case where invalid input is handed to us (<tt>null</tt> is not invalid input; there are many cases where you want to handle the formatting of <tt>null</tt> values; that's why we dealt with that as a separate case).  So here the contract tells us, effectively, to reject bad input with an <tt>IllegalArgumentException</tt>.  But, of course, it's up to you to decide what constitutes bad input.  I've chosen to err on the conservative side and say, look, this <tt>Format</tt> I'm writing works only on <tt>URI</tt> instances.  Anything else that it's asked to format won't work.  You could also simply do nothing and return the incoming <tt>buffer</tt> as is.</li><li>Now all we have to do is (again) use the well-documented and consistent <tt>toString()</tt> method from <tt>java.net.URI</tt> and append it to the <tt>buffer</tt> parameter.  Since <tt>append()</tt> returns the resulting <tt>StringBuffer</tt>, we simply return that.</li></ol>Again, the thought process behind this really simple method is what's important.  You want to think hard about the what garbage is going to be coming in and what the caller will expect out.</p>

<p>The <tt>parseObject</tt> method is basically just the reverse, but I'll have a little more to say about it in comparison to the <tt>setAsText()</tt> method of <tt>PropertyEditor</tt>.  It also has some of the weirdest error handling conventions I've ever seen.  Basically, if there is an error, you return <tt>null</tt>, and use the incoming <tt>ParsePosition</tt> object to store where the error occurred during parsing.  And in the success case, you are obligated to update the supplied <tt>parsePosition</tt>'s <i>regular</i> <tt>index</tt> property to just past where you finished parsing.</p>

<p>So what if you have to return <tt>null</tt>, so you can, for example, capture and parse user input that should be converted to the <tt>null</tt> reference?  It would appear, although the contract is not at all specific, that you return <tt>null</tt>, but make sure that the <tt>ParsePosition</tt>'s <tt>errorIndex</tt> property is set to <tt>-1</tt> to indicate that there is no error.  Additionally, there's some intent we can read from the source code.</p>

<p>Diving into the <tt>Format</tt> source code, we see that the convenience method, <tt>parseObject(String)</tt>, actually evaluates the return value of this method by more or less ignoring the contract entirely!  It checks to see if <i>this</i> method has modified the <tt>parsePosition</tt>'s <tt>index</tt> property.  If it <i>hasn't</i>, then, it would appear, an error has occurred (since hey, parsing couldn't even take place), and, it turns out, <i>regardless</i> of this method's return value, an exception is thrown.  So much for contracts, at least where Taligent <s>is</s> was concerned.</p>

<p>OK, then; here's how we do it:<blockquote><pre>//1
public Object parseObject(final String text, final ParsePosition parsePosition) {

  // 2
  if (parsePosition == null) {
    throw new NullPointerException("parsePosition == null");
  }

  // 3
  if (parsePosition.getErrorIndex() != -1) {
    return null;
  }

  // 4
  final int startIndex = parsePosition.getIndex();
  if (startIndex &lt; 0) {
    parsePosition.setErrorIndex(startIndex);
    return null;
  }

  // 5
  if (text == null) {
    // This is not an error; this is a valid input value.  We want to return null.
    // So we take liberties with this soft and squishy area of the contract,
    // and we set the parsePosition's beginning to a value that is different
    // from what it initially was.  No one is going to try to parse a null
    // text twice, anyhow, and this actually prevents it.
    parsePosition.setIndex(-1);
    parsePosition.setErrorIndex(-1);
    return null;
  }

  // 6
  final int textLength = text.length();
  if (textLength &lt;= 0 || text.trim().getLength() &lt;= 0) {
    parsePosition.setIndex(-1);
    parsePosition.setErrorIndex(-1);
    return null;
  }

  // 7
  if (startIndex &gt;= textLength) {
    parsePosition.setErrorIndex(startIndex);
    return null;
  }

  // 8
  try {
    final URI uri = new URI(text.substring(startIndex);
    parsePosition.setIndex(textLength);
    parsePosition.setErrorIndex(-1);
    return uri;
  } catch (final URISyntaxException kaboom) {
    parsePosition.setErrorIndex(kaboom.getIndex());
    return null;
  }

}</pre></blockquote><ol><li>This method is the one that all work is delegated to from the simpler <tt>parseObject(String)</tt> version.  You have to implement it.</li><li>The contract again, annoyingly, forces us to throw a <tt>NullPointerException</tt> if there's no <tt>ParsePosition</tt>.</li><li>Here I check to see if the error index on the supplied <tt>ParsePosition</tt> has already been set.  If it has, then it's not clear to me what I should do (the contract is silent; thanks, IBM!).  I err on the side of being conservative and, since the parameter indicates that there's an error in play already, I return <tt>null</tt> per that part of the contract.</li><li>I can't parse any text starting at a position less than zero, so we set the <tt>errorIndex</tt> of the <tt>parsePosition</tt> here and return <tt>null</tt> as instructed.</li><li>If the supplied text is <tt>null</tt>, then I interpret this to mean that the user would like a <tt>null</tt> <tt>URI</tt> in return—i.e. he's trying, with text as his only weapon, to clear an object reference.  But the contract to <tt>Format</tt> tells me I can't return <tt>null</tt> except in error conditions!  But then the contract also tells me that <tt>ParsePosition</tt> has an <tt>errorIndex</tt> property to indicate where an error occurred.  And the <tt>Format</tt> source code tells me that <i>really</i> the indicator of an error is whether the <tt>index</tt> has changed value or not.  If it has <i>not</i> changed value, then some of the <tt>Format</tt> class' innards assume that since parsing didn't happen, an error must have occurred.  (Pause for Buddhist-like contemplation of this leap of logic and faith.)  So, we ensure that the <tt>parsePosition</tt>'s index is set to a value that it could not have been set to by this point, but we <i>also</i> set the error index to <tt>-1</tt> to indicate that the return value is to be considered valid.  Whew.</li><li>Zero-length <tt>String</tt>s are interpreted as instructions to return a non-error-case <tt>null</tt> <tt>URI</tt>.  So we jump through the hoops here to do that.</li><li>If we were told to parse starting <i>after</i> the supplied <tt>String</tt>, then do what we need to do to indicate pilot error.</li><li>Finally, parse the supplied <tt>String</tt>, starting where we're supposed to, and, if we succeed, <i>remember to move the <tt>parsePosition</tt>'s index</i>!  If we fail, then fortunately <tt>URISyntaxException</tt> actually has an <tt>index</tt> property (glory be!), so we set that and return <tt>null</tt>.</li></ol>I hope if nothing else this little exercise should convince you, basically, to not replicate <i>any</i> object conversion logic in a <tt>java.text.Format</tt>.  They are gross, disgusting, and despite their general purpose aura that hangs about them, more or less unsuitable for use outside the <tt>java.text</tt> package.</p>

<p>But.</p>

<p>They can be quite useful for bridging gaps between <tt>PropertyEditor</tt>s and <tt>JFormattedTextField</tt>s, as we'll see in the next entry.  The gist is that we'll create a <tt>Format</tt> that delegates to a <tt>PropertyEditor</tt> implementation.  From there it's a drop-in to get your <tt>PropertyEditor</tt> to be used by <tt>JFormattedTextField</tt>s.</p>

<p>Thanks for reading.</p>

<p class="poweredbyperformancing">Powered by <a href="http://scribefire.com/">ScribeFire</a>.</p>]]>

</content>
</entry>
<entry>
<title>Objects and Strings and the Wrangling Thereof</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/ljnelson/archive/2007/08/objects_and_str.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-08-27T18:49:39Z</issued>
<id>tag:weblogs.java.net,2007:/blog/ljnelson/175.8111</id>
<created>2007-08-27T18:49:39Z</created>
<summary type="text/plain">PropertyEditors, Formats, and JFormattedTextFields, oh my!</summary>
<author>
<name>ljnelson</name>

<email>ljnelson@gmail.com</email>
</author>
<dc:subject>Swing</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/ljnelson/">
<![CDATA[See if this little scenario sounds familiar.<br /><blockquote>You're rolling along on some application somewhere, and you've decided to put some information in a <tt>Properties</tt> file somewhere.  You realize that you're beginning to encode a lot of information in a property setting, so much so that you realize that really what you're doing is building up a rather complicated <tt>Object</tt>.  You feel like you've done this before.</blockquote>Or this one:<blockquote>You're working on a Swing application, and you need to validate the input from the user.  Great, you say, I'll use a <tt>JFormattedTextField</tt>, and then I'll...I'll...I'll...read the...documentation...which features lots of...hmm...factories...and <tt>AbstractFormatters</tt>...and still more formats and navigation thingees and...I think I'll go get some coffee.</blockquote>Or this one:<blockquote>You're halfway through developing a complicated and enterprisey validation framework and you stop abruptly, realizing that <i>there has to be a better way</i>!</blockquote>Starting with this blog entry I'd like to cover the many, many different ways to edit, format and build up different kinds of <tt>Object</tt>s that are provided by the Java platform.<br /><br />Why should you think about turning <tt>Object</tt>s into <tt>String</tt>s?  Or <tt>String</tt>s into <tt>Object</tt>s?  Or all the other ways that a user might send input to you?<br /><br />For me, the answer is that whether you're developing on the desktop or on the Web, you are constantly accepting free-form user input in the form of text.  In some cases, you have control over this text, and in other cases you do not, but in all cases you often need to turn that text into things like dates, colors, fonts, <tt>java.net.URI</tt>s, custom domain objects and the like.  Wouldn't it be nice to come up with a standard set of tools that would manage this kind of conversion for you in a pluggable manner?  Wouldn't it be even better if most of that heavy lifting were done for you by the base platform?  Well, it is.<br /><br />In this entry, I'll cover <tt>java.beans.PropertyEditor</tt>—at least I'll cover some of its features—and then will move onto other tools in subsequent entries.<h3>PropertyEditors</h3>The <tt>java.beans.PropertyEditor</tt> class is quite a powerful beast.  Despite the fact that it's heavily used by Spring, Geronimo, JBoss and doubtless a whole host of other reasonably popular open source products, it seems to get lost in the shuffle, and developers often don't know it exists.<br /><br />A <tt>PropertyEditor</tt> exists to edit Java bean properties.  Or at least that's what the documentation will tell you.  But explaining it this way often leads to questions about what a Java bean is, what a property is, oh, doesn't that mean getters and setters and whatnot—all of which is largely irrelevant for understanding what a <tt>PropertyEditor</tt> actually <i>does</i>.<br /><br />So, then: a <tt>PropertyEditor</tt> provides a consistent way for accepting user-supplied data and turning it into an object of a particular class.  For now, we'll look at just its text conversion utilities and leave its boatload of other features aside.<br /><br />Before we dive into the API, we should think about what we're trying to do.  So for this example, let's say that we're going to make a <tt>PropertyEditor</tt> that converts <tt>java.net.URI</tt> instances into <tt>String</tt>s and vice versa.  That is a trivial enough example that it should be easy to step through, and a useful enough one that you may find yourself using the resulting <tt>PropertyEditor</tt> in an actual project.<br /><br />To start developing a new <tt>PropertyEditor</tt>, it's most helpful to simply subclass <tt>java.beans.PropertyEditorSupport</tt>, so that's what we'll do here.  For reasons that will become clear later (hint: see the API documentation for <tt>java.beans.PropertyEditorManager</tt>), you should suffix your property editors with the word <tt>Editor</tt>.  Finally, the API documentation also says that all <tt>PropertyEditors</tt> must have a public, no-arg constructor:<blockquote><pre>public class URIEditor extends java.beans.PropertyEditorSupport {<br />  public URIEditor() {<br />    super();<br />  }<br />}</pre></blockquote>Next, let's focus on the text conversion methods:<blockquote><pre>public String getAsText();<br />public void setAsText(final String text) throws IllegalArgumentException;<br />public Object getValue();<br />public void setValue(final Object value);</pre></blockquote>Actually, before we get there, an overriding thing that is worth remembering is that a <tt>PropertyEditor</tt> is a stateful object.  Granted, if all is going as it should, the state doesn't stick around very long, and technically speaking doesn't even get released back into the wild, but it's there nonetheless.  That means the typical flow of using a <tt>PropertyEditor</tt> for conversion purposes is:<ul><li>Stick a value into the editor.</li><li>Ask the editor to get you its current value's <tt>String</tt> representation.</li></ul>Or, equivalently:<ul><li>Try to set some text into the editor.  If this call completes, the editor will have a value ready and waiting for you.</li><li>Get the value out of the editor that resulted from the conversion process.</li></ul>So back to the methods.  Let's start (as is always good) by implementing the <tt>setAsText()</tt> method first.  Then to be good and defensive and bulletproof, we'll beef up the <tt>getValue()</tt> and <tt>setValue()</tt> methods in a moment.<blockquote><pre>public void setAsText(final String text) {<br />  // 1<br />  if (text == null) {<br />    // null text means a null URI<br />    this.setValue(null);<br />  } else {<br />    // 2<br />    final String trimmedText = text.trim();<br />    assert trimmedText != null; // guaranteed by trim() method<br />    // 3<br />    if (trimmedText.length() &lt;= 0) {<br />      // Empty text means a null URI<br />      this.setValue(null);<br />    } else {<br />      // We have a non-null, non-zero-length String.  Let's attempt to turn it into a URI.<br />      try {<br />        // 4<br />        this.setValue(new URI(trimmedText));<br />      } catch (final URISyntaxException kaboom) {<br />        // 5<br />        throw (IllegalArgumentException)new IllegalArgumentException(text).initCause(kaboom);<br />      }<br />    }<br />  }<br />}</pre></blockquote>What's going on here?  Why is this so complicated?  Let's walk the interesting bits of the code.  The numbers in the list below should correspond to the numbers in the code above.<ol><li>I am a defensive programmer, so I tend to overdo this part (in some people's opinion).That is, I always check for <tt>null</tt>s, even in situations where it can be "guaranteed" that <tt>null</tt> will never be supplied or returned.  So here, I make the decision that if <tt>null</tt> is supplied to us, I will interpret that as someone wanting to clear out the value stored by this editor.  To do that, we simply set the value to <tt>null</tt>.</li><li>Here, you may do this step or not, depending on your requirements.  I trim the supplied text to eliminate leading and trailing whitespace.  The assertion step is entirely optional; I use it more for documentation than anything else.</li><li>Once the text is trimmed, I can make a quick call to get its length, and if the string is empty, then I interpret that to mean that the user is, again, trying to clear out the value.  So I set the value to <tt>null</tt>.  I suppose you could be draconian and attempt to construct a <tt>URI</tt> with an empty string, but I don't really see the point.</li><li>By the time we get here, we know we have a "full" <tt>String</tt> to work with.  <tt>PropertyEditors</tt> always have to return a copy of whatever value is set on them, but in the case of <tt>URI</tt>s, the URI itself is immutable, so when we call <tt>setValue</tt> here with a new <tt>URI</tt>, we will not have to do anything special in our <tt>getValue</tt> method later on to copy the installed value.  More on this later.</li><li>The only specification-compliant option you have for rejecting input is to throw an <tt>IllegalArgumentException</tt>.  So here we catch the <tt>URISyntaxException</tt>, and, using some rather weird syntax, wrap that <tt>URISyntaxException</tt> inside an <tt>IllegalArgumentException</tt>.  The <tt>initCause()</tt> call is needed to make this code compile under 1.4 environments.  As a convenience, I supply the bad text itself (untrimmed, unprocessed) in the <tt>IllegalArgumentException</tt>'s message.</li></ol>What's important about the thought process behind implementing this (very simple) method is, I think, the following:<ul><li>Handle all kinds of input.  If you do this up front, you won't be surprised later, and your code will perform gracefully under pressure.  Can you accept dirty input?  Null?  What happens if there is whitespace?  Can you trim some of it away?  Or does that disturb the semantics of your object-to-string conversion?  In the case of <tt>URI</tt>s, there's really no harm in trimming the whitespace fat.</li><li>Think about providing a way, using just text, to clear out a value.  Consider, also, when this might be a bad idea.  This <tt>PropertyEditor</tt> implementation lets you clear the value by calling <tt>setAsText</tt> with either "" or <tt>null</tt>.</li><li>Work within the specification as much as you possibly can.  Although of course you're free to throw all sorts of different kinds of <tt>RuntimeException</tt>s whenever you want in a vacuum, the <tt>PropertyEditor</tt> specification says that the only <tt>RuntimeException</tt> (really, the only kind of <tt>Exception</tt>, period) that callers will expect is an <tt>IllegalArgumentException</tt>.  So throw one of those when things go bad.  I always make the bad text be the message, because that will show up in a stack trace in various log files.  Also, callers of <tt>PropertyEditor</tt>s will almost always catch a simple plain-Jane <tt>IllegalArgumentExcepiton</tt>, and won't know how to access any other values about it other than its message and cause.</li></ul>The <tt>getAsText()</tt>  method is much simpler.  Its only responsibility is to return the text representation of the currently installed value.  But be careful (and now you'll understand why I went to great lengths to trim the text in the <tt>setAsText()</tt> method above), because the specification says that if you return <tt>null</tt> from this method it is to be interpreted to mean that your <tt>PropertyEditor</tt> is unable to perform the text conversion.  So here's our <tt>getAsText()</tt> method:<blockquote><pre>public String getAsText() {<br />  // 1<br />  final Object value = this.getValue();<br />  // 2<br />  if (value == null) {<br />    return "";<br />  }<br />  // 3<br />  return value.toString();<br />}</pre></blockquote>And here are the details:<ol><li>Although we know we're always going to be working with <tt>java.net.URIs</tt> here, we technically speaking don't care what kind of value was installed, because ultimately (see 4) we're just going to return its <tt>String</tt> representation.  So no cast needed here.</li><li>This is the only gotcha in the contract for this method.  The specification tells us indirectly that even when our installed value is <tt>null</tt> we must not return <tt>null</tt> from this method—unless we want to indicate that something broke in the conversion process, or that we simply don't support text conversion at all.  Instead, we choose here to return the empty string, which is a good value to use in text fields and form input fields.  And <i>that's</i> why we explicitly test for whitespace-only <tt>Strings</tt> in the <tt>setAsText()</tt> method, because of course the return value from the <tt>getAsText()</tt> method is often indirectly resupplied as the input to the <tt>setAsText</tt> method.</li><li>Finally, we defer to the <tt>URI#toString()</tt> method for the "real" <tt>String</tt> representation because it just so happens to have really well-defined semantics.  In more complicated cases, you may very well <i>not</i> want to defer to the <tt>toString()</tt> method.  Specifically, you need to have a guarantee if you <i>do</i> defer to the <tt>toString()</tt> method that it will <i>not</i> return <tt>null</tt>, because although that may be OK for <i>its</i> contract, it's not OK for the <tt>PropertyEditor#getAsText()</tt> contract.</li></ol>Lastly, we'll override the "value" methods just to make sure that they're nice and defensive and well-documented:<blockquote><pre>public Object getValue() {<br />  final Object uri = super.getValue();<br />  // 1<br />  assert uri == null || uri instanceof URI;<br />  return uri;<br />}<br /><br />public void setValue(final Object value) {<br />  // 2<br />  if (value == null || value instanceof URI) {<br />    super.setValue(value);<br />  }<br />}</pre></blockquote><ol><li>The first thing we do is to make sure that no matter what happens later on in this class' lifecycle—no matter who "maintains" it after us, no matter what overridden methods in no matter what subclasses get butchered, we are intending this class to handle only <tt>java.net.URI</tt> instances and nothing else (well, except for <tt>String</tt>s).</li><li>In the <tt>setValue()</tt> method, we have a dilemma.  The specification is silent about how a <tt>PropertyEditor</tt> is supposed to handle <tt>setValue()</tt> calls that it's not designed to handle.  Once again, you can choose to throw a <tt>RuntimeException</tt> of your own choosing—the compiler certainly won't stop you and you're fully within your rights—but the typical caller of a <tt>PropertyEditor</tt> (usually some bit of infrastructure code) is not expecting you to call down fire and brimstone from this method.  I tend to write my <tt>setValue()</tt> implementations to ignore invalid input.  I obviously log the problem in such cases, but omitted the logging code here as installing logging here would be over the top for this example.  Finally, recall that the <tt>instanceof</tt> operator will return <tt>false</tt> if <tt>null</tt> is its left-hand operand, so you have to explicitly check for that (in order to permit clearing out the installed value).</li></ol><h3>Callers</h3>For reasons that I'll cover in the next installment, callers will expect to call this <tt>PropertyEditor</tt> in a way that looks something like this:<blockquote><pre>final PropertyEditor pe = // Get an appropriate property editor<br />final String text = // Gather user text<br />if (pe != null) {<br />  try {<br />    pe.setAsText(text);<br />  } catch (final IllegalArgumentException badText) {<br />    // Aha; the user input must have been bad.<br />    handleErrorVisuallyOrOtherwise(badText);<br />    return;<br />  }<br />  final Object canonicalValue = pe.getValue();<br />  final String canonicalText = pe.getAsText();<br />  if (canonicalText == null) {<br />    // Ah; this must mean that this particular PropertyEditor can't represent the value.<br />    // I'd better do something more fancy.<br />    maybeCreateSomeKindOfImage(canonicalValue);<br />  }<br />}</pre></blockquote><h3>Observations and Summary</h3>So, then, for <tt>Object</tt>-to-<tt>String</tt> conversion using <tt>PropertyEditor</tt>s, keep the following things in mind:<ul><li>Subclass <tt>PropertyEditorSupport</tt>.</li><li>Accept lousy input in your <tt>setAsText()</tt> method.</li><li>Never return <tt>null</tt> from your <tt>getAsText()</tt> method.</li><li>Define a non-<tt>null</tt> <tt>String</tt> you're going to use to represent the <tt>null</tt> value.  Then make sure that your <tt>getAsText()</tt> method returns that to mean <tt>null</tt>, and that your <tt>setAsText()</tt> method is prepared to accept it to <i>mean</i> <tt>null</tt>.</li><li>Decide what to do when your <tt>setValue()</tt> method gets called with unexpected input.</li><li>Remember that you report invalid user text by throwing an <tt>IllegalArgumentException</tt> from your <tt>setAsText()</tt> method, and that's the only thing your callers are going to be prepared for.</li></ul>If you build <tt>PropertyEditors</tt> bearing all these points in mind, then you will have a stable foundation for standardized <tt>Object</tt>-to-<tt>String</tt> conversion with well-defined semantics.  We'll see in the next installment how to make all of Java's other <tt>Object</tt>-converting tools expressible in terms of <tt>PropertyEditor</tt>s.  That, in turn, will let you define all your conversion logic in one place.<br /><br />In the next article, I'll cover <tt>java.text.Format</tt>, and will put togther a <tt>Format</tt> implementation that delegates to an underlying <tt>PropertyEditor</tt>.  See you then.<br /><br /><p class="poweredbyperformancing">Powered by <a href="http://scribefire.com/">ScribeFire</a>.</p>]]>

</content>
</entry>
<entry>
<title>Anemic vs. Obese Domain Objects</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/ljnelson/archive/2006/07/anemic_vs_obese.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2006-07-11T17:34:07Z</issued>
<id>tag:weblogs.java.net,2006:/blog/ljnelson/175.3786</id>
<created>2006-07-11T17:34:07Z</created>
<summary type="text/plain">In which we discuss the design of a good domain object.</summary>
<author>
<name>ljnelson</name>

<email>ljnelson@gmail.com</email>
</author>
<dc:subject>Patterns</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/ljnelson/">
<![CDATA[<p>Child number two has kept me away from the blogosphere.  As I write this, se&ntilde;or Nelson Jr. is busily learning how to access and destroy objects.  Next up: garbage collection.</p>

<p>I found <a href="http://jroller.com/page/coderant?entry=anemic_vs_obese_domain_objects">this article</a> on <a href="http://www.javablogs.com/">JavaBlogs</a> the other morning and while technically speaking it's an old topic, it seems one that none of us ever tire of talking about.  If you tire of talking about it, then you'll probably want to move on to another blog right about now.</p>

<p>Briefly summarized, the article points out that many domain objects are beefed up incorrectly in order to ostensibly avoid <a href="http://www.martinfowler.com/bliki/AnemicDomainModel.html">certain pejorative labels coined by certain well-known prolific industry visionaries</a>.  Specifically, the beef often takes the form of data access methods which, as the poster wonders out loud, are usually supposed to be whisked off to some <a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html">data access object</a>, are they not?  So if you move them, what are you left with?  The article examines a few cases of what he considers business methods, explores some of their wrinkles and ends, rather appropriately, in my opinion, with a semi-frustrated open-ended question:<blockquote>Aren't domain objects with persistence logic just really Enity [sic] Beans? Didn't we agree Entity Beans are bad? Let's keep the persistence out of the domain object and in the Dao where it belongs.</blockquote></p>

<p>I think this article raises a point that we all think about when setting out to design a class library or model a domain: what <i>is</i> the behavior, anyway?  Most modeling and design exercises I've been involved with typically start with the structure.  Members of the design or development team sit around and name domain objects and their attributes following good object-oriented practice.  Deep thought ensues.  More attributes are added, some are taken away.  Classes are refactored.  At the end of the day you have a glorified entity-relationship diagram, redubbed a class diagram, or, to use Fowler's term, a pile of anemic domain objects.  Then the team sprinkles behavior over the objects, and, just as CodeMonkey indicates, more often than not it is simply pick-it-up-put-it-down logic: <tt>Account.findByDate()</tt>, <tt>Order.update()</tt>, etc.</p>

<p>I used to think that getting the structure right was critically important.  Think deeply about your objects, make sure they have all the attributes they're going to need, move things around in the class hierarchy appropriately to reduce duplication, and there, you have your structure onto which you can drape the domain's behavior logic.  Now I think this is wrongheaded (to paint it in overly black-and-white terms), and I have found that examining the behavior is a much better way to arrive at the structure.  If you do this, the business logic falls out naturally.</p>

<p>To start with, think about some obvious but often neglected questions: for any given object with a proposed attribute <i>x</i>, why must that object have attribute <i>x</i>?  What little-"p" process needs that <i>x</i>?  Why, really, do I have to know an order's creation date?  Why do I need to know a student's age?</p>

<p>I've found that the answers take one of three rough forms:
<ol>
<li>Because someone somewhere is going to want to build some sort of general-purpose query that will involve <i>x</i>.  We can't even begin to predict what this query will be.</li>
<li>Because we need to make this attribute available for reports that we send to An Important Organization, Standards Body or Governmental Agency.  Who knows why; that's just what we do.</li>
<li>Because there is a business rule that dictates that things with an <i>x</i> in some range or meeting some criterion need to get flagged in a particular way, or exported, or associated with some other kind of thing.</li>
</ol></p>
<p>The first item is probably the only case where you really simply have to expose your object's attributes via public getters and setters Because They Simply Have To Be There.  I've also found that it's pretty rare.  And finally, it also follows from this that it doesn't really matter whether your domain object has an <i>x</i>, because it might as well have a <i>y</i>, or a <i>z</i>, or forty three other attributes.  The point is if an attribute is exposed simply for dynamic query purposes, then it hardly matters what that attribute is for, since your program isn't going to do anything with it other than show it to the person who constructed the query in the first place.  So if you're designing with interfaces, keep these types of getters and setters out of your interface and put them in the underlying implementation.</p>

<p>The second item is fairly common.  In higher education, which is the domain in which I currently find myself, the government has an interest in various kinds of data and reports that, to my eyes, consist of various combinations of obscure, unpronounceable "codes".  Your first inclination would be to stop there (well, mine is): OK, the government says we need to provide a <a href="http://nces.ed.gov/pubs2002/cip2000/">CIP code</a>, so we'd better have a <tt>getCIPCode()</tt> method on our <tt>Program</tt> object.  But stop there, and ask again: why do we need this?  Maybe the correct method is, instead, <tt>provideGovernmentMandatedData()</tt>, or maybe the solution is to move these kinds of obscure, for-reports-only attributes into an outboard descriptor object, e.g. <tt>CipCodes.getFor(program)</tt>.</p>

<p>The remaining item above is the killer.  Suppose you intuitively know your <tt>Student</tt> object has to have an <tt>age</tt> attribute.  Why?  What's it used for?  Why do you need to know how old a student is?  In a lot of scenarios, the checking of an attribute is really something else in disguise.  The business rule, in other words, may be if the student does not meet state requirements for taking a class, then reject him.  If that really <i>is</i> the business rule, then you don't really need an age accessor at all; just a <tt>meetsStateRequirementsForTakingAClass()</tt> method.</p>

<p>In practice, of course, returning to planet Earth, you end up having domain objects that have a mix of getters and setters and more object-oriented business methods.  But I've found that arriving at these methods by way of thinking about the processes that are going to need them tends to result in cleaner, less-coupled objects than the alternative approaches that I've tried.</p>

<p>Thanks for reading.</p>]]>

</content>
</entry>
<entry>
<title>Of Detachable Root Panes and Desktop Hopping</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/ljnelson/archive/2005/06/of_detachable_r.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-06-21T00:06:09Z</issued>
<id>tag:weblogs.java.net,2005:/blog/ljnelson/175.2528</id>
<created>2005-06-21T00:06:09Z</created>
<summary type="text/plain">How to build a desktop-hopping JRootPane subclass.</summary>
<author>
<name>ljnelson</name>

<email>ljnelson@gmail.com</email>
</author>
<dc:subject>Swing</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/ljnelson/">
<![CDATA[<p>Long, long, <i>long</i> time no post.  A job change and a two-year-old will do that to
you.</p>

<p>On today's menu: how to make a <tt>JRootPane</tt> subclass that can pop
itself in and out of <tt>JInternalFrame</tt>s and <tt>JFrame</tt>s.  Let's dive right in.</p>

<h2>Background</h2>

<p>Different people have different ideas on how an application should work when
it can open many different documents of many different types at the same time,
and, most importantly, when its value derives from being able to see those
documents side-by-side (ruling out, for example, a <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTabbedPane.html"><tt>JTabbedPane</tt></a>-based
interface).  Some like a true, old-school <a
href="http://en.wikipedia.org/wiki/Multiple_document_interface">MDI</a> feel;
others like there to be multiple external windows, &agrave; la Microsoft Word.
My current project's customers are evenly divided on the subject.</p>

<p>To make everyone happy, I decided to start with a <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JDesktopPane.html"><tt>JDesktopPane</tt></a>-based
MDI core.  Then I added the ability to detach the <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JInternalFrame.html"><tt>JInternalFrame</tt></a>s
from the desktop pane and open them up as external windows&mdash;i.e. to make the window hop off the <i>application</i> desktop and onto the <i>user</i> desktop (and, potentially, back again).  This comparatively
small insight has led to a surprisingly intuitive way of managing the
application's information.  When you just want to look at one thing and have it
be your central focus, it is easier to have it be in an external window.  On the
other hand, when you want to look at two things side by side, it seems easier to
grasp their relationship to each other and to their containing application if
they're presented inside an MDI.</p>

<h2>The Code</h2>

<p>The final code is available <a
href="http://weblogs.java.net/blog/ljnelson/archive/code/ellington/DetachableRootPane.java">here</a>
under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT
license</a>; my ramblings below detail how I designed it.</p>

<h2>The Gory Details</h2>

<p>Since both a <tt>JInternalFrame</tt> and a <tt>JFrame</tt> are <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/RootPaneContainer.html"><tt>RootPaneContainer</tt></a>s,
I focused on the <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JRootPane.html"><tt>JRootPane</tt></a>
class.  If there were some way to pop instances of this class out of one kind of
window and into another kind&mdash;preferably via the usual <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/ActionMap.html"><tt>ActionMap</tt></a>
machinery&mdash;I'd be in business.</p>

<p>If you look at the APIs for <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JFrame.html"><tt>JFrame</tt></a>
and <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JInternalFrame.html"><tt>JInternalFrame</tt></a>,
you can see that there is not a publicly accessible way to do this.  In general,
this is a good thing&mdash;how many times (other than this one!) do you ever
even think about the root pane let alone want to remove it or set a new one?
While there is a public <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/RootPaneContainer.html#getRootPane()">method
for retrieving the root pane</a> on both the <tt>JFrame</tt> and
<tt>JInternalFrame</tt> classes, there is no such public setter method.  So I
knew that overriding <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JRootPane.html"><tt>JRootPane</tt></a>
would be in order.  I called my <tt>JRootPane</tt> subclass
<tt>DetachableRootPane</tt>.</p>

<h3>Implementing the <tt>detach()</tt> method</h3>

<p>Next, I focused on what would become this subclass' <tt>detach()</tt> method.  What
would the state of this root pane be at the moment of detaching?  What aspects
of that state would be worth preserving, and what aspects would be worth
throwing away?</p>

<p>This turned out to be a bit of a thorny problem.  If a
<tt>JInternalFrame</tt> is maximized, and then detached, should the resulting
<tt>JFrame</tt> be maximized?  Or should it be the same size on screen as the
maximized <tt>JInternalFrame</tt> it "came from"?  If the
<tt>JInternalFrame</tt> were <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JInternalFrame.html#setResizable(boolean)">not
resizable</a>, then should the resulting <tt>JFrame</tt> <i>also</i> not be
resizable?  What about minimized <tt>JInternalFrame</tt>s?  Should they be
detachable at all?</p>

<p>Anyhow, at this stage in design I didn't focus too much on the answers to
these questions, but more on the fact that moving a <tt>DetachableRootPane</tt>
from a <tt>JInternalFrame</tt> to a <tt>JFrame</tt> and back again would require
certain elements of state to be carried through the detaching process.  The
easiest thing to do, I figured, was to store this state using the normal <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JComponent.html#getClientProperty(java.lang.Object)">client
property</a> mechanics.</p>

<h3>Pass 1: Get the Basics Working</h3>

<p>So, the <tt>detach()</tt> method began taking shape.  Here's more or less
what it looked like at this stage in the design, where I was focusing on the
going-from-a-<tt>JInternalFrame</tt>-to-a-<tt>JFrame</tt> detaching 
process.  Note that the code below is intended to represent where I was in the
design process at the time; as such, it may not be correct or complete:<pre>public void detach() {
  final Component parent = this.getParent();
  if (parent instanceof JInternalFrame) {
    // Leaving JInternalFrame; going into JFrame
    final JInternalFrame internalFrame = (JInternalFrame)parent;

    // Grab the JDesktopPane and stash it away because if we "go back" we need
    // to tell it to add() whatever JInternalFrame we "go back" to.  Note that if
    // abused, this could be the source of a memory leak.  There's probably 
    // a way to make this more robust.  In short, don't abuse it.
    final JDesktopPane pane = internalFrame.getDesktopPane();
    if (pane != null) {
      pane.remove(internalFrame);
      this.putClientProperty("desktop", pane);
    }
    
    // Store some state about the JInternalFrame we're "leaving" so that if we 
    // "come back" we can set up the new JInternalFrame just like the old one.
    // Resizability is tricky and isn't yet handled; more on this later.
    this.putClientProperty(INTERNAL_FRAME_CLOSABLE, Boolean.valueOf(internalFrame.isClosable()));
    this.putClientProperty(INTERNAL_FRAME_MAXIMIZABLE, Boolean.valueOf(internalFrame.isMaximizable()));
    this.putClientProperty(INTERNAL_FRAME_ICONIFIABLE, Boolean.valueOf(internalFrame.isIconifiable()));

    internalFrame.setVisible(false);

    // Create the new JFrame we're going to detach "into".
    final JFrame frame = new JFrame(internalFrame.getTitle()) {
      protected final void frameInit() {
        super.frameInit();
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        this.addWindowListener(new WindowAdapter() {
          public final void windowClosing(final WindowEvent event) {
            // Make it so that closing the external window causes us to "go
            // back into" a JInternalFrame.
            detach();
          }
        });
      }
      protected final JRootPane createRootPane() {
        return DetachableRootPane.this;
      }
    };

    // More on this later; we actually want to set bounds explicitly, but at
    // this stage in the design we'll punt.
    frame.pack();
    frame.setVisible(true);

  } else if (parent instanceof JFrame) {
    // Leaving JFrame; going into JInternalFrame
  }
}</pre></p>

<p>At this stage, I had a <tt>DetachableRootPane</tt> that was capable of
popping out of a <tt>JInternalFrame</tt> into a <tt>JFrame</tt> if its
<tt>detach()</tt> method were ever called.  The details to be worked out were:
<ul>
<li>Going the other way, i.e. detaching from a <tt>JFrame</tt> "into" a
<tt>JInternalFrame</tt></li>
<li>Setting the bounds properly so that the <tt>JFrame</tt> would
appear to simply "drop into" the <tt>JDesktopPane</tt> as a
<tt>JInternalFrame</tt>, and so that the <tt>JInternalFrame</tt> would appear to
"pop off" the application desktop and onto the user's desktop</li>
<li>Miscellaneous state-related tracking behavior, like making sure that we
monitor a <tt>JInternalFrame</tt>'s resizability so that we know how to create a
new one that looks just like it</li>
</ul></p>

<h3>Pass 2: Make Detaching Work Both Ways</h3>

<p>The first thing I did was to make it so that the <tt>DetachableRootPane</tt>
could go the other way.  Here is the section of code from the <tt>detach()</tt>
method that dealt with this issue.  Again this is supposed to illustrate the
design process more than it is supposed to be compilable, correct code:<pre>    } else if (parent instanceof JFrame) {
    // Leaving JFrame; going into JInternalFrame
    final JFrame frame = (JFrame)parent;

    // See if someone (usually us) has put a JDesktopPane into our client
    // property map.  If so, then we have the required parent component to add a
    // new JInternalFrame to.  If not, well, then we're up a creek, but handle
    // that gracefully too.
    final JDesktopPane pane = (JDesktopPane)this.getClientProperty("desktop");

    final String title = frame.getTitle();

    frame.dispose();

    if (pane != null) {
      // There is indeed a JDesktopPane to add a new JInternalFrame to, so do
      // it.

      final JInternalFrame internalFrame = 
        new JInternalFrame(title,
                           true, // punt on resizability for now
                           ((Boolean)this.getClientProperty(INTERNAL_FRAME_CLOSABLE)).booleanValue(),
                           ((Boolean)this.getClientProperty(INTERNAL_FRAME_MAXIMIZABLE)).booleanValue(),
                           ((Boolean)this.getClientProperty(INTERNAL_FRAME_ICONIFIABLE)).booleanValue()) {
          protected final JRootPane createRootPane() {
            return DetachableRootPane.this;
          }
        };
      pane.add(internalFrame);

      // TODO: we'll worry about bounds in our next pass
      internalFrame.pack();

      internalFrame.setVisible(true);
    } // end of if block
  } // end of method</pre></p>

<h3>Brief Interlude: Pull In the <tt>ActionMap</tt></h3>

<p>At this stage in the process, I had a <tt>DetachableRootPane</tt> that could
quite comfortably spawn <tt>JFrame</tt>s and <tt>JInternalFrame</tt>s and hop in
and out of them at will, provided that the <tt>detach()</tt> method could
actually be invoked.  I also had a test rig that was simply calling the
<tt>detach()</tt> method on a timer.  This was proving to be really annoying now
that the basic functionality was there.  So instead of diving into cleaning up
the details, I decided to work on the <tt>ActionMap</tt>- and
<tt>InputMap</tt>-related code.  So, in the constructor for
<tt>DetachableRootPane</tt> I did this:<pre>public DetachableRootPane() {
  super();
  final ActionMap actionMap = this.getActionMap();
  assert actionMap != null;
  actionMap.put("detach", new AbstractAction("Detach") {
      public final void actionPerformed(final ActionEvent event) {
        detach();
      }
    });
  final InputMap inputMap = this.getInputMap();
  assert inputMap != null;
  inputMap.put(KeyStroke.getKeyStroke("F2"), "detach");
}</pre></p>

<p>Now when I pressed <tt>F2</tt> on either a <tt>JInternalFrame</tt> or a
<tt>JFrame</tt> (provided, of course, its root pane was an instance of
<tt>DetachableRootPane</tt>), the frame would detach appropriately and move from
one desktop to the other.</p>

<h3>Pass 3: Get the Bounds Working</h3>

<p>Finally it was time to go back and worry about the bounds.</p>

<p>Going from a <tt>JInternalFrame</tt> in a <tt>JDesktopPane</tt> to the screen
was easy enough.  All I had to do was call the <a
href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Component.html#getLocationOnScreen()"><tt>getLocationOnScreen()</tt></a>
method on the "outgoing" <tt>JInternalFrame</tt> and set the bounds of the new
<tt>JFrame</tt> accordingly.  That part of the detach method now looked (in
part) like this:<pre>
      // internalFrame is the JInternalFrame that this DetachableRootPane is
      // "leaving".  Grab its *screen* location and set the bounds of the new
      // JFrame to those bounds.  The effect is of a seamless detaching from the
      // JDesktopPane.
      final Point point = internalFrame.getLocationOnScreen();
      assert point != null;
      bounds.x = point.x;
      bounds.y = point.y;

      // ...other code; see above in this weblog post...

      frame.setBounds(bounds);
</pre></p>

<p>Going the other way was more complicated and required me to wrap my head
around some of the more arcane-looking methods in <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/SwingUtilities.html"><tt>SwingUtilities</tt></a>.
What I wanted to have happen was if someone closed the <tt>JFrame</tt> I wanted
its new <tt>JInternalFrame</tt> to appear in the <tt>JDesktopPane</tt> at
exactly the location "underneath" the <tt>JFrame</tt> that had just been
closed.  After mucking around, I uncovered the <a
href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/SwingUtilities.html#convertPointFromScreen(java.awt.Point,%20java.awt.Component)"><tt>convertPointFromScreen()</tt></a>
method.  The general approach, then, was to grab the screen location of the
"outgoing" <tt>JFrame</tt> and convert it to the <tt>JDesktopPane</tt>'s
coordinate space.  That part of the <tt>detach()</tt> method looked like
this:<pre>
      // ...other code...

      final Rectangle bounds = frame.getBounds();
      frame.dispose();
      if (pane != null) {
        final JInternalFrame internalFrame = 
          new JInternalFrame(title,
                             true, // punt on resizability for now
                             ((Boolean)this.getClientProperty(INTERNAL_FRAME_CLOSABLE)).booleanValue(),
                             ((Boolean)this.getClientProperty(INTERNAL_FRAME_MAXIMIZABLE)).booleanValue(),
                             ((Boolean)this.getClientProperty(INTERNAL_FRAME_ICONIFIABLE)).booleanValue()) {
            protected final JRootPane createRootPane() {
              return DetachableRootPane.this;
            }
          };
        pane.add(internalFrame);
        final Point point = new Point(bounds.x, bounds.y);
        <b>SwingUtilities.convertPointFromScreen(point, pane);
        bounds.x = point.x;
        bounds.y = point.y;
        internalFrame.setBounds(bounds);</b>
        internalFrame.setVisible(true);
</pre></p>

<h3>Pass 4: Cleaning Up and Putting It All Together</h3>

<p>This looked pretty good.  <tt>F2</tt> on a <tt>JInternalFrame</tt> caused the
frame to pop off onto the user's desktop as a <tt>JFrame</tt> at exactly its
previous location on screen.  <tt>F2</tt> again caused that same <tt>JFrame</tt>
to sink down onto the <tt>JDesktopPane</tt> wherever it happened to be.</p>

<p>The last bit of work to do involved the resizability of the original
<tt>JInternalFrame</tt>.  It turns out that when a <tt>JInternalFrame</tt> is
maximized, it effectively sets its <tt>resizable</tt> property to
<tt>false</tt>.  This is a bug, because of course there are two semantic
properties at work here: the <i>current</i> resizability of the
<tt>JInternalFrame</tt>, and the <i>structural</i> resizability of the
<tt>JInternalFrame</tt>.  It is true that when a frame of any kind is maximized,
typically you can't resize it, but that says nothing about whether it's
resizable once it has returned to its normal bounds.  To put it in terms of this
project, I wanted to monitor the structural resizability of the
<tt>JInternalFrame</tt> and monitor it for any change; that way I could store
that property's value accurately in my <tt>DetachableRootPane</tt> for use
later&mdash;e.g. if the <tt>DetachableRootPane</tt> detaches into a
<tt>JFrame</tt> and back, when it comes back we want to make sure that the
<tt>JInternalFrame</tt> it comes back into is indistinguishable from the
<tt>JInternalFrame</tt> it left.</p>

<p>This, fortunately, sounds like a simple job for a <a
href="http://java.sun.com/j2se/1.4.2/docs/api/java/beans/PropertyChangeListener.html"><tt>PropertyChangeListener</tt></a>.
The extra wrinkle is that we want to manage the <tt>PropertyChangeListener</tt>
in the <tt>DetachableRootPane</tt>, but install it on the
<tt>DetachableRootPane</tt>'s parent.  Because the parent has to be present for
this to work, we can't do the installation work in the
<tt>DetachableRootPane</tt> constructor; we have to do it in the <a
href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Component.html#addNotify()"><tt>addNotify()</tt></a>
method instead.  This means we have to be careful to also remove it in the <a
href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Component.html#removeNotify()"><tt>removeNotify()</tt></a>
method:
<pre>
  private boolean parentIsResizable;
  private PropertyChangeListener pcl;

  public void addNotify() {
    super.addNotify();
    final Container parent = this.getParent();
    boolean addPropertyChangeListener = true;
    if (parent instanceof JInternalFrame) {
      final JInternalFrame parentFrame = (JInternalFrame)parent;
      this.parentIsResizable = parentFrame.isResizable();
    } else if (parent instanceof JFrame) {
      final JFrame parentFrame = (JFrame)parent;
      this.parentIsResizable = parentFrame.isResizable();
    } else {
      addPropertyChangeListener = false;
    }
    if (addPropertyChangeListener) {
      this.pcl = new PropertyChangeListener() {
          public final void propertyChange(final PropertyChangeEvent event) {
            if (event != null && "resizable".equals(event.getPropertyName())) {
              final Boolean value = (Boolean)event.getNewValue();
              parentIsResizable = value != null && value.booleanValue();
            }
          }
        };
      parent.addPropertyChangeListener("resizable", this.pcl);
    }
  }

  public void removeNotify() {
    if (this.pcl != null) {
      final Container parent = this.getParent();
      assert parent != null;
      parent.removePropertyChangeListener("resizable", this.pcl);
    }
    super.removeNotify();
  }
</pre></p>

<p>Then I went back and amended the parts of my <tt>detach()</tt> method that
"punted" on resizability to take into account the real value of the property:
<pre>
        if (parent instanceof JInternalFrame) {
          // ...other code...
          this.putClientProperty(INTERNAL_FRAME_RESIZABLE, new Boolean(this.parentIsResizable));
          // ...other code...
        } else if (parent instanceof JFrame) {
          // ...other code...
          final JInternalFrame internalFrame =
            new JInternalFrame(title,
                               ((Boolean)this.getClientProperty(INTERNAL_FRAME_RESIZABLE)).booleanValue(),
                               //...
        }
</pre></p>

<p>Finally, as my last bit of cleanup, I added a few <tt>static</tt> methods for
creating both <tt>JFrame</tt>s and <tt>JInternalFrame</tt>s with their root
panes set to an instance of <tt>DetachableRootPane</tt>.  Here's one example:
<pre>
  public static JInternalFrame createJInternalFrame(final String title, final boolean resizable, final boolean closable, final boolean maximizable, final boolean iconifiable) {
    return new JInternalFrame(title, resizable, closable, maximizable, iconifiable) {
        protected final JRootPane createRootPane() {
          return new DetachableRootPane();
        }
      };
  }
</pre></p>

<h2>The Wrapup</h2>

<p>This was a fun exercise, largely because it was well-bounded, solved a real
UI problem, and is really quite reusable in the large.  My respect for the Swing
architects who carefully allowed me to get this much rope has just gone up
another notch.</p>

<p>Thanks for reading, and I'll see you at JavaOne.</p>]]>

</content>
</entry>
<entry>
<title>Cheap Hack I: rename your jar file, get a different Main-Class</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/ljnelson/archive/2004/09/cheap_hack_i_re.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2004-09-20T20:09:45Z</issued>
<id>tag:weblogs.java.net,2004:/blog/ljnelson/175.238</id>
<created>2004-09-20T20:09:45Z</created>
<summary type="text/plain">How to get a different Main-Class for your jar file based off the jar file&apos;s name.</summary>
<author>
<name>ljnelson</name>

<email>ljnelson@gmail.com</email>
</author>
<dc:subject>J2SE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/ljnelson/">
<![CDATA[<p>Here's a fun hack.</p>

<p>I (like everyone else in the world) have a collection of utilities I take
with me from job to job.  It's served me well for several years now.  These
utilities are simple, domain-independent things: classes to copy files, find out
what jar file a class is loading from, that sort of thing.</p>

<p>Many of the classes in this utility collection jar have <code>main()</code>
methods, and could conceivably serve as the <a href="http://java.sun.com/j2se/1.3//docs/guide/jar/jar.html#Main%20Attributes"><code>Main-Class</code></a> in an
executable jar somewhere.  But I don't want to get into the business of
fragmenting my utility jar.  What to do?</p>

<p>Feeling hackish, I put together a class that itself is installed as the
<code>Main-Class</code> in a jar file, but which consults a file (also in the
jar) to let it know what class to <i>actually</i> use as the main class.  The
hackish part is that all you have to do is rename the jar file for the "right"
<code>Main-Class</code> to be selected.  Here's the (quick, dirty, uncommented)
code:

<blockquote><pre>import java.io.InputStream;
import java.io.IOException;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import java.net.URL;

import java.util.Properties;

public final class Main {

  private Main() {
    super();
  }

  public static final void main(final String[] args) throws Throwable {
    final URL location;
    final String classLocation = Main.class.getName().replace('.', '/') + ".class";
    final ClassLoader loader = Main.class.getClassLoader();
    if (loader == null) {
      location = ClassLoader.getSystemResource(classLocation);
    } else {
      location = loader.getResource(classLocation);
    }
    String token = null;
    if (location != null && "jar".equals(location.getProtocol())) {
      String urlString = location.toString();
      if (urlString != null) {
        final int lastBangIndex = urlString.lastIndexOf("!");
        if (lastBangIndex >= 0) {
          urlString = urlString.substring("jar:".length(), lastBangIndex);
          if (urlString != null) {
            final int lastSlashIndex = urlString.lastIndexOf("/");
            if (lastSlashIndex >= 0) {
              token = urlString.substring(lastSlashIndex + 1);
            }
          }
        }
      }
    }
    if (token != null) {
      InputStream stream = null;
      try {
        if (loader == null) {
          stream = ClassLoader.getSystemResourceAsStream("mainClasses");
        } else {
          stream = loader.getResourceAsStream("mainClasses");
        }
        if (stream != null) {
          final Properties properties = new Properties(System.getProperties());
          properties.load(stream);
          final String mainClassName = properties.getProperty(token + ".main.class");
          if (mainClassName != null) {
            final Class mainClass = Class.forName(mainClassName);
            if (mainClass != null) {
              final Method mainMethod = mainClass.getDeclaredMethod("main", new Class[] { args.getClass() });
              if (mainMethod != null && Void.TYPE.equals(mainMethod.getReturnType())) {
                final int modifiers = mainMethod.getModifiers();
                if (Modifier.isPublic(modifiers) &&
                    Modifier.isStatic(modifiers)) {
                  try {
                    mainMethod.invoke(null, new Object[] { args });
                  } catch (final InvocationTargetException kaboom) {
                    throw kaboom.getTargetException();
                  }
                }
              }
            }
          }
        }
      } finally {
        if (stream != null) {
          try {
            stream.close();
          } catch (final IOException ignore) {
            // ignore
          }
        }
      }
    }
  }

}</pre></blockquote>

</p>

<p>There are two interesting bits to this.  The first is the way that a class'
location is returned as a <code>URL</code>.  Suppose you have a class,
<code>com.foo.bar.Baz</code>.  And suppose that class is present in a jar file
whose (Windows, let's say) path is <code>C:\x\y\z.jar</code>.  Then if you say:

<blockquote><pre>URL url =
classLoader.getResource("com/foo/bar/Baz.class");</pre></blockquote>

...the URL you'll get back is:

<blockquote><pre>jar:file:C:/x/y/z.jar!/com/foo/bar/Baz.class</pre></blockquote>

This format, which is documented <a
href="http://java.sun.com/j2se/1.3.1/docs/api/java/net/JarURLConnection.html">as
part of the <code>java.net.JarURLConnection</code> class</a>, is remarkably
useful.  The URL format, as you can see, gives you both the directory structure
of the jar file itself, as well as the location of the jar file.  In the code
above, we use this URL format to figure out what the <i>un</i>qualified name of
the jar file is--the "basename":

<blockquote><pre>String urlString = location.toString();
if (urlString != null) {
  final int lastBangIndex = urlString.lastIndexOf("!");
  if (lastBangIndex >= 0) {
    urlString = urlString.substring("jar:".length(), lastBangIndex);
    if (urlString != null) {
      final int lastSlashIndex = urlString.lastIndexOf("/");
      if (lastSlashIndex >= 0) {
        token = urlString.substring(lastSlashIndex + 1);
      }
    }
  }
}</pre></blockquote>

Here we simply lop off everything from the "<code>jar:</code>" part up to and
including the last slash (well, the last slash before the "<code>!</code>"
delimiter).  Then we lop off everything from (and including) the
"<code>!</code>" delimiter to give us the "basename" of the jar file, which, in
our contrived example, would simply be <code>z.jar</code>.</p>

<p>Armed with that as a key, we now go looking for a well-known file inside the
jar.  I simply called it "<code>mainClasses</code>".  It is a simple
<code>Properties</code> dump, and is accessible via the usual
<code>getResourceAsStream()</code> machinery:

<blockquote><pre>stream =
loader.getResourceAsStream("mainClasses");</pre></blockquote>

(If you want to be really careful, you would actually open the jar file yourself
and extract this entry from it.  The problem with the way we've done it here is
that if there is any file in the classpath named <code>mainClasses</code> that
appears before the jar file in question, it will be selected instead.)</p>

<p>If we found it, we load a new <code>Properties</code> object from it, where,
hopefully, the keys are jar "basenames", and the values are fully qualified
names of classes, each of which will serve as that jar file's
<code>Main-Class</code>.  Here's an example of the contents of that file:

<blockquote><pre>z.jar: com.foo.bar.Xyzzy
q.jar: com.foo.bar.Frobnicator</pre></blockquote>

This file indicates that if the jar is named <code>z.jar</code>, then its main
class will be <code>com.foo.bar.Xyzzy</code>.  If, on the other hand, the jar is
named <code>q.jar</code>, then its main class will be
<code>com.foo.bar.Frobnicator</code>.</p>

<p>The rest of the code is simply the process of loading the correct class via
reflection and seeing if it has a <code>public static void main(String[])</code>
method on it.  Note that the only kind of <code>Exception</code> we explicitly
catch is <code>InvocationTargetException</code> so that if something goes wrong
in the delegate main class, it will look (as much as possible) as though that
class were directly invoked.</p>

<p>Obviously this dirty little hack will only scratch an itch if it makes sense
to copy the jar file to multiple places with different names.  In my case it
does, because my utility jar file is very small.</p>]]>

</content>
</entry>
<entry>
<title>Seventeenth century object design</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/ljnelson/archive/2004/09/seventeenth_cen.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2004-09-02T16:10:31Z</issued>
<id>tag:weblogs.java.net,2004:/blog/ljnelson/175.1019</id>
<created>2004-09-02T16:10:31Z</created>
<summary type="text/plain">John Locke on designing reusable objects.</summary>
<author>
<name>ljnelson</name>

<email>ljnelson@gmail.com</email>
</author>
<dc:subject>Programming</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/ljnelson/">
<![CDATA[<p>Hello, first of all.  It's an honor to be part of the <a href="http://weblogs.java.net/">java.net weblogging community</a>.</p>

<p>A <a href="http://weblogs.java.net/pub/wlg/1789">discussion concerning component
reuse</a> brought me back to my philosophy major days in college.  Who knew
British empiricism could help you with object design?</p>

<p>The discussion was (is) about, loosely, how best to design an object or a
component for reuse.  You want to get the hypothetical object down to what's
important across domains, to trim away the fat, but, as a competing concern, to
make it rich enough that people won't have to reinvent the wheel.  Slimming down
your object also provides incentive for someone else to use it, provided you
don't slim it down so far that it's impractical.</p>

<p>What is this "fat" we're talking about?  In general, it's concerns or aspects
or facets of the real-world thing that our object is modeling.  There are many
facets about a hypothetical and reusable <code>Person</code> object (and the set
of all persons that it models), for example, that could be included, ranging
from names to measurements to relationships with others.  Which of these groups
of attributes is necessary for a <code>Person</code> to be a
<code>Person</code>?  Which is superfluous?  What is the <code>Person</code>
apart from these groups of attributes?</p>

<p><a href="http://plato.stanford.edu/entries/locke/">John Locke</a> examined
these issues in <a
href="http://www.gutenberg.net/dirs/1/0/6/1/10615/10615.txt"><i>An Essay
Concerning Human Understanding</i></a>.  Ruthlessly paraphrased, and butchered
somewhat for this weblog's purposes, he argues that when you hear someone
mention a person, you frame a "complication or collection" of "simple ideas" in
your mind that "go constantly together", such as height, weight, general shape,
etc.  In Locke's view we humans in the normal unexamined course of our lives
don't imagine these ideas simply existing on their own, so we subconsciously
posit the existence of a "substratum" that they bind to, although strictly
speaking we never entirely know what we're talking about.  Locke calls this
substratum <i>substance</i>, and, believe it or not, it's one way of thinking
about object reuse, whether it exists or not.</p>

<p>A couple of choice quotes from Locke on this whole subject:

<blockquote> If any one should be asked, what is the subject wherein colour or
weight inheres, he would have nothing to say, but the solid extended parts; and
if he were demanded, what is it that solidity and extension adhere in, he
would...  [answer] SOMETHING, HE KNEW NOT WHAT.</blockquote>

<blockquote>...[O]ur...ideas of substances...have always the confused idea of
something to which they belong...and therefore when we speak of any sort of
substance, we say it is a thing having such or such qualities; as body is a
thing that is extended, figured, and capable of motion; spirit, a thing capable
of thinking; and so hardness, friability, and power to draw iron, we say, are
qualities to be found in a loadstone. These...intimate that the substance is
supposed always SOMETHING BESIDES the extension, figure, solidity, motion,
thinking, or other observable ideas, though we know not what it
is.</blockquote></p>

<p>Let's apply Locke to object design and see where it leads.  Suppose he's
right: a person is simply a collection of related attributes or facets that
adhere to some substratum.  Let's model this explicitly.</p>

<p>Backing up for a second for contrast, the normal way you would design a
domain-independent <code>Person</code> object, assuming for the moment you
could, would be to pick some attributes that you thought were sufficiently
general and important to be included in this superclass (and here's where you
run into problems).  Here, for the sake of brevity, is my silly offering:

<blockquote><pre>public class Person {
  
  // My selection for an attribute that is important enough to
  // be included in this reusable class.  Yours could be different.
  // Of course that means we'll probably end up not reusing each other's
  // classes.  Hmm.
  private String name;

  public Person() {
    super();
  }

  public String getName() {
    return this.name;
  }

  public void setName(final String name) {
    this.name = name;
  }

  // etc.

}</pre></blockquote></p>

<p>Of course, picking what those attributes are is what makes reusable object
design so tough.</p>

<p>Locke, if he were an object designer, would be a rebel.  He would probably
start with the attributes--the collections of simple ideas--and graft them on to
some simple "substance" object that would be deliberately designed to be more or
less inscrutable.  As it turns out, this is a much better way to achieve object
reuse across domains.  Maybe an extreme version of his code would look something
like this:

<blockquote><pre>public interface IKnowNotWhat {
  // If only we knew what it was!
}

public class Person implements IKnowNotWhat {

  public Person() {
    super();
  }

}

public abstract class CollectionOfSimpleIdeas {
    
  protected final IKnowNotWhat substance;

  public CollectionOfSimpleIdeas(final IKnowNotWhat substance) {
    super();
    this.substance = substance;
    if (substance == null) {
      throw new BritishEmpiricismMisunderstoodException();
    }
  }

  public IKnowNotWhat getSubstance() {
    return substance;
  }

}

public class PersonNames extends CollectionOfSimpleIdeas {
  
  private String familiarName;

  public PersonNames(final IKnowNotWhat substance) {
    super(substance);
  }

  public String getFamiliarName() {
    return this.familiarName;
  }

  public void setFamiliarName(final String familiarName) {
    this.familiarName = familiarName;
  }

  // etc.

}

public class PersonMeasurements extends CollectionOfSimpleIdeas {
    
  private int heightInInches;

  public PersonMeasurements(final IKnowNotWhat substance) {
    super(substance);
  }

  public int getHeight() {
    return this.heightInInches;
  }

  public void setHeight(final int height) {
    this.heightInInches = height;
  }

  // etc.

}</pre></blockquote></p>

<p>The key insight here is that people aren't interested in a reusable
<code>Person</code> object at all.  They are interested in different
combinations of facets that all <i>concern</i> a person in a particular domain.
A financial services programmer doesn't care about a person's weight, but that
might be very important to the programmer of an insurance system.  Explicitly
modeling a person this way--inside out--lets each domain of attributes stand
alone, but also lets them play nicely together when bound together.  What's
important is that the <i>attributes</i> are reused, not the substratum.</p>

<p>All of this philosophy has made my brain hurt.  I'm going to go get some
lunch (although I know not what).</p>]]>

</content>
</entry>

</feed>