Subpages: 1. JLayeredPane
2. Using JLayeredPane to enhance interfaces
3. Creating a custom MDI: part I - Dragging panels
4. Creating a custom MDI: part II - Resizability
5. Creating a custom MDI: part III - Enhancements
6. Creating a custom MDI: part IV - Selection and management
7. Creating a custom MDI: part V - JavaBeans compliance
15.7 Creating a custom MDI: part V - JavaBeans compliance
The functionality of our InnerFrame is pretty much complete at this point. However, there is still much to be desired if we plan to use InnerFrame in the field. JavaBeans compliance is one feature that not only is popular, but has come to be expected of each and every Java GUI component. In this section we will enhance InnerFrame by implementing the Externalizable interface, providing us with full control over its serialization. Although JComponent provides a default serialization mechanism for all Swing components, this is far from reliable at the time of this writing. Implementing our own serialization mechanism is not only reliable and safe for both long and short-term persistency, but it is also efficient. The default serialization mechanism tends to store much more information than we actually need.
Figure 15.10. Custom MDI: part V
The Code: InnerFrame.java
public class InnerFrame
extends JPanel implements RootPaneContainer, Externalizable
// Unchanged code
/////////////// Serialization /////////////////
public void writeExternal(ObjectOutput out)
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException
Rectangle r = (Rectangle)in.readObject();
r.x = getX();
r.y = getY();
Understanding The Code:
The added support for InnerFrame serialization here is quite simple. The readExternal() method will be invoked when readObject() is called on a given ObjectInput stream pointing to a previouly serialized InnerFrame. The writeExternal() method will be invoked when writeObject() is passed an InnerFrame and called on a given ObjectOutput stream. Refer back to chapter 4, section 4.7 to see how this is implemented in our BeanContainer JavaBeans environment.
Running The Code
Figure 5.10 shows an instance of InnerFrame, instantiated from a serialized InnerFrame saved to disk, and loaded into our JavaBeans property editing environment. We started the construction of this environment in chapter 4 and it will be completed (as shown) in chapter 18. The point to make here is that InnerFrame is now a JavaBean. There are certainly many ways to make InnerFrame a better bean. Specifically, many of the class variables would allow greater flexibility as properties, such as the default title bar height, border thickness, frame icon padding, button icons, etc. (Some of these might actually be better off within UI delegate code. Colors and button icons should change with look-and-feel, not be part of the component itself.) We could also add support for communication (which is completely lacking in InnerFrame now). For instance, we could make m_maximized into a bound or constrained property by sending out PropertyChangeEvents or VetoableChangeEvents respectively (refer back to chapter 2 for a discussion of JavaBeans and properties.). In this way we could notify interested listeners that a miximization is about to occur (in the case that m_maximize is constrained), and give them an opportunity to veto it.
Another major feature lacking in InnerFrame is look-and-feel support. The title bar and borders look like standard army-issued components at best. They should respond to look-and-feel changes just like any other Swing component. In chapter 21 we will implement support for all the major look-and-feels (Metal, Motif, Windows) for InnerFrame, plus our own custom look-and-feel (Malachite).