KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > chart > title > LegendTitle


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ----------------
28  * LegendTitle.java
29  * ----------------
30  * (C) Copyright 2002-2006, by Object Refinery Limited.
31  *
32  * Original Author: David Gilbert (for Object Refinery Limited);
33  * Contributor(s): Pierre-Marie Le Biot;
34  *
35  * $Id: LegendTitle.java,v 1.20.2.7 2006/10/06 15:46:34 mungady Exp $
36  *
37  * Changes
38  * -------
39  * 25-Nov-2004 : First working version (DG);
40  * 11-Jan-2005 : Removed deprecated code in preparation for 1.0.0 release (DG);
41  * 08-Feb-2005 : Updated for changes in RectangleConstraint class (DG);
42  * 11-Feb-2005 : Implemented PublicCloneable (DG);
43  * 23-Feb-2005 : Replaced chart reference with LegendItemSource (DG);
44  * 16-Mar-2005 : Added itemFont attribute (DG);
45  * 17-Mar-2005 : Fixed missing fillShape setting (DG);
46  * 20-Apr-2005 : Added new draw() method (DG);
47  * 03-May-2005 : Modified equals() method to ignore sources (DG);
48  * 13-May-2005 : Added settings for legend item label and graphic padding (DG);
49  * 09-Jun-2005 : Fixed serialization bug (DG);
50  * 01-Sep-2005 : Added itemPaint attribute (PMLB);
51  * ------------- JFREECHART 1.0.0 ---------------------------------------------
52  * 20-Jul-2006 : Use new LegendItemBlockContainer to restore support for
53  * LegendItemEntities (DG);
54  * 06-Oct-2006 : Add tooltip and URL text to legend item (DG);
55  *
56  */

57
58 package org.jfree.chart.title;
59
60 import java.awt.Color JavaDoc;
61 import java.awt.Font JavaDoc;
62 import java.awt.Graphics2D JavaDoc;
63 import java.awt.Paint JavaDoc;
64 import java.awt.geom.Rectangle2D JavaDoc;
65 import java.io.IOException JavaDoc;
66 import java.io.ObjectInputStream JavaDoc;
67 import java.io.ObjectOutputStream JavaDoc;
68 import java.io.Serializable JavaDoc;
69
70 import org.jfree.chart.LegendItem;
71 import org.jfree.chart.LegendItemCollection;
72 import org.jfree.chart.LegendItemSource;
73 import org.jfree.chart.block.Arrangement;
74 import org.jfree.chart.block.Block;
75 import org.jfree.chart.block.BlockContainer;
76 import org.jfree.chart.block.BorderArrangement;
77 import org.jfree.chart.block.CenterArrangement;
78 import org.jfree.chart.block.ColumnArrangement;
79 import org.jfree.chart.block.FlowArrangement;
80 import org.jfree.chart.block.LabelBlock;
81 import org.jfree.chart.block.RectangleConstraint;
82 import org.jfree.chart.event.TitleChangeEvent;
83 import org.jfree.io.SerialUtilities;
84 import org.jfree.ui.RectangleAnchor;
85 import org.jfree.ui.RectangleEdge;
86 import org.jfree.ui.RectangleInsets;
87 import org.jfree.ui.Size2D;
88 import org.jfree.util.PaintUtilities;
89 import org.jfree.util.PublicCloneable;
90
91 /**
92  * A chart title that displays a legend for the data in the chart.
93  * <P>
94  * The title can be populated with legend items manually, or you can assign a
95  * reference to the plot, in which case the legend items will be automatically
96  * created to match the dataset(s).
97  */

98 public class LegendTitle extends Title
99                          implements Cloneable JavaDoc, PublicCloneable, Serializable JavaDoc {
100
101     /** For serialization. */
102     private static final long serialVersionUID = 2644010518533854633L;
103     
104     /** The default item font. */
105     public static final Font JavaDoc DEFAULT_ITEM_FONT
106         = new Font JavaDoc("SansSerif", Font.PLAIN, 12);
107
108     /** The default item paint. */
109     public static final Paint JavaDoc DEFAULT_ITEM_PAINT = Color.black;
110
111     /** The sources for legend items. */
112     private LegendItemSource[] sources;
113     
114     /** The background paint (possibly <code>null</code>). */
115     private transient Paint JavaDoc backgroundPaint;
116     
117     /** The edge for the legend item graphic relative to the text. */
118     private RectangleEdge legendItemGraphicEdge;
119     
120     /** The anchor point for the legend item graphic. */
121     private RectangleAnchor legendItemGraphicAnchor;
122     
123     /** The legend item graphic location. */
124     private RectangleAnchor legendItemGraphicLocation;
125     
126     /** The padding for the legend item graphic. */
127     private RectangleInsets legendItemGraphicPadding;
128
129     /** The item font. */
130     private Font JavaDoc itemFont;
131     
132     /** The item paint. */
133     private transient Paint JavaDoc itemPaint;
134
135     /** The padding for the item labels. */
136     private RectangleInsets itemLabelPadding;
137
138     /**
139      * A container that holds and displays the legend items.
140      */

141     private BlockContainer items;
142     
143     private Arrangement hLayout;
144     
145     private Arrangement vLayout;
146     
147     /**
148      * An optional container for wrapping the legend items (allows for adding
149      * a title or other text to the legend).
150      */

151     private BlockContainer wrapper;
152
153     /**
154      * Constructs a new (empty) legend for the specified source.
155      *
156      * @param source the source.
157      */

158     public LegendTitle(LegendItemSource source) {
159         this(source, new FlowArrangement(), new ColumnArrangement());
160     }
161     
162     /**
163      * Creates a new legend title with the specified arrangement.
164      *
165      * @param source the source.
166      * @param hLayout the horizontal item arrangement (<code>null</code> not
167      * permitted).
168      * @param vLayout the vertical item arrangement (<code>null</code> not
169      * permitted).
170      */

171     public LegendTitle(LegendItemSource source,
172                        Arrangement hLayout, Arrangement vLayout) {
173         this.sources = new LegendItemSource[] {source};
174         this.items = new BlockContainer(hLayout);
175         this.hLayout = hLayout;
176         this.vLayout = vLayout;
177         this.backgroundPaint = null;
178         this.legendItemGraphicEdge = RectangleEdge.LEFT;
179         this.legendItemGraphicAnchor = RectangleAnchor.CENTER;
180         this.legendItemGraphicLocation = RectangleAnchor.CENTER;
181         this.legendItemGraphicPadding = new RectangleInsets(2.0, 2.0, 2.0, 2.0);
182         this.itemFont = DEFAULT_ITEM_FONT;
183         this.itemPaint = DEFAULT_ITEM_PAINT;
184         this.itemLabelPadding = new RectangleInsets(2.0, 2.0, 2.0, 2.0);
185     }
186     
187     /**
188      * Returns the legend item sources.
189      *
190      * @return The sources.
191      */

192     public LegendItemSource[] getSources() {
193         return this.sources;
194     }
195     
196     /**
197      * Sets the legend item sources and sends a {@link TitleChangeEvent} to
198      * all registered listeners.
199      *
200      * @param sources the sources (<code>null</code> not permitted).
201      */

202     public void setSources(LegendItemSource[] sources) {
203         if (sources == null) {
204             throw new IllegalArgumentException JavaDoc("Null 'sources' argument.");
205         }
206         this.sources = sources;
207         notifyListeners(new TitleChangeEvent(this));
208     }
209
210     /**
211      * Returns the background paint.
212      *
213      * @return The background paint (possibly <code>null</code>).
214      */

215     public Paint JavaDoc getBackgroundPaint() {
216         return this.backgroundPaint;
217     }
218     
219     /**
220      * Sets the background paint for the legend and sends a
221      * {@link TitleChangeEvent} to all registered listeners.
222      *
223      * @param paint the paint (<code>null</code> permitted).
224      */

225     public void setBackgroundPaint(Paint JavaDoc paint) {
226         this.backgroundPaint = paint;
227         notifyListeners(new TitleChangeEvent(this));
228     }
229     
230     /**
231      * Returns the location of the shape within each legend item.
232      *
233      * @return The location (never <code>null</code>).
234      */

235     public RectangleEdge getLegendItemGraphicEdge() {
236         return this.legendItemGraphicEdge;
237     }
238     
239     /**
240      * Sets the location of the shape within each legend item.
241      *
242      * @param edge the edge (<code>null</code> not permitted).
243      */

244     public void setLegendItemGraphicEdge(RectangleEdge edge) {
245         if (edge == null) {
246             throw new IllegalArgumentException JavaDoc("Null 'edge' argument.");
247         }
248         this.legendItemGraphicEdge = edge;
249         notifyListeners(new TitleChangeEvent(this));
250     }
251     
252     /**
253      * Returns the legend item graphic anchor.
254      *
255      * @return The graphic anchor (never <code>null</code>).
256      */

257     public RectangleAnchor getLegendItemGraphicAnchor() {
258         return this.legendItemGraphicAnchor;
259     }
260     
261     /**
262      * Sets the anchor point used for the graphic in each legend item.
263      *
264      * @param anchor the anchor point (<code>null</code> not permitted).
265      */

266     public void setLegendItemGraphicAnchor(RectangleAnchor anchor) {
267         if (anchor == null) {
268             throw new IllegalArgumentException JavaDoc("Null 'anchor' point.");
269         }
270         this.legendItemGraphicAnchor = anchor;
271     }
272     
273     /**
274      * Returns the legend item graphic location.
275      *
276      * @return The location (never <code>null</code>).
277      */

278     public RectangleAnchor getLegendItemGraphicLocation() {
279         return this.legendItemGraphicLocation;
280     }
281     
282     /**
283      * Sets the legend item graphic location.
284      *
285      * @param anchor the anchor (<code>null</code> not permitted).
286      */

287     public void setLegendItemGraphicLocation(RectangleAnchor anchor) {
288         this.legendItemGraphicLocation = anchor;
289     }
290     
291     /**
292      * Returns the padding that will be applied to each item graphic.
293      *
294      * @return The padding (never <code>null</code>).
295      */

296     public RectangleInsets getLegendItemGraphicPadding() {
297         return this.legendItemGraphicPadding;
298     }
299     
300     /**
301      * Sets the padding that will be applied to each item graphic in the
302      * legend and sends a {@link TitleChangeEvent} to all registered listeners.
303      *
304      * @param padding the padding (<code>null</code> not permitted).
305      */

306     public void setLegendItemGraphicPadding(RectangleInsets padding) {
307         if (padding == null) {
308             throw new IllegalArgumentException JavaDoc("Null 'padding' argument.");
309         }
310         this.legendItemGraphicPadding = padding;
311         notifyListeners(new TitleChangeEvent(this));
312     }
313     
314     /**
315      * Returns the item font.
316      *
317      * @return The font (never <code>null</code>).
318      */

319     public Font JavaDoc getItemFont() {
320         return this.itemFont;
321     }
322     
323     /**
324      * Sets the item font and sends a {@link TitleChangeEvent} to
325      * all registered listeners.
326      *
327      * @param font the font (<code>null</code> not permitted).
328      */

329     public void setItemFont(Font JavaDoc font) {
330         if (font == null) {
331             throw new IllegalArgumentException JavaDoc("Null 'font' argument.");
332         }
333         this.itemFont = font;
334         notifyListeners(new TitleChangeEvent(this));
335     }
336     
337     /**
338      * Returns the item paint.
339      *
340      * @return The paint (never <code>null</code>).
341      */

342     public Paint JavaDoc getItemPaint() {
343         return this.itemPaint;
344     }
345    
346     /**
347      * Sets the item paint.
348      *
349      * @param paint the paint (<code>null</code> not permitted).
350      */

351     public void setItemPaint(Paint JavaDoc paint) {
352         if (paint == null) {
353             throw new IllegalArgumentException JavaDoc("Null 'paint' argument.");
354         }
355         this.itemPaint = paint;
356         notifyListeners(new TitleChangeEvent(this));
357     }
358    
359     /**
360      * Returns the padding used for the items labels.
361      *
362      * @return The padding (never <code>null</code>).
363      */

364     public RectangleInsets getItemLabelPadding() {
365         return this.itemLabelPadding;
366     }
367     
368     /**
369      * Sets the padding used for the item labels in the legend.
370      *
371      * @param padding the padding (<code>null</code> not permitted).
372      */

373     public void setItemLabelPadding(RectangleInsets padding) {
374         if (padding == null) {
375             throw new IllegalArgumentException JavaDoc("Null 'padding' argument.");
376         }
377         this.itemLabelPadding = padding;
378         notifyListeners(new TitleChangeEvent(this));
379     }
380     
381     /**
382      * Fetches the latest legend items.
383      */

384     protected void fetchLegendItems() {
385         this.items.clear();
386         RectangleEdge p = getPosition();
387         if (RectangleEdge.isTopOrBottom(p)) {
388             this.items.setArrangement(this.hLayout);
389         }
390         else {
391             this.items.setArrangement(this.vLayout);
392         }
393         for (int s = 0; s < this.sources.length; s++) {
394             LegendItemCollection legendItems = this.sources[s].getLegendItems();
395             if (legendItems != null) {
396                 for (int i = 0; i < legendItems.getItemCount(); i++) {
397                     LegendItem item = legendItems.get(i);
398                     Block block = createLegendItemBlock(item);
399                     this.items.add(block);
400                 }
401             }
402         }
403     }
404     
405     /**
406      * Creates a legend item block.
407      *
408      * @param item the legend item.
409      *
410      * @return The block.
411      */

412     protected Block createLegendItemBlock(LegendItem item) {
413         BlockContainer result = null;
414         LegendGraphic lg = new LegendGraphic(item.getShape(),
415                 item.getFillPaint());
416         lg.setShapeFilled(item.isShapeFilled());
417         lg.setLine(item.getLine());
418         lg.setLineStroke(item.getLineStroke());
419         lg.setLinePaint(item.getLinePaint());
420         lg.setLineVisible(item.isLineVisible());
421         lg.setShapeVisible(item.isShapeVisible());
422         lg.setShapeOutlineVisible(item.isShapeOutlineVisible());
423         lg.setOutlinePaint(item.getOutlinePaint());
424         lg.setOutlineStroke(item.getOutlineStroke());
425         lg.setPadding(this.legendItemGraphicPadding);
426
427         LegendItemBlockContainer legendItem = new LegendItemBlockContainer(
428                 new BorderArrangement(), item.getDatasetIndex(),
429                 item.getSeriesIndex());
430         lg.setShapeAnchor(getLegendItemGraphicAnchor());
431         lg.setShapeLocation(getLegendItemGraphicLocation());
432         legendItem.add(lg, this.legendItemGraphicEdge);
433         LabelBlock labelBlock = new LabelBlock(item.getLabel(), this.itemFont,
434                 this.itemPaint);
435         labelBlock.setPadding(this.itemLabelPadding);
436         legendItem.add(labelBlock);
437         legendItem.setToolTipText(item.getToolTipText());
438         legendItem.setURLText(item.getURLText());
439         
440         result = new BlockContainer(new CenterArrangement());
441         result.add(legendItem);
442         
443         return result;
444     }
445     
446     /**
447      * Returns the container that holds the legend items.
448      *
449      * @return The container for the legend items.
450      */

451     public BlockContainer getItemContainer() {
452         return this.items;
453     }
454
455     /**
456      * Arranges the contents of the block, within the given constraints, and
457      * returns the block size.
458      *
459      * @param g2 the graphics device.
460      * @param constraint the constraint (<code>null</code> not permitted).
461      *
462      * @return The block size (in Java2D units, never <code>null</code>).
463      */

464     public Size2D arrange(Graphics2D JavaDoc g2, RectangleConstraint constraint) {
465         Size2D result = new Size2D();
466         fetchLegendItems();
467         if (this.items.isEmpty()) {
468             return result;
469         }
470         BlockContainer container = this.wrapper;
471         if (container == null) {
472             container = this.items;
473         }
474         RectangleConstraint c = toContentConstraint(constraint);
475         Size2D size = container.arrange(g2, c);
476         result.height = calculateTotalHeight(size.height);
477         result.width = calculateTotalWidth(size.width);
478         return result;
479     }
480
481     /**
482      * Draws the title on a Java 2D graphics device (such as the screen or a
483      * printer).
484      *
485      * @param g2 the graphics device.
486      * @param area the available area for the title.
487      */

488     public void draw(Graphics2D JavaDoc g2, Rectangle2D JavaDoc area) {
489         draw(g2, area, null);
490     }
491
492     /**
493      * Draws the block within the specified area.
494      *
495      * @param g2 the graphics device.
496      * @param area the area.
497      * @param params ignored (<code>null</code> permitted).
498      *
499      * @return An {@link org.jfree.chart.block.EntityBlockResult} or
500      * <code>null</code>.
501      */

502     public Object JavaDoc draw(Graphics2D JavaDoc g2, Rectangle2D JavaDoc area, Object JavaDoc params) {
503         Rectangle2D JavaDoc target = (Rectangle2D JavaDoc) area.clone();
504         target = trimMargin(target);
505         if (this.backgroundPaint != null) {
506             g2.setPaint(this.backgroundPaint);
507             g2.fill(target);
508         }
509         getBorder().draw(g2, target);
510         getBorder().getInsets().trim(target);
511         BlockContainer container = this.wrapper;
512         if (container == null) {
513             container = this.items;
514         }
515         target = trimPadding(target);
516         return container.draw(g2, target, params);
517     }
518
519     /**
520      * Sets the wrapper container for the legend.
521      *
522      * @param wrapper the wrapper container.
523      */

524     public void setWrapper(BlockContainer wrapper) {
525         this.wrapper = wrapper;
526     }
527     
528     /**
529      * Tests this title for equality with an arbitrary object.
530      *
531      * @param obj the object (<code>null</code> permitted).
532      *
533      * @return A boolean.
534      */

535     public boolean equals(Object JavaDoc obj) {
536         if (obj == this) {
537             return true;
538         }
539         if (!(obj instanceof LegendTitle)) {
540             return false;
541         }
542         if (!super.equals(obj)) {
543             return false;
544         }
545         LegendTitle that = (LegendTitle) obj;
546         if (!PaintUtilities.equal(this.backgroundPaint, that.backgroundPaint)) {
547             return false;
548         }
549         if (this.legendItemGraphicEdge != that.legendItemGraphicEdge) {
550             return false;
551         }
552         if (this.legendItemGraphicAnchor != that.legendItemGraphicAnchor) {
553             return false;
554         }
555         if (this.legendItemGraphicLocation != that.legendItemGraphicLocation) {
556             return false;
557         }
558         if (!this.itemFont.equals(that.itemFont)) {
559             return false;
560         }
561         if (!this.itemPaint.equals(that.itemPaint)) {
562             return false;
563         }
564         if (!this.hLayout.equals(that.hLayout)) {
565             return false;
566         }
567         if (!this.vLayout.equals(that.vLayout)) {
568             return false;
569         }
570         return true;
571     }
572     
573     /**
574      * Provides serialization support.
575      *
576      * @param stream the output stream.
577      *
578      * @throws IOException if there is an I/O error.
579      */

580     private void writeObject(ObjectOutputStream JavaDoc stream) throws IOException JavaDoc {
581         stream.defaultWriteObject();
582         SerialUtilities.writePaint(this.backgroundPaint, stream);
583         SerialUtilities.writePaint(this.itemPaint, stream);
584     }
585
586     /**
587      * Provides serialization support.
588      *
589      * @param stream the input stream.
590      *
591      * @throws IOException if there is an I/O error.
592      * @throws ClassNotFoundException if there is a classpath problem.
593      */

594     private void readObject(ObjectInputStream JavaDoc stream)
595         throws IOException JavaDoc, ClassNotFoundException JavaDoc {
596         stream.defaultReadObject();
597         this.backgroundPaint = SerialUtilities.readPaint(stream);
598         this.itemPaint = SerialUtilities.readPaint(stream);
599     }
600
601 }
602
Popular Tags