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