1 22 23 24 package net.sourceforge.chart2d; 25 26 27 import java.awt.*; 28 import java.util.*; 29 import java.awt.font.*; 30 import java.awt.geom.*; 31 import java.text.*; 32 33 34 41 final class TextArea extends FontArea { 42 43 44 private String text; 45 private Vector textLayouts; 46 private boolean rotateLeft; 47 private int textJustification; 48 private boolean needsUpdate; 49 50 51 58 TextArea () { 59 60 setText (""); 61 setRotateLeft (false); 62 setTextJustification (CENTER); 63 resetTextAreaModel (true); 64 needsUpdate = true; 65 } 66 67 68 72 final void setText (String t) { 73 74 needsUpdate = true; 75 text = t; 76 } 77 78 79 88 final void setRotateLeft (boolean r) { 89 90 needsUpdate = true; 91 rotateLeft = r; 92 } 93 94 95 107 final void setTextJustification (int which) { 108 109 needsUpdate = true; 110 if (which == TOP) textJustification = RIGHT; 111 else if (which == BOTTOM) textJustification = LEFT; 112 else textJustification = which; 113 } 114 115 116 120 final String getText() { 121 122 return text; 123 } 124 125 126 130 final boolean getRotateLeft () { 131 132 return rotateLeft; 133 } 134 135 136 140 final boolean getTextAreaNeedsUpdate() { 141 142 return (needsUpdate || getFontAreaNeedsUpdate()); 143 } 144 145 146 151 final void updateTextArea (Graphics2D g2D) { 152 153 if (getTextAreaNeedsUpdate()) { 154 updateFontArea (); 155 update (g2D); 156 } 157 needsUpdate = false; 158 } 159 160 161 173 final void resetTextAreaModel (boolean reset) { 174 175 needsUpdate = true; 176 resetFontAreaModel (reset); 177 } 178 179 180 185 final void paintComponent (Graphics2D g2D) { 186 187 updateTextArea (g2D); 188 super.paintComponent (g2D); 189 190 Color oldColor = g2D.getColor(); 191 g2D.setColor (getFontColor()); 192 193 int delta = 0; 194 int count = textLayouts.size(); 195 for (int i = 0; i < count; ++i) { 196 197 TextLayout layout = (TextLayout)textLayouts.get(i); 198 Shape shape = layout.getOutline(new AffineTransform()); 199 int ascent = (int)Math.abs (shape.getBounds(). y); 200 int descent = shape.getBounds().height - ascent; 201 int height = ascent + descent; 202 int leading = (int)layout.getLeading(); 203 204 if (!rotateLeft) { 205 206 int clipHeight = delta + height > getSpaceSize(MIN).height ? 207 getSpaceSize(MIN).height - delta : height; 208 Rectangle rect = new Rectangle 209 (getSpaceSizeLocation (MIN).x, getSpaceSizeLocation (MIN).y + delta, 210 getSpaceSize(MIN).width, clipHeight); 211 g2D.clip (rect); 212 int translateX; 213 if (textJustification == LEFT) { 214 translateX = 215 getSpaceSizeLocation (MIN).x - shape.getBounds().x; 216 } 217 else if (textJustification == RIGHT) { 218 translateX = getSpaceSizeLocation (MIN).x + getSpaceSize (MIN).width - 219 shape.getBounds().width - shape.getBounds().x; 220 } 221 else { 222 translateX = getSpaceSizeLocation (MIN).x + 223 (getSpaceSize (MIN).width - shape.getBounds().width) / 2 - 224 shape.getBounds().x; 225 } 226 int translateY = getSpaceSizeLocation (MIN).y + delta + ascent; 227 g2D.translate (translateX, translateY); 228 g2D.fill (shape); 229 230 g2D.setClip (null); 231 g2D.translate (-translateX, -translateY); 232 delta = delta + height + leading; 233 } 234 else { 235 236 int clipHeight = delta + height > getSpaceSize(MIN).width ? 237 getSpaceSize(MIN).width - delta : height; 238 Rectangle rect = new Rectangle 239 (getSpaceSizeLocation (MIN).x + delta, getSpaceSizeLocation (MIN).y, 240 clipHeight, getSpaceSize(MIN).height); 241 g2D.clip (rect); 242 int translateX = getSpaceSizeLocation (MIN).x + delta + ascent; 243 int translateY; 244 if (textJustification == LEFT) { 245 translateY = getSpaceSizeLocation (MIN).y + getSpaceSize(MIN).height + 246 shape.getBounds().x; 247 } 248 else if (textJustification == RIGHT) { 249 translateY = getSpaceSizeLocation (MIN).y + shape.getBounds().width + 250 shape.getBounds().x; 251 } 252 else { 253 translateY = getSpaceSizeLocation (MIN).y + 254 (getSpaceSize (MIN).height + shape.getBounds().width) / 2 255 + shape.getBounds().x; 256 } 257 g2D.translate (translateX, translateY); 258 g2D.rotate(Math.toRadians(-90d)); 259 g2D.fill (shape); 260 261 g2D.setClip (null); 262 g2D.rotate (Math.toRadians(90d)); 263 g2D.translate (-translateX, -translateY); 264 delta = delta + height + leading; 265 } 266 } 267 268 g2D.setColor (oldColor); 269 } 270 271 272 private void update (Graphics2D g2D) { 273 274 int greatestAdvance = 0; 275 int lineBreaksMeasurement = 0; 276 int leading = 0; 277 textLayouts = new Vector (0, 1); 278 if (text.length() > 0) { 279 int wrapping = 280 !rotateLeft ? getSpaceSize (MAX).width : getSpaceSize (MAX).height; 281 int mockWrapping = wrapping; 282 boolean fits = true; 283 AttributedString attributedString = 284 new AttributedString (text, getFont().getAttributes()); 285 AttributedCharacterIterator attributedCharacterIterator = 286 attributedString.getIterator(); 287 FontRenderContext fontRenderContext = g2D.getFontRenderContext(); 288 for(;;) { 289 LineBreakMeasurer measurer = new LineBreakMeasurer 290 (attributedCharacterIterator, fontRenderContext); 291 textLayouts = new Vector (0, 1); 292 greatestAdvance = 0; 293 lineBreaksMeasurement = 0; 294 for (TextLayout layout = measurer.nextLayout (mockWrapping); 295 layout != null; 296 layout = measurer.nextLayout(mockWrapping)) { 297 textLayouts.add (layout); 298 Shape shape = layout.getOutline(new AffineTransform()); 299 int width = shape.getBounds().width; 300 greatestAdvance = greatestAdvance < width ? width : greatestAdvance; 301 int ascent = (int)Math.abs (shape.getBounds().y); 302 int descent = shape.getBounds().height - ascent; 303 int height = ascent + descent; 304 leading = (int)layout.getLeading(); 305 lineBreaksMeasurement = lineBreaksMeasurement + height + leading; 306 307 } 308 lineBreaksMeasurement -= leading; 309 310 if (lineBreaksMeasurement > 311 (!rotateLeft ? getSpaceSize (MAX).height : getSpaceSize (MAX).width)) 312 { 313 fits = false; 314 greatestAdvance = 0; 315 lineBreaksMeasurement = 0; 316 textLayouts = new Vector(0,1); 317 break; 318 } 319 else if (greatestAdvance > wrapping) { 320 mockWrapping = mockWrapping - (greatestAdvance - mockWrapping); 321 if (mockWrapping <= 0) { 322 fits = false; 323 greatestAdvance = 0; 324 lineBreaksMeasurement = 0; 325 textLayouts = new Vector(0,1); 326 break; 327 } 328 } 330 else break; } 332 } 333 334 if (!getAutoSize (MIN)) { 335 if (!rotateLeft) { 336 setSpaceSize (MIN, 337 new Dimension (greatestAdvance, lineBreaksMeasurement)); 338 } 339 else { 340 setSpaceSize (MIN, 341 new Dimension (lineBreaksMeasurement, greatestAdvance)); 342 } 343 updateFontArea(); 344 } 345 } 346 } | Popular Tags |