Package research

Source Code of research.AbstractFigure

/*
* @(#)AbstractFigure.java
*
* Project:    JHotdraw - a GUI framework for technical drawings
*        http://www.jhotdraw.org
*        http://jhotdraw.sourceforge.net
* Copyright:  ?by the original author(s) and all contributors
* License:    Lesser GNU Public License (LGPL)
*        http://www.opensource.org/licenses/lgpl-license.html
*/

package research;

import research.util.Geom;
import research.util.ColorMap;

import java.awt.*;
import java.util.*;
import java.io.*;

import research.store.StorableOutput;
import research.store.StorableInput;
import research.connector.ChopBoxConnector;
import research.connector.Connector;

import javax.swing.*;

/**
* AbstractFigure provides default implementations for
* the Figure interface.
*
* <hr>
* <b>Design Patterns</b><P>
* <img src="images/red-ball-small.gif" width=6 height=6 alt=" o ">
* <b><a href=../pattlets/sld036.htm>Template Method</a></b><br>
* Template Methods implement default and invariant behavior for
* figure subclasses.
* <hr>
*
* @see research.Figure
* @see research.Handle
*
* @version <$CURRENT_VERSION$>
*/
public abstract class AbstractFigure extends AttributeFigure {

  /**
   * The listeners for a figure's changes.
   * @see #invalidate
   * @see #changed
   * @see #willChange
   */
  protected transient FigureChangeListener fListener;

    protected Connector[] connector = null;

  /*
   * Serialization support.
   */
  private static final long serialVersionUID = -10857585979273442L;
  private int abstractFigureSerializedDataVersion = 1;

    public ActionMap getActionMap(){
        return null;
    }

    public void setAttribute(String name, Object value){
        this.willChange();
        super._setAttribute(name, value);
        this.changed();
    }

  /**
   * Moves the figure by the given offset.
   */
  public void moveBy(int dx, int dy) {
    willChange();
    basicMoveBy(dx, dy);
    changed();
  }

  /**
   * Moves the figure. This is the
   * method that subclassers override. Clients usually
   * call displayBox.
   * @see #moveBy
   */
  protected abstract void basicMoveBy(int dx, int dy);

  /**
   * Changes the display box of a figure. Clients usually
   * call this method. It changes the display box
   * and announces the corresponding change.
   * @param origin the new origin
   * @param corner the new corner
   * @see #getDisplayBox
   */
  public void setDisplayBox(Point origin, Point corner) {
    willChange();
    basicDisplayBox(origin, corner);
    changed();
  }

  /**
   * Sets the display box of a figure. This is the
   * method that subclassers override. Clients usually
   * call displayBox.
   * @see #getDisplayBox
   */
  public abstract void basicDisplayBox(Point origin, Point corner);

  /**
   * Gets the display box of a figure.
   */
  public abstract Rectangle getDisplayBox();

    /**
   * Gets the display box of a figure.
   */
  public abstract Rectangle getDisplayBox(Rectangle r);

  /**
   * Returns the handles of a Figure that can be used
   * to manipulate some of its attributes.
   * @return a Vector of handles

   */
  public abstract Vector handles();

  /**
   * Returns an Enumeration of the figures contained in this figure.
   * @see CompositeFigure
   */
  public FigureEnumeration getFigures() {
    Vector figures = new Vector(1);
    figures.addElement(this);
    return new FigureEnumerator(figures);
  }


  /**
   * Gets the size of the figure. A convenience method.
   */
  public Dimension size() {
        Rectangle rect = getDisplayBox();
    return new Dimension(rect.width, rect.height);
  }

  /**
   * Checks if the figure is empty. The default implementation returns
   * true if the width or height of its display box is < 3
   * @see Figure#isEmpty
   */
  public boolean isEmpty() {
        Dimension size = size();
    return (size.width < 3) || (size.height < 3);
  }

  /**
   * Returns the figure that contains the given point.
   * In contrast to containsPoint it returns its
   * innermost figure that contains the point.
   *
   * @see #containsPoint
   */
  public Figure findFigureInside(int x, int y) {
    if (containsPoint(x, y)) {
      return this;
    }
    return null;
  }

  /**
   * Checks if a point is inside the figure.
   */
  public boolean containsPoint(int x, int y) {
    return getDisplayBox().contains(x, y);
  }

  /**
   * Changes the display box of a figure. This is a
   * convenience method. Implementors should only
   * have to override _setDisplayBox
   * @see #getDisplayBox
   */
  public void setDisplayBox(Rectangle r) {
    setDisplayBox(new Point(r.x, r.y), new Point(r.x+r.width, r.y+r.height));
  }

  /**
   * Checks whether the given figure is contained in this figure.
   */
  public boolean includes(Figure figure) {
    return figure == this;
  }

        /**
     * Draws the figure in the given graphics. Draw is a template
     * method calling drawBackground followed by drawFrame.
     */
    public void draw(Graphics g) {

        //added by zhangwei
        boolean visible = FigureHelper.isVisible(this);
        if (!visible)
            return;

        Color fill = getFillColor();
        Color oldColor = g.getColor();
        if (!ColorMap.isTransparent(fill)) {
            g.setColor(fill);
            drawBackground(g);
        }

        Color frame = getFrameColor();
        if (!ColorMap.isTransparent(frame)) {
            g.setColor(frame);
            drawFrame(g);
        }

        g.setColor(oldColor);

        drawContent(g);

        boolean connectorVisible = FigureHelper.isConnectorVisible(this);
        if(connectorVisible){
            Connector[] array = this.getConnectors();
            for(int i = 0; i < array.length; i++){
                array[i].draw(g);
            }
        }
    }

    /**
     * Draws the background of the figure.
     * @see #draw
     */
    protected void drawBackground(Graphics g) {
    }

    /**
     * Draws the frame of the figure.
     * @see #draw
     */
    protected void drawFrame(Graphics g) {
    }

    /**
     *
     */
    protected void drawContent(Graphics g) {

    }

    /**
     * Gets the fill color of a figure. This is a convenience
     * method.
     * @see #getAttribute
     */
    protected Color getFillColor() {
        return (Color) getAttribute("fillColor");
    }

    /**
     * Gets the frame color of a figure. This is a convenience
     * method.
     * @see #getAttribute
     */
    protected Color getFrameColor() {
        return (Color) getAttribute("frameColor");
    }

    protected Color getTextColor() {
        return (Color) getAttribute("textColor");
    }

  /**
   * Decomposes a figure into its parts. It returns a Vector
   * that contains itself.
   * @return an Enumeration for a Vector with itself as the
   * only element.
   */
  public FigureEnumeration decompose() {
    Vector figures = new Vector(1);
    figures.addElement(this);
    return new FigureEnumerator(figures);
  }


  /**
   * Sets the Figure's container and registers the container
   * as a figure change listener. A figure's container can be
   * any kind of FigureChangeListener. A figure is not restricted
   * to have a single container.
   */
  public void addToContainer(FigureChangeListener c) {
    addFigureChangeListener(c);
    invalidate();
  }

  /**
   * Removes a figure from the given container and unregisters
   * it as a change listener.
   */
  public void removeFromContainer(FigureChangeListener c) {
    invalidate();
    removeFigureChangeListener(c);
  }

  /**
   * Adds a listener for this figure.
   */
  public void addFigureChangeListener(FigureChangeListener l) {
    fListener = FigureChangeEventMulticaster.add(fListener, l);
  }

  /**
   * Removes a listener for this figure.
   */
  public void removeFigureChangeListener(FigureChangeListener l) {
    fListener = FigureChangeEventMulticaster.remove(fListener, l);
  }

  /**
   * Gets the figure's listners.
   */
  public FigureChangeListener listener() {
    return fListener;
  }

  /**
   * A figure is released from the drawing. You never call this
   * method directly. Release notifies its listeners.
   * @see Figure#release
   */
  public void release() {
    if (fListener != null) {
      fListener.figureRemoved(new FigureChangeEvent(this));
    }
  }

  /**
   * Invalidates the figure. This method informs the listeners
   * that the figure's current display box is invalid and should be
   * refreshed.
   */
  public void invalidate() {
    if (fListener != null) {
      Rectangle r = getDisplayBox();
      r.grow(Handle.HANDLESIZE/2 + 1, Handle.HANDLESIZE/2 + 1);
      fListener.figureInvalidated(new FigureChangeEvent(this, r));
    }
  }

  /**
   * Informes that a figure is about to change such that its
   * display box is affected.
   * Here is an example of how it is used together with changed()
   * <pre>
   * public void move(int x, int y) {
   *      willChange();
   *      // change the figure's location
   *      changed();
   *  }
   * </pre>
   * @see #invalidate
   * @see #changed
   */
  public void willChange() {
    invalidate();
  }

  /**
   * Informes that a figure has changed its display box.
   * This method also triggers an update call for its
   * registered observers.
   * @see #invalidate
   * @see #willChange
   *
   */
  public void changed() {
    invalidate();
    if (fListener != null) {
      fListener.figureChanged(new FigureChangeEvent(this));
    }
  }

  /**
   * Gets the center of a figure. A convenice
   * method that is rarely overridden.
   */
  public Point center() {
    return Geom.center(getDisplayBox());
  }

  /**
   * Returns the connection inset. The connection inset
   * defines the area where the display box of a
   * figure can't be connected. By default the entire
   * display box can be connected.
   *
   */
  public Insets connectionInsets() {
    return new Insets(0, 0, 0, 0);
  }

  /**
   * Returns the Figures connector for the specified location.
   * By default a ChopBoxConnector is returned.
   */
  public Connector connectorAt(int x, int y) {

        Connector[] array = getConnectors();

        Connector rv = null;
        for(int i = 0; i < array.length; i++){
            if(array[i].containsPoint(x,y)){
                rv = array[i];
                break;
            }
        }

    return rv;
  }

    public Connector[] getConnectors(){
        if(connector == null){
            connector = new Connector[1];
            connector[0] = new ChopBoxConnector(this);
        }

        return connector;
    }

  /**
   * Returns the locator used to located connected text.
   */
  public Locator connectedTextLocator(Figure text) {
    return RelativeLocator.center();
  }

    public void write(StorableOutput dw) {
        super.write(dw);

        Connector[] array = getConnectors();
        int connectorNum = 0;
        if(array != null){
            connectorNum = array.length;
        }

        dw.writeInt(connectorNum);

        for(int i = 0; i < connectorNum; i++){
            dw.writeStorable(array[i]);
        }

    }

    public void read(StorableInput dr) throws IOException {
        super.read(dr);

        int connectorNum = dr.readInt();

        connector = new Connector[connectorNum];

        for(int i = 0; i < connectorNum; i++){
            connector[i] = (Connector) dr.readStorable();
        }

    }

}
TOP

Related Classes of research.AbstractFigure

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.