Package simtools.shapes

Source Code of simtools.shapes.AbstractShape

/* ==============================================
* Simtools : The tools library used in JSynoptic
* ==============================================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* 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., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2003, by :
*     Corporate:
*         Astrium SAS
*         EADS CRC
*     Individual:
*         Claude Cazenave
*      Nicolas Brodu
*
*
* $Id: AbstractShape.java,v 1.27 2009/01/08 16:40:18 ogor Exp $
*
* Changes
* -------
* 25-Sep-2003 : Initial public release (NB);
*
*/
package simtools.shapes;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.swing.undo.CompoundEdit;

import simtools.diagram.Element;
import simtools.shapes.ShapeListener;
import simtools.shapes.ui.AbstractShapePropertiesDialogBox;
import simtools.shapes.undo.PropertyChangeEdit;
import simtools.ui.JPropertiesPanel;
import simtools.util.ListenerManager;
import simtools.util.NamedProperties;

/**
* This base class is used for shapes with a specific bounds computation
* based on anchor definition. The derived classes can be serialized.
*
* @author Claude Cazenave
*
* @version 1.0 2001
*/
public abstract class AbstractShape implements java.io.Serializable, Cloneable, Element,
                      NamedProperties {

  static final long serialVersionUID = -7697012777559414541L;


    public static int MIN_SIZE = 20;
   
   
  protected int _x;
  protected int _y;
  protected int _w;
  protected int _h;

  /** anchor location on x */
  protected int _ox;

  /** anchor location on y */
  protected int _oy;


  /**
   * The list of properties managed by this panel
   */
  protected transient String[] _propertyNames=null;
 
 
  protected transient ListenerManager listeners = new ListenerManager();

  /**
   * Refresh at no more than 100 ms
   */
  static public int REFRESH_PERIOD = 100;

  /**
   * Use anti aliasing
   */
  static public boolean ANTI_ALIASING = true;


  /**
   * Available font list
   */
  static public String[] FONT_NAMES={"Dialog", "Lucida Bright", "Lucida Sans", "Monospaced", "SansSerif", "Serif"};

 
  /** Only one shape properties dialog box can be displayed at once
   * When user opens a dialog box properties while another one is still displayed: this last dislaog box is closed
   */
  public transient static AbstractShapePropertiesDialogBox currentDialogBox=null;
 
 
  /**
   * Initializes this abstract shape, anchored at 0,0
   */
  public AbstractShape() {
    this(0,0);
  }
 
  /**
   * Initializes this abstract shape
   * @param ox the anchor x position
   * @param oy the anchor y position
   */
  public AbstractShape(int ox, int oy){
    _ox=ox;
    _oy=oy;
    _x=0;
    _y=0;
    _w=0;
    _h=0;
  }


  /**
   * Performs a copy of the shape
   * This method has to be overriden to deal with concrete shapes
   * @return a copy of the shape
   */
  protected AbstractShape cloneShape(){
    try{
      AbstractShape clone = (AbstractShape)super.clone();
      clone.listeners = new ListenerManager();
      return clone;
    }
    catch(CloneNotSupportedException cnse){
    }
    return null;
  }

  /**
   * Compares shape left/top origin with a point
   * If the shape origin is lowered then replace the
   * point coordinates with the minimum corrdinates
   * @param p the point
   * @param pa the anchor origin
   */
  public void getMin(Point p){
          int x=_ox+_x;
          int y=_oy+_y-_h;
    if(x<p.x){
      p.x=x;
    }
    if(y<p.y){
      p.y=y;
    }
  }

  /**
   * Gets shape anchor
   * @return the origin
   */
  public Point getAnchor(){
    return new Point(_ox,_oy);
  }
 
  /**
   * Get an optional affineTransform applied to this shape on display.
   * @return
   */
  public AffineTransform getTransform(){
      return null;
  }

  /**
   * Sets shape anchor
   * @param p the origin
   */
  public void setAnchor(Point p) {
    setAnchor(p.x, p.y);
  }
  public void setAnchor(int ox, int oy){
    _ox=ox;
    _oy=oy;
  }

  /**
   * Compare shape right/down coordinates with a point
   * If the shape coordiantes are lowered then replace the
   * point coordinates with the maximum value of the coordinates
   * @param p the point
   */
  public void getMax(Point p){
          int x=_ox+_x+_w;
          int y=_oy+_y;
    if(x>p.x){
      p.x=x;
    }
    if(y>p.y){
      p.y=y;
    }
  }

  /**
   * Compares shape right/down coordinates with a transalted point
   * If the shape coordiantes are lowered then replace the
   * point coordinates with the maximum value of the coordinates
   * @param p the point
   * @param pa the anchor origin
   * @param dx translation along X axis
   * @param dy translation along Y axis
   */
  public void getMaxTranslated(Point p, int dx, int dy){
          int x=_ox+_x+_w+dx;
          int y=_oy-_y;
    if(x>p.x){
      p.x=x;
    }
    if(y>p.y){
      p.y=y;
    }
  }

  /**
   * Translates the shape
   */
  public void translate(int dx, int dy){
    _ox+=dx;
    _oy+=dy;
  }

  /**
   * Draws the shape
   * @param g the graphics context
   */
        public abstract void draw(Graphics2D g);

  //
  // Shape Interface
  //
  public boolean contains(double x, double y){
          int ox=_ox+_x;
          int oy=_oy+_y;
    return     (x >= ox)
      && (x <= (ox+_w))
      && (y >= (oy-_h))
      && (y <= oy);
  }

  public boolean contains(double x, double y, double w, double h){
          int ox=_ox+_x;
          int oy=_oy+_y;
    return     (x>=ox)
      && ((x+w)<=(ox+_w))
      && (y>=(oy-_h))
      && ((y+h)<=oy);
  }

  public boolean contains(Point2D p){
    return contains(p.getX(), p.getY());
  }

  public boolean contains(Rectangle2D r){
    return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
  }

  public boolean intersects(double x, double y, double w, double h){
    return getBounds2D().intersects(x,y,w,h);
  }

  public boolean intersects(Rectangle2D r){
    return getBounds2D().intersects(r);
  }

  public Rectangle getBounds(){
    return new Rectangle(_ox+_x,_oy+_y-_h,_w,_h);
  }

  public Rectangle2D getBounds2D(){
    return new Rectangle2D.Double(_ox+_x,_oy+_y-_h,_w,_h);
  }
  public PathIterator getPathIterator(AffineTransform at){
    return null;
  }

  public PathIterator getPathIterator(AffineTransform at, double flatness){
    return null;
  }
  // Shape Interface end


  // Listeners related functions

  public void addListener(ShapeListener sl) {
    listeners.add(sl);
  }

  public void removeListener(ShapeListener sl) {
      listeners.remove(sl);
  }

 


  /* (non-Javadoc)
   * @see simtools.diagram.Element#processShapeRestoring()
   */
  public void processShapeRestoring(){
        // by default do nothing
  }


  /* (non-Javadoc)
   * @see simtools.diagram.Element#processShapeRemoving()
   */
  public void processShapeRemoving(){
      // by default do nothing
  }


 
 
  /**
   * Notify listeners that this shape has changed.
   * This is called by the various subclasses when necessary. For example, when connected
   * to dynamic data sources.
   */
  protected synchronized void notifyChange() {
    notifyChange(null);
  }

  protected synchronized void notifyChange(Rectangle changedArea) {
   
    if (listeners.size()==0) return;
    Rectangle r=getBounds();
    if (changedArea!=null){
      r.add(changedArea);
    }
   
    synchronized(listeners) {
      int n = listeners.size(); // only one call outside loop
      for (int i=0; i<n; ++i) {
        ShapeListener sl = (ShapeListener)listeners.get(i);
        if (sl!=null) sl.shapeChanged(AbstractShape.this, r);
      }
    }   
  }

  /**
   * Restores a serialized object.
   *
   * @param stream  the input stream.
   *
   * @throws IOException if there is an I/O problem.
   * @throws ClassNotFoundException if there is a problem loading a class.
   */
  private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    stream.defaultReadObject();
    listeners = new ListenerManager();
  }

  /**
   * Assigns <code>value</code> to the property named <code>name</code>
   * @param name
   * @param value
   */
  public void setPropertyValue(String name, Object value) {
    if(false){ // DEBUG
      Object oldValue=getPropertyValue(name);
      if(((oldValue==null)&&(value!=null))
        ||((oldValue!=null)&&!oldValue.equals(value))){
       
        System.err.println("Property: "+name
              +", "+getClass()
              +", OLD: "+oldValue
              +", NEW: "+value);
      }
    }
  }

 
    /**
     * Get the panel that best fit with the given list of properties
     * @param properties
     * @return The panel, or null if no panel complies with the given list of properties
     */
    public JPropertiesPanel getPanel(List properties){
        return null;
    }
   
    /**
     * @return the name of the shape
     */
    public String getShapeName(){
        return "";
    }
   
   
  /**
   * Get the value of the property named <code>name</code>
   * @param name
   */
  public Object getPropertyValue(String name) {
    return null;
  }
 
  /* (non-Javadoc)
   * @see simtools.util.NamedProperties#getInnerProperties()
   */
  public Collection getInnerProperties() {
    return null;
  }

  public String[] getPropertyNames(){
    return null;
  }
   
  public boolean setProperties(NamedProperties properties, CompoundEdit ce) {

    boolean res=false;
 
    String[] props = properties.getPropertyNames();
    if(props!=null){
      // Set local properties
      for(int j=0; j<props.length; j++) {
        String pname=props[j];
        Object value=properties.getPropertyValue(pname);
        ce.addEdit(new PropertyChangeEdit(this, pname, getPropertyValue(pname),value));
        setPropertyValue(pname, value);
        res=true;
      }
    }
   
    // Manage inner shapes if any
    Collection c = properties.getInnerProperties();
    Collection cshape=getInnerProperties();
    if(c!=null&&cshape!=null){
      Iterator it=c.iterator();
      Iterator itshape=cshape.iterator();
      while(it.hasNext()&& itshape.hasNext()){
        AbstractShape as=(AbstractShape)itshape.next();
        NamedProperties np=(NamedProperties)it.next();
        res |= as.setProperties(np,ce);
      }
    }
   
   
    return res;
  }

  /**
   * Wipe-off all all buffered resources in order to refresh shape.
   * This is overloaded by the various subclasses when necessary.
   *
   * For example, a image shape shall wipe-off all its buffered images
   */
  public void wipeOff(){}

 
  /**
   * Reload all shape properties.
   */
  public void refresh(){
    String[] names = getPropertyNames();
    if (names != null){
        for(int j =0; j<names.length;j++){
              setPropertyValue(names [j], getPropertyValue(names [j]));
          }
    }
 
  }
 
 
  /**
   * @param shapes - a list of shapes
   * @return a list of properties that can be applied to all given shapes. Return null if list  of shapes is empty
   */
  protected static List getCommonProperties(List shapes){
      List ret = new ArrayList();
     
      if (!shapes.isEmpty()){
          String[] properties = ((AbstractShape)shapes.get(0)).getPropertyNames();

          for(int i=0; i < properties.length; i++){
              String property = properties[i];
              boolean isCommonProperty = true;

              for(int j=1; (j< shapes.size()) && isCommonProperty; j++){
                  AbstractShape s = (AbstractShape)shapes.get(j);
                  isCommonProperty &= Arrays.asList(s.getPropertyNames()).contains(property);
              }
              if (isCommonProperty){
                  ret.add(property);
              }   
          }  
      }
      return ret;
  }
 
 
  /**
   * A delegate class that provides the list of properties names related to its mother class
   * @author zxpletran007
   *
   */
  public static class AbstractShapePropertiesNames{
    protected ArrayList propertyNames;
   
    public AbstractShapePropertiesNames(){
      propertyNames = new ArrayList();
    }
 
    public String[] getPropertyNames(){
      return (String[])propertyNames.toArray(new String[propertyNames.size()]);
    }
  }
 
}


TOP

Related Classes of simtools.shapes.AbstractShape

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.