BaseObject.java
001 /**
002  *
003  * All content copyright (c) 2003-2008 Terracotta, Inc.,
004  * except as may otherwise be noted in a separate copyright notice.
005  * All rights reserved.
006  *
007  */
008 package demo.sharededitor.models;
009 
010 import java.awt.BasicStroke;
011 import java.awt.Color;
012 import java.awt.Graphics2D;
013 import java.awt.Image;
014 import java.awt.Rectangle;
015 import java.awt.Shape;
016 import java.awt.Stroke;
017 import java.io.ByteArrayInputStream;
018 import java.io.ByteArrayOutputStream;
019 import java.io.ObjectInputStream;
020 import java.io.ObjectOutputStream;
021 import java.util.ArrayList;
022 import java.util.Collections;
023 import java.util.Iterator;
024 import java.util.List;
025 
026 import javax.swing.ImageIcon;
027 
028 import demo.sharededitor.events.ListListener;
029 import demo.sharededitor.ui.FillStyleConsts;
030 import demo.sharededitor.ui.Texturable;
031 
032 /**
033  *  Description of the Class
034  *
035  *@author    Terracotta, Inc.
036  */
037 public abstract class BaseObject implements FillStyleConsts {
038    private List listeners;
039 
040    private int grabbedAnchor;
041 
042    private int fillstyle;
043 
044    private Color foreground;
045 
046    private Color background;
047 
048    private Stroke stroke = new BasicStroke();
049 
050    private byte[] texture = null;
051    private transient Image textureImage = null;
052 
053    public synchronized void setGrabbedAnchorAt(int x, int y) {
054       Shape[] anchors = getAnchors();
055       for (int i = 0; i < anchors.length; i++) {
056          if (anchors[i].contains(x, y)) {
057             grabbedAnchor = i;
058             return;
059          }
060       }
061       grabbedAnchor = -1;
062    }
063 
064    public synchronized void setFillStyle(int fillstyle) {
065       this.fillstyle = fillstyle;
066       notifyListeners(this);
067    }
068 
069    public synchronized void setForeground(Color color) {
070       this.foreground = color;
071       notifyListeners(this);
072    }
073 
074    public synchronized void setBackground(Color color) {
075       this.background = color;
076       notifyListeners(this);
077    }
078 
079    public synchronized void setStroke(Stroke stroke) {
080       this.stroke = stroke;
081       notifyListeners(this);
082    }
083 
084    public boolean isAt(int x, int y) {
085       if (!isReady()) {
086          return false;
087       }
088 
089       Shape shape = getShape();
090       if (shape.contains(x, y)) {
091          return true;
092       }
093 
094       Shape[] anchors = getAnchors();
095       for (int i = 0; i < anchors.length; i++) {
096          if (anchors[i].contains(x, y)) {
097             return true;
098          }
099       }
100       return false;
101    }
102 
103    public boolean isAnchorGrabbed() {
104       return (grabbedAnchor >= 0&& (grabbedAnchor < getAnchors().length);
105    }
106 
107    public boolean isTransient() {
108       return false;
109    }
110 
111    public void addListener(ListListener listListener) {
112       if (listeners == null) {
113          listeners = Collections.synchronizedList(new ArrayList());
114       }
115 
116       if (!listeners.contains(listListener)) {
117          listeners.add(listListener);
118       }
119    }
120 
121    public void removeListener(ListListener listListener) {
122       if ((listeners != null&& (listeners.contains(listListener))) {
123          listeners.remove(listListener);
124       }
125    }
126 
127    public abstract void resize(int x, int y);
128 
129    public abstract void move(int dx, int dy);
130 
131    public void draw(Graphics2D g, boolean showAnchors) {
132       Shape shape = getShape();
133       Rectangle bounds = shape.getBounds();
134       g.setColor(this.background);
135 
136       if (FILLSTYLE_SOLID == this.fillstyle) {
137          g.fill(shape);
138       }
139 
140       if ((FILLSTYLE_TEXTURED == this.fillstyle)
141             && (this instanceof Texturable&& isTextured()
142             && (bounds.width > 0&& (bounds.height > 0)) {
143          g.drawImage(getTexture(), bounds.x, bounds.y, bounds.width,
144                bounds.height, null);
145       }
146 
147       g.setStroke(this.stroke);
148       g.setColor(this.foreground);
149       g.draw(shape);
150 
151       if (showAnchors) {
152          Shape[] anchors = getAnchors();
153          for (int i = 0; i < anchors.length; i++) {
154             g.fill(anchors[i]);
155          }
156       }
157    }
158 
159    public synchronized void selectAction(boolean flag) {
160       // nothing to do here
161    }
162 
163    public synchronized void alternateSelectAction(boolean flag) {
164       // nothing to do here
165    }
166 
167    protected void setTexture(Image image) {
168       try {
169          ByteArrayOutputStream bos = new ByteArrayOutputStream();
170          ObjectOutputStream oos = new ObjectOutputStream(bos);
171          int width = image.getWidth(null);
172          if (width > 640) {
173             width = 640;
174          }
175 
176          int height = image.getHeight(null);
177          if (height > 480) {
178             height = 480;
179          }
180 
181          Image scaledImage = image.getScaledInstance(width, height,
182                Image.SCALE_FAST);
183          oos.writeObject(new ImageIcon(scaledImage));
184 
185          texture = bos.toByteArray();
186          textureImage = null;
187       }
188       catch (Exception ex) {
189          throw new InternalError("Unable to convert Image to byte[]");
190       }
191    }
192 
193    protected Shape[] getAnchors() {
194       return new Shape[0];
195    }
196 
197    protected abstract Shape getShape();
198 
199    protected Image getTexture() {
200       try {
201          if (textureImage == null) {
202             ByteArrayInputStream bis = new ByteArrayInputStream(texture);
203             ObjectInputStream ois = new ObjectInputStream(bis);
204             ImageIcon image = (ImageIconois.readObject();
205             textureImage = image.getImage();
206          }
207          return textureImage;
208       }
209       catch (Exception ex) {
210          throw new InternalError("Unable to convert byte[] to Image");
211       }
212    }
213 
214    protected boolean isTextured() {
215       return (texture != null);
216    }
217 
218    protected void notifyListeners(Object obj) {
219       if (listeners == null) {
220          return;
221       }
222 
223       for (Iterator i = listeners.iterator(); i.hasNext()) {
224          ListListener listListener = (ListListeneri.next();
225          listListener.changed(this, this);
226       }
227    }
228 
229    protected int grabbedAnchor() {
230       return grabbedAnchor;
231    }
232 
233    protected void clearTexture() {
234       this.texture = null;
235    }
236 
237    private boolean isReady() {
238       return (getShape() != null);
239    }
240 
241    public static final BaseObject createObject(String name) {
242       try {
243          Class klass = Class.forName("demo.sharededitor.models." + name);
244          return (BaseObjectklass.newInstance();
245       }
246       catch (Exception ex) {
247          throw new InternalError(ex.getMessage());
248       }
249    }
250 }