1 50 51 package org.jfree.text; 52 53 import java.awt.Font ; 54 import java.awt.Graphics2D ; 55 import java.awt.Paint ; 56 import java.awt.Shape ; 57 import java.awt.geom.Rectangle2D ; 58 import java.io.Serializable ; 59 import java.util.Collections ; 60 import java.util.Iterator ; 61 import java.util.List ; 62 63 import org.jfree.ui.HorizontalAlignment; 64 import org.jfree.ui.Size2D; 65 import org.jfree.ui.TextAnchor; 66 import org.jfree.util.Log; 67 import org.jfree.util.LogContext; 68 import org.jfree.util.ShapeUtilities; 69 70 77 public class TextBlock implements Serializable { 78 79 80 private static final long serialVersionUID = -4333175719424385526L; 81 82 83 private List lines; 84 85 86 private HorizontalAlignment lineAlignment; 87 88 89 protected static final LogContext logger 90 = Log.createContext(TextBlock.class); 91 92 95 public TextBlock() { 96 this.lines = new java.util.ArrayList (); 97 this.lineAlignment = HorizontalAlignment.CENTER; 98 } 99 100 105 public HorizontalAlignment getLineAlignment() { 106 return this.lineAlignment; 107 } 108 109 114 public void setLineAlignment(HorizontalAlignment alignment) { 115 if (alignment == null) { 116 throw new IllegalArgumentException ("Null 'alignment' argument."); 117 } 118 this.lineAlignment = alignment; 119 } 120 121 128 public void addLine(final String text, final Font font, final Paint paint) { 129 addLine(new TextLine(text, font, paint)); 130 } 131 132 137 public void addLine(final TextLine line) { 138 this.lines.add(line); 139 } 140 141 146 public TextLine getLastLine() { 147 TextLine last = null; 148 final int index = this.lines.size() - 1; 149 if (index >= 0) { 150 last = (TextLine) this.lines.get(index); 151 } 152 return last; 153 } 154 155 160 public List getLines() { 161 return Collections.unmodifiableList(this.lines); 162 } 163 164 171 public Size2D calculateDimensions(final Graphics2D g2) { 172 double width = 0.0; 173 double height = 0.0; 174 final Iterator iterator = this.lines.iterator(); 175 while (iterator.hasNext()) { 176 final TextLine line = (TextLine) iterator.next(); 177 final Size2D dimension = line.calculateDimensions(g2); 178 width = Math.max(width, dimension.getWidth()); 179 height = height + dimension.getHeight(); 180 } 181 if (logger.isDebugEnabled()) { 182 logger.debug("width = " + width + ", height = " + height); 183 } 184 return new Size2D(width, height); 185 } 186 187 200 public Shape calculateBounds(final Graphics2D g2, 201 final float anchorX, final float anchorY, 202 final TextBlockAnchor anchor, 203 final float rotateX, final float rotateY, 204 final double angle) { 205 206 final Size2D d = calculateDimensions(g2); 207 final float[] offsets = calculateOffsets( 208 anchor, d.getWidth(), d.getHeight() 209 ); 210 final Rectangle2D bounds = new Rectangle2D.Double ( 211 anchorX + offsets[0], anchorY + offsets[1], 212 d.getWidth(), d.getHeight() 213 ); 214 final Shape rotatedBounds = ShapeUtilities.rotateShape( 215 bounds, angle, rotateX, rotateY 216 ); 217 return rotatedBounds; 218 219 } 220 221 229 public void draw(final Graphics2D g2, final float x, final float y, 230 final TextBlockAnchor anchor) { 231 draw(g2, x, y, anchor, 0.0f, 0.0f, 0.0); 232 } 233 234 247 public void draw(final Graphics2D g2, 248 final float anchorX, final float anchorY, 249 final TextBlockAnchor anchor, 250 final float rotateX, final float rotateY, 251 final double angle) { 252 253 final Size2D d = calculateDimensions(g2); 254 final float[] offsets = calculateOffsets(anchor, d.getWidth(), 255 d.getHeight()); 256 final Iterator iterator = this.lines.iterator(); 257 float yCursor = 0.0f; 258 while (iterator.hasNext()) { 259 TextLine line = (TextLine) iterator.next(); 260 Size2D dimension = line.calculateDimensions(g2); 261 float lineOffset = 0.0f; 262 if (this.lineAlignment == HorizontalAlignment.CENTER) { 263 lineOffset = (float) (d.getWidth() - dimension.getWidth()) 264 / 2.0f; 265 } 266 else if (this.lineAlignment == HorizontalAlignment.RIGHT) { 267 lineOffset = (float) (d.getWidth() - dimension.getWidth()); 268 } 269 line.draw( 270 g2, anchorX + offsets[0] + lineOffset, anchorY + offsets[1] + yCursor, 271 TextAnchor.TOP_LEFT, rotateX, rotateY, angle 272 ); 273 yCursor = yCursor + (float) dimension.getHeight(); 274 } 275 276 } 277 278 289 private float[] calculateOffsets(final TextBlockAnchor anchor, 290 final double width, final double height) { 291 final float[] result = new float[2]; 292 float xAdj = 0.0f; 293 float yAdj = 0.0f; 294 295 if (anchor == TextBlockAnchor.TOP_CENTER 296 || anchor == TextBlockAnchor.CENTER 297 || anchor == TextBlockAnchor.BOTTOM_CENTER) { 298 299 xAdj = (float) -width / 2.0f; 300 301 } 302 else if (anchor == TextBlockAnchor.TOP_RIGHT 303 || anchor == TextBlockAnchor.CENTER_RIGHT 304 || anchor == TextBlockAnchor.BOTTOM_RIGHT) { 305 306 xAdj = (float) -width; 307 308 } 309 310 if (anchor == TextBlockAnchor.TOP_LEFT 311 || anchor == TextBlockAnchor.TOP_CENTER 312 || anchor == TextBlockAnchor.TOP_RIGHT) { 313 314 yAdj = 0.0f; 315 316 } 317 else if (anchor == TextBlockAnchor.CENTER_LEFT 318 || anchor == TextBlockAnchor.CENTER 319 || anchor == TextBlockAnchor.CENTER_RIGHT) { 320 321 yAdj = (float) -height / 2.0f; 322 323 } 324 else if (anchor == TextBlockAnchor.BOTTOM_LEFT 325 || anchor == TextBlockAnchor.BOTTOM_CENTER 326 || anchor == TextBlockAnchor.BOTTOM_RIGHT) { 327 328 yAdj = (float) -height; 329 330 } 331 result[0] = xAdj; 332 result[1] = yAdj; 333 return result; 334 } 335 336 343 public boolean equals(final Object obj) { 344 if (obj == this) { 345 return true; 346 } 347 if (obj instanceof TextBlock) { 348 final TextBlock block = (TextBlock) obj; 349 return this.lines.equals(block.lines); 350 } 351 return false; 352 } 353 354 359 public int hashCode() { 360 return (this.lines != null ? this.lines.hashCode() : 0); 361 } 362 } 363 | Popular Tags |