1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package net.jbeans.j3d.modeler.scene.glyph;
24
25 /* ------------------ Import classes (packages) ------------------- *//package-summary/html">class="comment"> ------------------ Import classes (packages) ------------------- *//package-summary.html">class="comment">/* ------------------ Import classes (packages) ------------------- *//package-summary.html">class="comment"> ------------------ Import classes (packages) ------------------- */
26 import java.awt.*;
27 import java.beans.*;
28 import java.io.*;
29 import java.lang.reflect.*;
30 import javax.media.j3d.*;
31 import javax.vecmath.*;
32 import com.sun.j3d.utils.geometry.*;
33
34 import net.jbeans.j3d.modeler.scene.*;
35 import net.jbeans.util.debug.*;
36
37
38
39
40 /***
41 * GString is a glyph source which generatees javax.media.j3d.Shape3D
42 * object from a string.
43 *
44 * @version $Revision: 1.3 $
45 * @author Masahiro Takatsuka (masa@jbeans.net)
46 * @see GlyphSource, Serializable
47 */
48
49 public class GString implements GlyphSource, Serializable {
50 private static final boolean DEBUG = Debug.getDebugFlag(GString.class);
51
52 private static Method[] sSetMethods;
53 private static int[] sEssentials;
54 static {
55 setSetMethods();
56 }
57
58 private static void setSetMethods() {
59 Class clazz = net.jbeans.j3d.modeler.scene.glyph.GString.class;
60 sSetMethods = new Method[1];
61 sEssentials = new int[1];
62 Method m = null;
63
64
65
66
67 try {
68 m = clazz.getMethod("setString", new Class[] {java.lang.String.class});
69 sSetMethods[0] = m;
70 } catch (Exception e) {
71 sSetMethods[0] = null;
72 }
73 sEssentials[0] = 0;
74 }
75
76 public static final int STRING_2D = 0;
77 public static final int STRING_3D = 1;
78
79
80 private static final String DEFAULT_NULL_STR = "";
81 private static final Font DEFAULT_FONT = new Font("Times", Font.BOLD, 1);
82
83
84 private static final Color3f DEFAULT_COLOR = new Color3f(1.0f, 1.0f, 1.0f);
85
86 private static final int DEFAULT_ALIGNMENT = Text3D.ALIGN_CENTER;
87 private static final int DEFAULT_PATH = Text3D.PATH_RIGHT;
88
89
90 transient private String textString;
91 transient private Font3D font3d;
92 transient private PropertyChangeSupport changes;
93
94
95
96 private int type;
97 private Font font = DEFAULT_FONT;
98 private String stringForNull = DEFAULT_NULL_STR;
99
100
101 private int alignment = DEFAULT_ALIGNMENT;
102 private int path = DEFAULT_PATH;
103
104
105 private Color3f fontColor = DEFAULT_COLOR;
106 private float rectangleScaleFactor = 200.0f;
107
108 public GString() {
109 super();
110 initialize();
111 }
112
113 private void initialize() {
114 this.changes = new PropertyChangeSupport(this);
115
116 setType(STRING_3D);
117
118 setString(DEFAULT_NULL_STR);
119 setFont3D();
120
121 }
122
123 public void setStringForNull(String nullStr) {
124 this.stringForNull = nullStr;
125 }
126
127 public String getStringForNull() {
128 return this.stringForNull;
129 }
130
131 public void addPropertyChangeListener(PropertyChangeListener l) {
132 this.changes.addPropertyChangeListener(l);
133 }
134
135 public void removePropertyChangeListener(PropertyChangeListener l) {
136 this.changes.removePropertyChangeListener(l);
137 }
138
139 private void setFont3D() {
140 this.font3d = new Font3D(this.font, new FontExtrusion());
141 }
142
143
144 public void setType(int type) {
145 int old = this.type;
146 switch (type) {
147 case STRING_2D:
148 default:
149 type = STRING_2D;
150 int size = (int) this.rectangleScaleFactor * this.font.getSize();
151 setFont(new Font(this.font.getName(), this.font.getStyle(), size));
152 break;
153 case STRING_3D:
154 type = STRING_3D;
155 break;
156 }
157 this.type = type;
158 this.changes.firePropertyChange("type", old, this.type);
159 }
160
161 public int getType() {
162 return this.type;
163 }
164
165 public void setFont(Font font) {
166 Font old = this.font;
167 this.font = font;
168 setFont3D();
169 this.changes.firePropertyChange("font", old, this.font);
170 }
171
172 public Font getFont() {
173 return this.font;
174 }
175
176
177 public void setAlignment(int alignment) {
178 int old = this.alignment;
179 this.alignment = alignment;
180 this.changes.firePropertyChange("alignment", old, this.alignment);
181 }
182
183 public int getAlignment() {
184 return this.alignment;
185 }
186
187 public void setPath(int path) {
188 int old = this.path;
189 this.path = path;
190 this.changes.firePropertyChange("path", old, this.path);
191 }
192
193 public int getPath() {
194 return this.path;
195 }
196
197
198 public void setFontColor(Color3f color) {
199 Color3f old = this.fontColor;
200 this.fontColor = color;
201 this.changes.firePropertyChange("fontColor", old, this.fontColor);
202 }
203
204 public Color3f getFontColor() {
205 return this.fontColor;
206 }
207
208 public void setRectangleScaleFactor(float factor) {
209 float old = this.rectangleScaleFactor;
210 this.rectangleScaleFactor = factor;
211 this.changes.firePropertyChange("rectangleScaleFactor", new Float(old), new Float(this.rectangleScaleFactor));
212 }
213
214 public float getRectangleScaleFactor() {
215 return this.rectangleScaleFactor;
216 }
217
218
219 public void setString(String string) {
220 if (string == null) {
221 string = this.stringForNull;
222 }
223 this.textString = string;
224 }
225
226 public String getString() {
227 return this.textString;
228 }
229
230
231 public Node getNode() {
232 Shape3D shape3d = null;
233 switch (this.type) {
234 case STRING_2D:
235 shape3d = createText2D();
236 break;
237 case STRING_3D:
238 shape3d = createText3D();
239 break;
240 }
241 return shape3d;
242 }
243
244 private void setCapabilities(Geometry geom) {
245 geom.setCapability(GeometryArray.ALLOW_COUNT_READ);
246 geom.setCapability(GeometryArray.ALLOW_FORMAT_READ);
247 geom.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
248 geom.setCapability(GeometryArray.ALLOW_COORDINATE_WRITE);
249 geom.setCapability(GeometryArray.ALLOW_NORMAL_READ);
250 geom.setCapability(GeometryArray.ALLOW_NORMAL_WRITE);
251 geom.setCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ);
252 geom.setCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_WRITE);
253 geom.setCapability(IndexedGeometryArray.ALLOW_NORMAL_INDEX_READ);
254 geom.setCapability(IndexedGeometryArray.ALLOW_NORMAL_INDEX_WRITE);
255 }
256
257 private Shape3D createText2D() {
258 Text2D text2D = new Text2D(this.textString,
259 this.fontColor,
260 this.font.getFontName(),
261 this.font.getSize(),
262 this.font.getStyle());
263
264 Appearance ap = text2D.getAppearance();
265 PolygonAttributes pa = ap.getPolygonAttributes();
266 if (pa == null) {
267 pa = new PolygonAttributes();
268 }
269 pa.setCullFace(PolygonAttributes.CULL_NONE);
270 if (ap.getPolygonAttributes() == null) {
271 ap.setPolygonAttributes(pa);
272 }
273
274 text2D.setCapability(Node.ALLOW_BOUNDS_READ);
275 text2D.setCapability(Node.ALLOW_BOUNDS_WRITE);
276 text2D.setCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_READ);
277 text2D.setCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE);
278
279 Geometry geom = text2D.getGeometry();
280 setCapabilities(geom);
281
282 return text2D;
283 }
284
285 private Shape3D createText3D() {
286 Text3D text3d = new Text3D(this.font3d, this.textString);
287 text3d.setAlignment(this.alignment);
288 text3d.setPath(this.path);
289 text3d.setCapability(Text3D.ALLOW_ALIGNMENT_READ);
290 text3d.setCapability(Text3D.ALLOW_ALIGNMENT_WRITE);
291 text3d.setCapability(Text3D.ALLOW_PATH_READ);
292 text3d.setCapability(Text3D.ALLOW_PATH_WRITE);
293 text3d.setCapability(Text3D.ALLOW_STRING_READ);
294 text3d.setCapability(Text3D.ALLOW_STRING_WRITE);
295
296 setCapabilities(text3d);
297
298 Shape3D shape3d = new Shape3D(text3d);
299 shape3d.setCapability(Node.ALLOW_BOUNDS_READ);
300 shape3d.setCapability(Node.ALLOW_BOUNDS_WRITE);
301 shape3d.setCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_READ);
302 shape3d.setCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE);
303
304 return shape3d;
305 }
306
307 /***
308 * Updates the specified Shape3D object.
309 */
310 public Node updateNode(Node node) {
311 if (node instanceof Text2D) {
312 ((Text2D) node).setString(this.textString);
313 } else {
314 Text3D text3D = (Text3D) ((Shape3D)node).getGeometry();
315 text3D.setString(this.textString);
316 text3D.setAlignment(this.alignment);
317 text3D.setPath(this.path);
318 }
319
320 return node;
321 }
322
323 /***
324 * Returns an array containing methods to set data to construct
325 * a glyph source.
326 * setString(String);
327 */
328 public Method[] getSetMethods() {
329 return sSetMethods;
330 }
331
332
333
334
335 public int[] getEssentials() {
336 return sEssentials;
337 }
338
339 /***
340 * Returns javax.media.3d.Appearance object.
341 */
342 public Appearance getAppearanceOfNode(Node node) {
343 return (node instanceof Shape3D) ? ((Shape3D) node).getAppearance() : null;
344 }
345
346 /***
347 * Updates the specified Appearance object.
348 */
349 public void setAppearanceOfNode(Node node, Appearance appearance) {
350 if (node instanceof Shape3D) {
351 ((Shape3D) node).setAppearance(appearance);
352 }
353 }
354 }