Friday, June 08, 2007

Swing mini design pattern

I don't know whether this qualifies as a design pattern, but here goes anyway.

Intent/Motivation
You have a Swing MDI application with the main window managing the lifecycles of the child windows. When the user selects a menu option, the corresponding child window should be displayed. But no action should be taken if the menu is selected when the child window is already displayed. We cannot check for the null value of the child window data member (and spawn a new window) because there is no way for the child window to set itself to null when it is closed.

Applicability
Swing MDI applications where only one instance of a child window should be displayed at any point in time.

Implementation
Have the main window class implement a callback interface:

public interface CallBackHandler
{
    public void call(int ID);
}

public class MainWindow implements CallBackHandler
{
    //repeat for each child window
    public static final int CHILDWINDOW1 = 1;
    private ChildWindow1 childWindow1;

    public void call(int windowId)
    {
        //repeat for each child window
        if(windowId == CHILDWINDOW1)
        {
            childWindow1 = null;
        }
    }

        ...

The child window constructor is passed the main window reference (but is only bound to the CallBackHandler, though nothing would prevent a ctor defined with a parameter of type MainWindow and accessing MainWindow's (public) members).

        ...
        //code to invoke child window
        if(childWindow1 == null)
        {
            childWindow1 = new ChildWindow1(this);
            childWindow1.show();
            ...
        }

public class ChildWindow1
{
    private CallBackHandler cbh;
    public ChildWindow1(CallBackHandler cbh)
    {
        this.cbh = cbh;
    }
        ...
        //code in listener that handles window closing
        cbh.call(MainWindow.CHILDWINDOW1);
        ...
}