/*
* @(#)CompositeFigure.java
*
* Copyright (c) 1996-2010 The authors and contributors of JHotDraw.
* You may not use, copy or modify this file, except in compliance with the
* accompanying license terms.
*/
package org.jhotdraw.draw;
import org.jhotdraw.geom.Insets2D;
import org.jhotdraw.draw.layouter.Layouter;
import org.jhotdraw.draw.event.CompositeFigureListener;
/**
* A <em>composite figure</em> is composed of several child {@link Figure}s.
* <p>
* A composite figure can be laid out using a {@link Layouter}.
* <p>
* {@code CompositeFigure} listens to {@code requestRemove} events
* sent by its child figures, and then removes the child figure which sent
* the event.
*
* <hr>
* <b>Design Patterns</b>
*
* <p><em>Composite</em><br>
* Composite figures can be composed of other figures.<br>
* Component: {@link Figure}; Composite: {@link CompositeFigure}.
*
* <p><em>Observer</em><br>
* State changes of figures can be observed by other objects. Specifically
* {@code CompositeFigure} observes area invalidations and remove requests
* of its child figures. {@link DrawingView} also observes area invalidations
* of its drawing object.<br>
* Subject: {@link Figure};
* Observer: {@link org.jhotdraw.draw.event.FigureListener};
* Event: {@link org.jhotdraw.draw.event.FigureEvent};
* Concrete Observer: {@link CompositeFigure}, {@link DrawingView}.
*
* <p><em>Observer</em><br>
* Changes in the composition of a composite figure can be observed.<br>
* Subject: {@link CompositeFigure}; Observer:
* {@link org.jhotdraw.draw.event.CompositeFigureListener};
* Event: {@link org.jhotdraw.draw.event.CompositeFigureEvent}.
*
* <p><em>Strategy</em><br>
* Composite figures can be laid out using different layout algorithms which
* are implemented by layouters.<br>
* Context: {@link CompositeFigure}; Strategy: {@link Layouter}.
* <hr>
*
* @author Werner Randelshofer
* @version $Id$
*/
public interface CompositeFigure extends Figure {
/**
* The value of this attribute is a Insets2D.Double object.
*/
public static final AttributeKey<Insets2D.Double> LAYOUT_INSETS = new AttributeKey<Insets2D.Double>("layoutInsets", Insets2D.Double.class, new Insets2D.Double());
/**
* Adds a child to the figure.
* <p>
* This is a convenience method for {@code add(getChildCount(), child);}
* <p>
* This method calls {@code figureAdded} on all registered
* {@code CompositeFigureListener}s.
*
* @return {@code true} if this CompositeFigure changed as a result of the
* call
*/
public boolean add(Figure child);
/**
* Adds a child to the figure at the specified index.
* <p>
* This method calls {@code figureAdded} on all registered
* {@code CompositeFigureListener}s.
*/
public void add(int index, Figure child);
/**
* Adds a child to the figure without firing events.
* <p>
* This method can be used to reinsert a child figure which has been
* temporarily removed from this CompositeFigure (for example to reorder
* the sequence of the children) and to efficiently build a drawing from
* an {@link org.jhotdraw.draw.io.InputFormat}.
*
* This is a convenience method for calling
* {@code basicAdd(getChildCount(), child);}.
*/
public void basicAdd(Figure child);
/**
* Adds a child to the figure at the specified index without
* firing events.
* <p>
* This method can be used to reinsert a child figure which has been
* temporarily removed from this CompositeFigure (for example to reorder
* the sequence of the children) and to efficiently build a drawing from
* an {@link org.jhotdraw.draw.io.InputFormat}.
*/
public void basicAdd(int index, Figure child);
/**
* Removes the specified child.
* Returns true, if the Figure contained the removed child.
* <p>
* This is a convenience method for calling
* {@code removeChild(getChildren().indexOf(child));}
* <p>
* This method calls {@code figureRemoved} on all registered
* {@code CompositeFigureListener}'s.
*/
public boolean remove(Figure child);
/**
* Removes the child at the specified index.
* Returns the removed child figure.
* <p>
* Calls {@code figureRemoved} on all registered
* {@code CompositeFigureListener}'s.
*/
public Figure removeChild(int index);
/**
* Removes all children from the composite figure.
* <p>
* This is a convenience method for
* {@code while(getChildCount() > 0) removeChild(0); }
*/
public void removeAllChildren();
/**
* Removes the specified child without firing events.
* <p>
* This method can be used to temporarily remove a child from this
* CompositeFigure (for example to reorder the sequence of the children).
* <p>
* This is a convenience method for calling
* {@code basicRemove(indexOf(child));}.
* <p>
* Returns the index of the removed figure. Returns -1 if the
* figure was not a child of this CompositeFigure.
*/
public int basicRemove(Figure child);
/**
* Removes the child at the specified index without firing events.
* <p>
* This method can be used to temporarily remove a child from this
* CompositeFigure (for example to reorder the sequence of the children).
* <p>
* Returns the removed child figure.
*/
public Figure basicRemoveChild(int index);
/**
* Removes all children from the composite figure without firing events.
* <p>
* This method can be used to temporarily remove a child from this
* CompositeFigure (for example to reorder the sequence of the children).
* <p>
* This is a convenience method for
* {@code while(getChildCount() > 0) basicRemoveChild(0); }
*/
public void basicRemoveAllChildren();
/**
* Returns an unchangeable list view on the children.
*/
public java.util.List<Figure> getChildren();
/**
* Returns the number of children.
* <p>
* This is a convenience method for calling
* {@code getChildren().size();}.
*/
public int getChildCount();
/**
* Returns the child figure at the specified index.
* <p>
* This is a convenience method for calling
* {@code getChildren().get(index);}.
*/
public Figure getChild(int index);
/**
* Returns the index of the specified child.
* <p>
* This is a convenience method for calling
* {@code getChildren().indexOf(index);}.
*
* @return The index of the child, or -1 if the specified figure is not
* a child of this CompositeFigure.
*/
public int indexOf(Figure child);
/**
* Returns true if this composite figure contains the specified figure.
* <p>
* This is a convenience method for calling
* {@code getChildren().contains(f);}.
*/
public boolean contains(Figure f);
/**
* Get a Layouter object which encapsulated a layout
* algorithm for this figure. Typically, a Layouter
* accesses the child components of this figure and arranges
* their graphical presentation.
*
* @return layout strategy used by this figure
*/
public Layouter getLayouter();
/**
* A layout algorithm is used to define how the child components
* should be laid out in relation to each other.
* <p>
* This method first calls layout() on all child figures which implement
* the CompositeFigure interface. Then the children are laid out.
* <p>
* The task for laying out the child figures is delegated to a Layouter
* which can be plugged in at runtime.
*/
public void layout();
/**
* Set a Layouter object which encapsulated a layout
* algorithm for this figure. Typically, a Layouter
* accesses the child components of this figure and arranges
* their graphical presentation. It is a good idea to put
* the Layouter in the protected initialize() method
* so it can be recreated if a GraphicalCompositeFigure is
* read and restored from a StorableInput stream.
*
*
* @param newValue encapsulation of a layout algorithm.
*/
public void setLayouter(Layouter newValue);
/**
* Adds a listener for this composite figure.
*/
public void addCompositeFigureListener(CompositeFigureListener listener);
/**
* Removes a listener from this composite figure.
*/
public void removeCompositeFigureListener(CompositeFigureListener listener);
}