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 = (ImageIcon) ois.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 = (ListListener) i.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 (BaseObject) klass.newInstance();
245 }
246 catch (Exception ex) {
247 throw new InternalError(ex.getMessage());
248 }
249 }
250 }
|