KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > buchuki > ensmer > text > TextDisplay


1 /*
2  * Copyright 2005 Dusty Phillips
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package com.buchuki.ensmer.text;
18
19 import com.buchuki.ensmer.SceneGraphUtils;
20 import com.buchuki.annotations.*;
21 import java.awt.*;
22 import java.awt.image.BufferedImage JavaDoc;
23 import java.util.*;
24 import javax.media.j3d.*;
25
26
27 /**
28  * Class to display text on a Java3D widget. This class basically acts as a
29  * wrapper to Text2D. Text2D seems to have a problem resizing when setString()
30  * is called, and requires certain capabilities to be set.
31  *
32  * This class may have additional or different functionality if there
33  * are problems with multiline text display.
34  *
35  * @author Dusty Phillips [dusty@buchuki.com]
36  */

37 public class TextDisplay extends Shape3D {
38     
39     /**
40      * The scale factor for the text geometries. Tries to put 30 16pt characters
41      * on an 8.5" sheet of paper.
42      */

43     private static final float SCALE_FACTOR = 1f/1024f;
44     
45     /**
46      * Creates a new instance of TextDisplay. TextDisplay displays a TextInput
47      * object, correctly allowing for new lines. It displays the cursor if the
48      * textInput is focused.
49      *
50      * @param color the color of the text
51      * @param font the font to be displayed
52      */

53     public TextDisplay(Color color, Font font) {
54         this.color = color;
55         this.font = font;
56         setCapability(ALLOW_GEOMETRY_WRITE);
57         Appearance app = new Appearance();
58         app.setCapability(app.ALLOW_TEXTURE_WRITE);
59         TransparencyAttributes trAtt = new TransparencyAttributes();
60         trAtt.setTransparencyMode(TransparencyAttributes.FASTEST);
61         trAtt.setTransparency(0f);
62         app.setTransparencyAttributes(trAtt);
63         setAppearance(app);
64         geom = new QuadArray(4,
65                 QuadArray.COORDINATES | QuadArray.TEXTURE_COORDINATE_2);
66         geom.setCapability(geom.ALLOW_COORDINATE_WRITE);
67         geom.setTextureCoordinates(0, 0, new float[] {
68             0f, 1f,
69             0f, 0f,
70             1f, 0f,
71             1f, 1f
72         });
73         setGeometry(geom);
74         SceneGraphUtils.enableEnsmerCapabilities(this);
75     }
76     
77     /**
78      * Set the string to the given value and ignore the cursor
79      *
80      * @param text the nev String to display
81      */

82     public void setText(String JavaDoc text) {
83         TextInput newText = new TextInput();
84         newText.setText(text);
85         newText.setFocused(false);
86         setText(newText);
87     }
88     
89     /**
90      * Set the string and cursor to the given value
91      *
92      * @param text the new TextInput display
93      */

94     @Optimize("The cursor positioning algorithm doesn't need to cycle through every character, but my other attempts all broke")
95     public void setText(TextInput text) {
96         StringTokenizer stok = new StringTokenizer(text.getText(), "\n", true);
97         java.util.List JavaDoc<String JavaDoc> lines = new ArrayList<String JavaDoc>();
98         int numLines = 0;
99         boolean lastWasNewLine = true;
100         while (stok.hasMoreTokens()) {
101             String JavaDoc next = stok.nextToken();
102             if (next.equals("\n")) {
103                 if (lastWasNewLine == true) {
104                     lines.add("");
105                 }
106                 lastWasNewLine = true;
107             }
108             else {
109                 lastWasNewLine = false;
110                 lines.add(next);
111             }
112         }
113         graphics.setFont(font);
114         FontMetrics metrics = graphics.getFontMetrics();
115         int width = longestString(lines, metrics) + 4;
116         int height = (lines.size() + 1) * metrics.getHeight();
117         textWidth = width * SCALE_FACTOR;
118         textHeight = height * SCALE_FACTOR;
119         
120         width = SceneGraphUtils.greaterBinaryPower(width, 16);
121         height = SceneGraphUtils.greaterBinaryPower(height, 16);
122         
123         texture = new BufferedImage JavaDoc(width, height, BufferedImage.TYPE_INT_ARGB);
124         graphics = texture.createGraphics();
125         graphics.setFont(font);
126         graphics.setColor(new Color(0, 0, 0, 0)); //full transparency
127
graphics.fillRect(0, 0, width, height);
128         graphics.setColor(color);
129         graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
130         int baseLine = metrics.getHeight() - metrics.getDescent() + 1;
131         for (String JavaDoc line : lines) {
132             graphics.drawString(line, 1, baseLine);
133             baseLine += metrics.getHeight();
134         }
135         
136         //draw the cursor
137
if (text.isFocused()) {
138             String JavaDoc s = text.getText();
139             int pos = text.getCursorPosition();
140             int x = 0;
141             int y = 0;
142             StringBuffer JavaDoc currLine = new StringBuffer JavaDoc();
143             for (int i = 0; i < pos; i++) {
144                 if (s.charAt(i) == '\n') {
145                     y += metrics.getHeight();
146                     currLine.delete(0, currLine.length());
147                 }
148                 else {
149                     currLine.append(s.charAt(i));
150                 }
151             }
152             x = metrics.stringWidth(currLine.toString());
153             int y2 = y+metrics.getHeight();
154             graphics.setColor(new Color(0.5f, 0.3f, 0.2f));
155             graphics.drawLine(x, y, x, y2);
156         }
157         
158         ImageComponent2D image = new ImageComponent2D(
159                 ImageComponent.FORMAT_RGBA, texture);
160         
161         Texture2D tex = new Texture2D(Texture2D.BASE_LEVEL, Texture2D.RGBA,
162                 image.getWidth(), image.getHeight());
163         tex.setImage(0, image);
164         getAppearance().setTexture(tex);
165         float gHeight = height * SCALE_FACTOR;
166         float gWidth = width * SCALE_FACTOR;
167         geom.setCoordinates(0, new float[] {
168             0, 0, 0,
169             0, -gHeight, 0,
170             gWidth, -gHeight, 0,
171             gWidth, 0, 0
172         });
173         setGeometry(geom);
174 }
175     
176     /**
177      * Get the width of the text in world coordinates. This is not likely
178      * the same as the width of the geometry.
179      *
180      * @return the width of the text
181      */

182     public float getWidth() {
183         return textWidth;
184     }
185     
186     /**
187      * Get the height of the text in world coordinates. This is not likely
188      * the same as the height of the geometry.
189      *
190      * @return the height of the text
191      */

192     public float getHeight() {
193         return textHeight;
194     }
195     
196     
197     /**
198      * Determine which is the longest string using the given fontMetrics and
199      * return the length of the string in those metrics.
200      *
201      * @param lines list of strings to determine which is longest
202      * @param metrics the fontMetrics to determine the longest string for
203      */

204     private int longestString(java.util.List JavaDoc<String JavaDoc> lines, FontMetrics metrics) {
205         int longestWidth = 1; //0 width images cause exceptions
206
for (String JavaDoc line : lines) {
207             int lineWidth = metrics.stringWidth(line);
208             if (lineWidth > longestWidth) {
209                 longestWidth = lineWidth;
210             }
211         }
212         return longestWidth;
213     }
214     
215     /**
216      * The font to be applied to the string.
217      */

218     private Font font;
219     
220     /**
221      * The color of the String
222      */

223     private Color color;
224     
225     /**
226      * The BufferedImage to draw the text on
227      */

228     private BufferedImage JavaDoc texture = new BufferedImage JavaDoc(5, 5, BufferedImage.TYPE_INT_ARGB);
229     
230     /**
231      * The graphics associated with the texture
232      */

233     private Graphics2D graphics = texture.createGraphics();
234     
235     /**
236      * The geometry for the Shape3D
237      */

238     private GeometryArray geom;
239     
240     /**
241      * The width of the text portion of the object
242      */

243     private float textWidth;
244     
245     /**
246      * The height of the text portion of the object. THese differ from
247      * geom.getHeight because the texture must be a power of 2 size.
248      */

249     private float textHeight;
250     
251 }
252
Popular Tags