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 * @return The font (never <code>null</code>). 097 */ 098 public Font getFont() { 099 return this.font; 100 } 101 102 /** 103 * Sets the font and regenerates the label. 104 * @param font the font (<code>null</code> not permitted). 105 */ 106 public void setFont(Font font) { 107 if (font == null) { 108 throw new IllegalArgumentException("Null 'font' argument."); 109 } 110 this.font = font; 111 this.label = TextUtilities.createTextBlock(this.text, font, this.paint); 112 this.label.setLineAlignment(HorizontalAlignment.LEFT); 113 } 114 115 /** 116 * Returns the paint. 117 * @return The paint (never <code>null</code>). 118 */ 119 public Paint getPaint() { 120 return this.paint; 121 } 122 123 /** 124 * Sets the paint and regenerates the label. 125 * @param paint the paint (<code>null</code> not permitted). 126 */ 127 public void setPaint(Paint paint) { 128 if (paint == null) { 129 throw new IllegalArgumentException("Null 'paint' argument."); 130 } 131 this.paint = paint; 132 this.label = TextUtilities.createTextBlock(this.text, this.font, this.paint); 133 this.label.setLineAlignment(HorizontalAlignment.LEFT); 134 } 135 136 /** 137 * Returns the tool tip text. 138 * @return The tool tip text (possibly <code>null</code>). 139 */ 140 public String getToolTipText() { 141 return this.toolTipText; 142 } 143 144 /** 145 * Sets the tool tip text. 146 * @param text the text (<code>null</code> permitted). 147 */ 148 public void setToolTipText(String text) { 149 this.toolTipText = text; 150 } 151 152 /** 153 * Returns the URL text. 154 * @return The URL text (possibly <code>null</code>). 155 */ 156 public String getURLText() { 157 return this.urlText; 158 } 159 160 /** 161 * Sets the URL text. 162 * @param text the text (<code>null</code> permitted). 163 */ 164 public void setURLText(String text) { 165 this.urlText = text; 166 } 167 168 /** 169 * Arranges the contents of the block, within the given constraints, and 170 * returns the block size. 171 * 172 * @param g2 the graphics device. 173 * @param constraint the constraint (<code>null</code> not permitted). 174 * 175 * @return The block size (in Java2D units, never <code>null</code>). 176 */ 177 public Size2D arrange(Graphics2D g2, RectangleConstraint constraint) { 178 g2.setFont(this.font); 179 Size2D s = this.label.calculateDimensions(g2); 180 return new Size2D(calculateTotalWidth(s.getWidth()), 181 calculateTotalHeight(s.getHeight())); 182 } 183 184 /** 185 * Draws the block. 186 * 187 * @param g2 the graphics device. 188 * @param area the area. 189 */ 190 public void draw(Graphics2D g2, Rectangle2D area) { 191 draw(g2, area, null); 192 } 193 194 /** 195 * Draws the block within the specified area. 196 * 197 * @param g2 the graphics device. 198 * @param area the area. 199 * @param params ignored (<code>null</code> permitted). 200 * 201 * @return Always <code>null</code>. 202 */ 203 public Object draw(Graphics2D g2, Rectangle2D area, Object params) { 204 area = trimMargin(area); 205 drawBorder(g2, area); 206 area = trimBorder(area); 207 area = trimPadding(area); 208 209 // check if we need to collect chart entities from the container 210 EntityBlockParams ebp = null; 211 StandardEntityCollection sec = null; 212 Shape entityArea = null; 213 if (params instanceof EntityBlockParams) { 214 ebp = (EntityBlockParams) params; 215 if (ebp.getGenerateEntities()) { 216 sec = new StandardEntityCollection(); 217 entityArea = (Shape) area.clone(); 218 } 219 } 220 g2.setPaint(this.paint); 221 g2.setFont(this.font); 222 this.label.draw(g2, (float) area.getX(), (float) area.getY(), 223 TextBlockAnchor.TOP_LEFT); 224 BlockResult result = null; 225 if (ebp != null && sec != null) { 226 if (this.toolTipText != null || this.urlText != null) { 227 ChartEntity entity = new ChartEntity(entityArea, 228 this.toolTipText, this.urlText); 229 sec.add(entity); 230 result = new BlockResult(); 231 result.setEntityCollection(sec); 232 } 233 } 234 return result; 235 } 236 237 /** 238 * Tests this <code>LabelBlock</code> for equality with an arbitrary 239 * object. 240 * 241 * @param obj the object (<code>null</code> permitted). 242 * 243 * @return A boolean. 244 */ 245 public boolean equals(Object obj) { 246 if (!(obj instanceof LabelBlock)) { 247 return false; 248 } 249 LabelBlock that = (LabelBlock) obj; 250 if (!this.text.equals(that.text)) { 251 return false; 252 } 253 if (!this.font.equals(that.font)) { 254 return false; 255 } 256 if (!PaintUtilities.equal(this.paint, that.paint)) { 257 return false; 258 } 259 if (!ObjectUtilities.equal(this.toolTipText, that.toolTipText)) { 260 return false; 261 } 262 if (!ObjectUtilities.equal(this.urlText, that.urlText)) { 263 return false; 264 } 265 return super.equals(obj); 266 } 267 268 /** 269 * Returns a clone of this <code>LabelBlock</code> instance. 270 * 271 * @return A clone. 272 * 273 * @throws CloneNotSupportedException if there is a problem cloning. 274 */ 275 public Object clone() throws CloneNotSupportedException { 276 return super.clone(); 277 } 278 279 /** 280 * Provides serialization support. 281 * 282 * @param stream the output stream. 283 * 284 * @throws IOException if there is an I/O error. 285 */ 286 private void writeObject(ObjectOutputStream stream) throws IOException { 287 stream.defaultWriteObject(); 288 SerialUtilities.writePaint(this.paint, stream); 289 } 290 291 /** 292 * Provides serialization support. 293 * 294 * @param stream the input stream. 295 * 296 * @throws IOException if there is an I/O error. 297 * @throws ClassNotFoundException if there is a classpath problem. 298 */ 299 private void readObject(ObjectInputStream stream) 300 throws IOException, ClassNotFoundException { 301 stream.defaultReadObject(); 302 this.paint = SerialUtilities.readPaint(stream); 303 } 304 305 }