/Users/richardallenbair/Documents/Source/Projects/nonsense/swingx/src/beaninfo/JXMultiSplitPane_API.java
/*
 * $Id: JXMultiSplitPane_API.html 1352 2006-08-22 22:52:00Z rbair $
 *
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package org.jdesktop.swingx;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.JPanel;
import javax.swing.event.MouseInputAdapter;
import org.jdesktop.swingx.MultiSplitLayout.Divider;
import org.jdesktop.swingx.MultiSplitLayout.Node;

/**
 * <p>MultiSplitPane is a Swing container that supports a resizable tiled layout of 
 * arbitrary components. It's intended to be a generalization of the existing 
 * JSplitPane component, which only supports a pair of tiles. The 
 * MultiSplitLayout layout manager recursively arranges its components in row 
 * and column groups called "splits." Elements of the layout are separated by 
 * gaps called "dividers" that can be moved by the user, in the same way as 
 * JSplitPane. The overall layout is defined with a simple tree-structured 
 * model that can be stored and retrieved to make the user's layout 
 * configuration persistent. The initial layout, before the user has intervened, 
 * is defined conventionally, in terms of the layout model and the component's 
 * preferred sizes.</p>
 * 
 * <p>MultiSplitPane differs from components with similar capabilities in that 
 * complex dynamic layouts can be defined without nesting or composition. All 
 * of the children managed by a MultiSplitPane are arranged in their 
 * rows and columns (and rows within columns and columns within rows) end up 
 * separated by divider gaps, but not by extra layout-managing containers. 
 * MultiSplitPane's layout class, MultiSplitLayout, is also 
 * a little unusual in that it exposes a model of the complete layout.</p>
 * 
 * <h2>Basic Usage</h2>
 * <p>Using MultiSplitPane requires two steps. First, a tree model that 
 * specifies the layout is created using the MultiSplitLayout's 
 * Split, Divider, and Leaf classes. 
 * These classes are static inner classes of MultiSplitLayout, 
 * so they have names like MultiSplitLayout.Divider. Leaf nodes 
 * represent components, dividers represent the gaps between components that the 
 * user can drag around, and splits represent rows or columns. Components are 
 * added to the MultiSplitPane with a constraint that names the 
 * Leaf (leaf nodes have a name property) that will specify their bounds.</p>
 * 
 * <p>Here's an example that creates the MultiSplitPane equivalent of 
 * JSplitPane. There are just two components, arranged in a row, with a 
 * Divider in between.
 * <pre><code>
 *  List children = 
 *      Arrays.asList(new Leaf("left"),
 *          new Divider(), 
 *          new Leaf("right"));
 *  Split modelRoot = new Split();
 *  modelRoot.setChildren(children);
 * 
 *  MultiSplitPane multiSplitPane = new MultiSplitPane();
 *  multiSplitPane.getMultiSplitLayout().setModel(modelRoot);
 *  multiSplitPane.add(new JButton("Left Component"), "left");
 *  multiSplitPane.add(new JButton("Right Component"), "right");
 * </code></pre></p>
 * 
 * <p>All properties in this class are bound: when a properties value
 * is changed, all PropertyChangeListeners are fired.</p>
 * 
 * @see {@link http://today.java.net/pub/a/today/2006/03/23/multi-split-pane.html}
 * 
 * @author Hans Muller
 */
public class JXMultiSplitPane extends JXPanel {
    /**
     * Creates a JXMultiSplitPane with it's LayoutManager set to 
     * an empty MultiSplitLayout.
     */
    public JXMultiSplitPane();

    /**
     * A convenience method that returns the layout manager cast 
     * to MutliSplitLayout.
     * 
     * @return this JXMultiSplitPane's layout manager
     * @see java.awt.Container#getLayout
     * @see #setModel
     */
    public final MultiSplitLayout getMultiSplitLayout();

    /** 
     * A convenience method that sets the MultiSplitLayout model.
     * Equivalent to <code>getMultiSplitLayout.setModel(model)</code>
     * 
     * @param model the root of the MultiSplitLayout model
     * @see #getMultiSplitLayout
     * @see MultiSplitLayout#setModel
     */
    public final void setModel(Node model);

    /** 
     * A convenience method that sets the MultiSplitLayout dividerSize
     * property. Equivalent to 
     * <code>getMultiSplitLayout().setDividerSize(newDividerSize)</code>.
     * 
     * @param dividerSize the value of the dividerSize property
     * @see #getMultiSplitLayout
     * @see MultiSplitLayout#setDividerSize
     */
    public final void setDividerSize(int dividerSize);

    /**
     * Sets the value of the <code>continuousLayout</code> property.
     * If true, then the layout is revalidated continuously while
     * a divider is being moved.  The default value of this property
     * is true.
     *
     * @param continuousLayout value of the continuousLayout property
     * @see #isContinuousLayout
     */
    public void setContinuousLayout(boolean continuousLayout);

    /**
     * Returns true if dragging a divider only updates
     * the layout when the drag gesture ends (typically, when the 
     * mouse button is released).
     *
     * @return the value of the <code>continuousLayout</code> property
     * @see #setContinuousLayout
     */
    public boolean isContinuousLayout();

    /** 
     * Returns the Divider that's currently being moved, typically
     * because the user is dragging it, or null.
     * 
     * @return the Divider that's being moved or null.
     */
    public Divider activeDivider();

    /**
     * Draws a single Divider.  Typically used to specialize the
     * way the active Divider is painted.  
     * 
     * @see #getDividerPainter
     * @see #setDividerPainter
     */
    public static abstract class DividerPainter {
        /**
         * Paint a single Divider.       
         * 
         * @param g the Graphics object to paint with
         * @param divider the Divider to paint
         */
        public abstract void paint(Graphics g, Divider divider);
    }

    /**
     * The DividerPainter that's used to paint Dividers on this JXMultiSplitPane.
     * This property may be null.
     * 
     * @return the value of the dividerPainter Property
     * @see #setDividerPainter
     */
    public DividerPainter getDividerPainter();

    /**
     * Sets the DividerPainter that's used to paint Dividers on this 
     * JXMultiSplitPane.  The default DividerPainter only draws
     * the activeDivider (if there is one) and then, only if 
     * continuousLayout is false.  The value of this property is 
     * used by the paintChildren method: Dividers are painted after
     * the JXMultiSplitPane's children have been rendered so that 
     * the activeDivider can appear "on top of" the children.
     * 
     * @param dividerPainter the value of the dividerPainter property, can be null
     * @see #paintChildren
     * @see #activeDivider
     */
    public void setDividerPainter(DividerPainter dividerPainter);

    /**
     * Uses the DividerPainter (if any) to paint each Divider that
     * overlaps the clip Rectangle.  This is done after the call to
     * <code>super.paintChildren()</code> so that Dividers can be 
     * rendered "on top of" the children.
     * <p>
     * {@inheritDoc}
     */
    protected void paintChildren(Graphics g);
}