001 package org.jfree.chart.block; 002 003 import java.awt.Color; 004 import java.awt.Font; 005 import java.awt.Graphics2D; 006 import java.awt.Paint; 007 import java.awt.Shape; 008 import java.awt.geom.Rectangle2D; 009 import java.io.IOException; 010 import java.io.ObjectInputStream; 011 import java.io.ObjectOutputStream; 012 013 import org.jfree.chart.entity.ChartEntity; 014 import org.jfree.chart.entity.StandardEntityCollection; 015 import org.jfree.io.SerialUtilities; 016 import org.jfree.text.TextBlock; 017 import org.jfree.text.TextBlockAnchor; 018 import org.jfree.text.TextUtilities; 019 import org.jfree.ui.HorizontalAlignment; 020 import org.jfree.ui.Size2D; 021 import org.jfree.util.ObjectUtilities; 022 import org.jfree.util.PaintUtilities; 023 import org.jfree.util.PublicCloneable; 024 025 /** 026 * A block containing a label. 027 */ 028 public class LabelBlock extends AbstractBlock 029 implements Block, PublicCloneable { 030 031 /** For serialization. */ 032 static final long serialVersionUID = 249626098864178017L; 033 034 /** 035 * The text for the label - retained in case the label needs 036 * regenerating (for example, to change the font). 037 */ 038 private String text; 039 040 /** The label. */ 041 private TextBlock label; 042 043 /** The font. */ 044 private Font font; 045 046 /** The tool tip text (can be <code>null</code>). */ 047 private String toolTipText; 048 049 /** The URL text (can be <code>null</code>). */ 050 private String urlText; 051 052 /** The default color. */ 053 public static final Paint DEFAULT_PAINT = Color.black; 054 055 /** The paint. */ 056 private transient Paint paint; 057 058 /** 059 * Creates a new label block. 060 * 061 * @param label the label (<code>null</code> not permitted). 062 */ 063 public LabelBlock(String label) { 064 this(label, new Font("SansSerif", Font.PLAIN, 10), DEFAULT_PAINT); 065 } 066 067 /** 068 * Creates a new label block. 069 * 070 * @param text the text for the label (<code>null</code> not permitted). 071 * @param font the font (<code>null</code> not permitted). 072 */ 073 public LabelBlock(String text, Font font) { 074 this(text, font, DEFAULT_PAINT); 075 } 076 077 /** 078 * Creates a new label block. 079 * 080 * @param text the text for the label (<code>null</code> not permitted). 081 * @param font the font (<code>null</code> not permitted). 082 * @param paint the paint (<code>null</code> not permitted). 083 */ 084 public LabelBlock(String text, Font font, Paint paint) { 085 this.text = text; 086 this.paint = paint; 087 this.label = TextUtilities.createTextBlock(text, font, this.paint); 088 this.label.setLineAlignment(HorizontalAlignment.LEFT); 089 this.font = font; 090 this.toolTipText = null; 091 this.urlText = null; 092 } 093 094 /** 095 * Returns the font. 096 * 097 * @return The font (never <code>null</code>). 098 * 099 * @see #setFont(Font) 100 */ 101 public Font getFont() { 102 return this.font; 103 } 104 105 /** 106 * Sets the font and regenerates the label. 107 * 108 * @param font the font (<code>null</code> not permitted). 109 * 110 * @see #getFont() 111 */ 112 public void setFont(Font font) { 113 if (font == null) { 114 throw new IllegalArgumentException("Null 'font' argument."); 115 } 116 this.font = font; 117 this.label = TextUtilities.createTextBlock(this.text, font, this.paint); 118 this.label.setLineAlignment(HorizontalAlignment.LEFT); 119 } 120 121 /** 122 * Returns the paint. 123 * 124 * @return The paint (never <code>null</code>). 125 * 126 * @see #setPaint(Paint) 127 */ 128 public Paint getPaint() { 129 return this.paint; 130 } 131 132 /** 133 * Sets the paint and regenerates the label. 134 * 135 * @param paint the paint (<code>null</code> not permitted). 136 * 137 * @see #getPaint() 138 */ 139 public void setPaint(Paint paint) { 140 if (paint == null) { 141 throw new IllegalArgumentException("Null 'paint' argument."); 142 } 143 this.paint = paint; 144 this.label = TextUtilities.createTextBlock(this.text, this.font, this.paint); 145 this.label.setLineAlignment(HorizontalAlignment.LEFT); 146 } 147 148 /** 149 * Returns the tool tip text. 150 * 151 * @return The tool tip text (possibly <code>null</code>). 152 * 153 * @see #setToolTipText(String) 154 */ 155 public String getToolTipText() { 156 return this.toolTipText; 157 } 158 159 /** 160 * Sets the tool tip text. 161 * 162 * @param text the text (<code>null</code> permitted). 163 * 164 * @see #getToolTipText() 165 */ 166 public void setToolTipText(String text) { 167 this.toolTipText = text; 168 } 169 170 /** 171 * Returns the URL text. 172 * 173 * @return The URL text (possibly <code>null</code>). 174 * 175 * @see #setURLText(String) 176 */ 177 public String getURLText() { 178 return this.urlText; 179 } 180 181 /** 182 * Sets the URL text. 183 * 184 * @param text the text (<code>null</code> permitted). 185 * 186 * @see #getURLText() 187 */ 188 public void setURLText(String text) { 189 this.urlText = text; 190 } 191 192 /** 193 * Arranges the contents of the block, within the given constraints, and 194 * returns the block size. 195 * 196 * @param g2 the graphics device. 197 * @param constraint the constraint (<code>null</code> not permitted). 198 * 199 * @return The block size (in Java2D units, never <code>null</code>). 200 */ 201 public Size2D arrange(Graphics2D g2, RectangleConstraint constraint) { 202 g2.setFont(this.font); 203 Size2D s = this.label.calculateDimensions(g2); 204 return new Size2D(calculateTotalWidth(s.getWidth()), 205 calculateTotalHeight(s.getHeight())); 206 } 207 208 /** 209 * Draws the block. 210 * 211 * @param g2 the graphics device. 212 * @param area the area. 213 */ 214 public void draw(Graphics2D g2, Rectangle2D area) { 215 draw(g2, area, null); 216 } 217 218 /** 219 * Draws the block within the specified area. 220 * 221 * @param g2 the graphics device. 222 * @param area the area. 223 * @param params ignored (<code>null</code> permitted). 224 * 225 * @return Always <code>null</code>. 226 */ 227 public Object draw(Graphics2D g2, Rectangle2D area, Object params) { 228 area = trimMargin(area); 229 drawBorder(g2, area); 230 area = trimBorder(area); 231 area = trimPadding(area); 232 233 // check if we need to collect chart entities from the container 234 EntityBlockParams ebp = null; 235 StandardEntityCollection sec = null; 236 Shape entityArea = null; 237 if (params instanceof EntityBlockParams) { 238 ebp = (EntityBlockParams) params; 239 if (ebp.getGenerateEntities()) { 240 sec = new StandardEntityCollection(); 241 entityArea = (Shape) area.clone(); 242 } 243 } 244 g2.setPaint(this.paint); 245 g2.setFont(this.font); 246 this.label.draw(g2, (float) area.getX(), (float) area.getY(), 247 TextBlockAnchor.TOP_LEFT); 248 BlockResult result = null; 249 if (ebp != null && sec != null) { 250 if (this.toolTipText != null || this.urlText != null) { 251 ChartEntity entity = new ChartEntity(entityArea, 252 this.toolTipText, this.urlText); 253 sec.add(entity); 254 result = new BlockResult(); 255 result.setEntityCollection(sec); 256 } 257 } 258 return result; 259 } 260 261 /** 262 * Tests this <code>LabelBlock</code> for equality with an arbitrary 263 * object. 264 * 265 * @param obj the object (<code>null</code> permitted). 266 * 267 * @return A boolean. 268 */ 269 public boolean equals(Object obj) { 270 if (!(obj instanceof LabelBlock)) { 271 return false; 272 } 273 LabelBlock that = (LabelBlock) obj; 274 if (!this.text.equals(that.text)) { 275 return false; 276 } 277 if (!this.font.equals(that.font)) { 278 return false; 279 } 280 if (!PaintUtilities.equal(this.paint, that.paint)) { 281 return false; 282 } 283 if (!ObjectUtilities.equal(this.toolTipText, that.toolTipText)) { 284 return false; 285 } 286 if (!ObjectUtilities.equal(this.urlText, that.urlText)) { 287 return false; 288 } 289 return super.equals(obj); 290 } 291 292 /** 293 * Returns a clone of this <code>LabelBlock</code> instance. 294 * 295 * @return A clone. 296 * 297 * @throws CloneNotSupportedException if there is a problem cloning. 298 */ 299 public Object clone() throws CloneNotSupportedException { 300 return super.clone(); 301 } 302 303 /** 304 * Provides serialization support. 305 * 306 * @param stream the output stream. 307 * 308 * @throws IOException if there is an I/O error. 309 */ 310 private void writeObject(ObjectOutputStream stream) throws IOException { 311 stream.defaultWriteObject(); 312 SerialUtilities.writePaint(this.paint, stream); 313 } 314 315 /** 316 * Provides serialization support. 317 * 318 * @param stream the input stream. 319 * 320 * @throws IOException if there is an I/O error. 321 * @throws ClassNotFoundException if there is a classpath problem. 322 */ 323 private void readObject(ObjectInputStream stream) 324 throws IOException, ClassNotFoundException { 325 stream.defaultReadObject(); 326 this.paint = SerialUtilities.readPaint(stream); 327 } 328 329 }