KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > chart2d > TitledArea


1 /**
2  * Chart2D, a java library for drawing two dimensional charts.
3  * Copyright (C) 2001 Jason J. Simas
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * The author of this library may be contacted at:
19  * E-mail: jjsimas@users.sourceforge.net
20  * Street Address: J J Simas, 887 Tico Road, Ojai, CA 93023-3555 USA
21  */

22
23
24 package net.sourceforge.chart2d;
25
26
27 import java.awt.*;
28
29
30 /**
31  * A bordered area with a title and auto calculations for left over space. This
32  * class uses all the customizability of the bordered area class, adds a text
33  * area for the title, automatic gap below title functionality and title within
34  * area justification. The title can be located at the top, bottom, left or
35  * right, and sometimes centered. With
36  * any of these scenarios, the title can be rotated left. The left over space
37  * will be computed and is availabe through a get method.<br>
38  * Note: Do not pass any null values; instead pass an empty string if need be.
39  */

40 class TitledArea extends FontArea {
41
42
43   private boolean titleAutoLocate;
44   private boolean titleExistence;
45   private TextArea title;
46   private Rectangle maxEntitledSpaceBounds;
47   private Rectangle minEntitledSpaceBounds;
48   private Color titleBackgroundColor;
49   private boolean betweenTitleAndSpaceGapExistence;
50   private int betweenTitleAndSpaceGapThicknessModel;
51   private int betweenTitleAndSpaceGapThickness;
52   private Dimension minUsedSpaceSize;
53   private boolean needsUpdate;
54
55
56   /**
57    * Creates a new titled area with the default values:<br>
58    * setTitleExistence (true);<br>
59    * setFontPointModel (14);<br>
60    * setBetweenTitleAndSpaceGapExistence (true);<br>
61    * setBetweenTitleAndSpaceGapThicknessModel (5);<br>
62    * setTitleJustifications (CENTER, TOP);<br>
63    * setTitleAutoLocate (true);<br>
64    * title.setAutoJustifys (false, false);<br>
65    * title.setBorderExistences (false, false, false, false);<br>
66    * title.setGapExistences (false, false, false, false);<br>
67    * title.setBackgroundExistence (false);<br>
68    * resetTitledAreaModel (true);<br>
69    */

70   TitledArea() {
71
72     title = new TextArea();
73     maxEntitledSpaceBounds = new Rectangle();
74     minEntitledSpaceBounds = new Rectangle();
75
76     setTitleExistence (true);
77     setFontPointModel (14);
78     setBetweenTitleAndSpaceGapExistence (true);
79     setBetweenTitleAndSpaceGapThicknessModel (5);
80     setTitleJustifications (CENTER, TOP);
81     setTitleAutoLocate (true);
82
83     title.setAutoJustifys (false, false);
84     title.setBorderExistences (false, false, false, false);
85     title.setGapExistences (false, false, false, false);
86     title.setBackgroundExistence (false);
87     resetTitledAreaModel (true);
88     needsUpdate = true;
89   }
90
91
92   /**
93    * Changes the existence of the title; whether the title exists or not.
94    * Otherwise, title will not be included in calculations and will not be
95    * painted.
96    * @param existence If true, then title exists.
97    */

98   final void setTitleExistence (boolean existence) {
99
100     needsUpdate = true;
101     titleExistence = existence;
102   }
103
104
105   /**
106    * Changes the text of the title.
107    * @param title The new text of this title.
108    */

109   final void setTitle (String JavaDoc title) {
110
111     needsUpdate = true;
112     this.title.setText (title);
113   }
114
115
116   /**
117    * Changes whether the title will locate itself automatically within
118    * the area according to the title justifications. Otherwise, the title
119    * location must be set manually using the title set location method.
120    * @param auto true if the title will locate itself
121    */

122   final void setTitleAutoLocate (boolean auto) {
123
124     needsUpdate = true;
125     titleAutoLocate = auto;
126   }
127
128
129   /**
130    * Changes the location of the title. The top, left part of the title
131    * no matter what title orientation.
132    * @param location The top left part of the title's location.
133    */

134   final void setTitleLocation (Point location) {
135
136     needsUpdate = true;
137     title.setSpaceSizeLocation (MIN, location);
138   }
139
140
141   /**
142    * Changes whether this title should be rotated left of not.
143    * When rotating left, the text will be rotated -90 degrees. However, the
144    * origin and the size of the label will not be rotated. It will encapsulate
145    * the newly rotated text.
146    * @param rotate If true, then text will be rotated -90 degrees whenever
147    * painted. However, values are updated immediately.
148    */

149   final void setTitleRotateLeft (boolean rotate) {
150
151     needsUpdate = true;
152     title.setRotateLeft (rotate);
153   }
154
155
156   /**
157    * Specifies the horizontal and vertical justification for the title text
158    * respective to the size of the area. Note: A non rotated title cannot
159    * be vertically centered. And a rotated title cannot be horizontally
160    * centered.
161    * @param horizontal How to justify the title horizontally. Possible values
162    * area LEFT, RIGHT, and CENTER.
163    * [see note above for more detail about centering]
164    * @param vertical How to justify the title vertically. Possible values area
165    * TOP, BOTTOM, and CENTER. [see note above for more detail about centering]
166    */

167   final void setTitleJustifications (int horizontal, int vertical) {
168
169     needsUpdate = true;
170     title.setJustifications (horizontal, vertical);
171   }
172
173
174   /**
175    * Specifies whether there should exist a gap between title and the available
176    * space. Part of the functionality of this class is to calculate space not
177    * used by the title. Setting this gap, makes the available space less so
178    * drawing can begin exactly in the space, and look good becuase its spaced
179    * nicely from the title.
180    * @param existence If true, then gap is subtracted from space; else gap model
181    * thickness is ignored.
182    */

183   final void setBetweenTitleAndSpaceGapExistence (boolean existence) {
184
185     needsUpdate = true;
186     betweenTitleAndSpaceGapExistence = existence;
187   }
188
189
190   /**
191    * Specifies how large the model gap should be. Part of the functionality of
192    * this class is to calculate space not
193    * used by the title. This gap, makes the available space less so
194    * drawing can begin exactly in the space, and look good becuase its spaced
195    * nicely from the title.
196    * @param gap The thickness of the model gap. If model max size autosizing is
197    * disabled, then a ratio based on max size / model max size will be applied
198    * to this thickness to obtain the actual thickness; otherwise, the thickness
199    * will be this model thickness. Also, if gap existence is false, this
200    * thickness will be ignored.
201    */

202   final void setBetweenTitleAndSpaceGapThicknessModel (int gap) {
203
204     needsUpdate = true;
205     betweenTitleAndSpaceGapThicknessModel = gap;
206   }
207
208
209   /**
210    * Returns the model gap thickness between the title and the bounds.
211    * @return The thickness of the model gap.
212    */

213   final int getBetweenTitleAndSpaceGapThicknessModel() {
214
215     return betweenTitleAndSpaceGapThicknessModel;
216   }
217
218
219   /**
220    * Returns the available space and location of that space. The available
221    * space is the area less the title and the gap. Updates all variables
222    * before calculating the bounds.
223    * @param g2D The graphics context for calculations and painting.
224    * @return The bounds of the available space.
225    */

226   final Rectangle getMaxEntitledSpaceBounds (Graphics2D g2D) {
227
228     updateTitledArea (g2D);
229     return maxEntitledSpaceBounds;
230   }
231
232
233   /**
234    * Returns the available space and location of that space. The available
235    * space is the area less the title and the gap. Updates all variables
236    * before calculating the bounds.
237    * @param g2D The graphics context for calculations and painting.
238    * @return The bounds of the available space.
239    */

240   final Rectangle getMinEntitledSpaceBounds (Graphics2D g2D) {
241     updateTitledArea (g2D);
242     return minEntitledSpaceBounds;
243   }
244
245
246   /**
247    * Returns the existence of the title; whether the title exists or not.
248    * @return If true, then title exists.
249    */

250   final boolean getTitleExistence () {
251
252     return titleExistence;
253   }
254
255
256   /**
257    * Gets the text of the title.
258    * @return The new text of this title.
259    */

260   final String JavaDoc getTitleText() {
261
262     return title.getText();
263   }
264
265
266   /**
267    * Gets the title.
268    * @return The title's TextArea.
269    */

270   final TextArea getTitle() {
271     return title;
272   }
273
274
275   /**
276    * Returns the size of this title. Even if the title is rotated, the width
277    * of this dimension will correspond to width on the monitor screen, and
278    * not height. The same is true for the height of the dimension.
279    * @return The size of the title.
280    * @param which Which size MAXMODEL, MAX, or MIN.
281    * @param g2D The graphics context for calculations and painting.
282    */

283   final Dimension getTitleSize (int which, Graphics2D g2D) {
284
285     updateTitledArea (g2D);
286     return title.getSize (which);
287   }
288
289
290   /**
291    * Returns the horizontal or vertical justification of this title within the
292    * area.
293    * @param which Which type of justification to return. Possible values are
294    * HORIZONTAL and VERTICAL.
295    * @return The justification of this title. Possible values of
296    * horizontal justification area LEFT, RIGHT, and CENTER. Possible values of
297    * vertical justification are TOP, BOTTOM, and CENTER.
298    */

299   final int getTitleJustifications (int which) {
300
301     return title.getJustifications (which);
302   }
303
304
305   /**
306    * Indicates whether the title will locate itself automatically within
307    * the area according to the title justifications. Otherwise, the title
308    * location must be set manually using the title set location method.
309    * @return True if the title will locate itself
310    */

311   final boolean getTitleAutoLocate () {
312
313     return titleAutoLocate;
314   }
315
316
317   /**
318    * Returns the gap between the title and the available space. This is not
319    * the model gap thickness but the actual thickness, after applying the ratio
320    * when relevant. All variables area updated before returning this size.
321    * @param g2D The graphics context to use for calculations.
322    * @return The thickness of the gap between the title and the available space.
323    */

324   final int getBetweenTitleAndSpaceGapThickness (Graphics2D g2D) {
325
326     updateTitledArea (g2D);
327     return betweenTitleAndSpaceGapThickness;
328   }
329
330
331   /**
332    * Indicates whether some property of this class has changed.
333    * @return True if some property has changed.
334    */

335   final boolean getTitledAreaNeedsUpdate() {
336
337     return (needsUpdate || getFontAreaNeedsUpdate());
338   }
339
340
341   /**
342    * Updates all the variables in this parent's classes, then all of this'
343    * variables.
344    * @param g2D The graphics context to use for calculations.
345    */

346   final void updateTitledArea (Graphics2D g2D) {
347
348     if (getTitledAreaNeedsUpdate()) {
349       updateFontArea();
350       update (g2D);
351     }
352     needsUpdate = false;
353   }
354
355
356   /**
357    * Resets the model for this class. The model is used for shrinking and
358    * growing of its components based on the maximum size of this class. If this
359    * method is called, then the next time the maximum size is set, this classes
360    * model maximum size will be made equal to the new maximum size. Effectively
361    * what this does is ensure that whenever this objects maximum size is equal
362    * to the one given, then all of the components will take on their default
363    * model sizes. Note: This is only useful when auto model max sizing is
364    * disabled.
365    * @param reset True sets the max model size on the next max sizing.
366    */

367   final void resetTitledAreaModel (boolean reset) {
368
369     needsUpdate = true;
370     resetFontAreaModel (reset);
371     title.resetTextAreaModel (reset);
372   }
373
374
375   /**
376    * Paints all the components of this class. First all variables are updated.
377    * @param g2D The graphics context for calculations and painting.
378    */

379   void paintComponent (Graphics2D g2D) {
380
381     updateTitledArea (g2D);
382     super.paintComponent (g2D);
383     title.paintComponent (g2D);
384   }
385
386
387   private void update (Graphics2D g2D) {
388     updateMaxTitle();
389     title.updateTextArea (g2D);
390     updateGap();
391     updateMaxBounds (g2D);
392     updateMinBounds (g2D);
393     updateMinTitle();
394   }
395
396
397   private void updateMaxTitle() {
398
399     if (titleExistence) {
400       title.setCustomRatio (WIDTH, true, getRatio (WIDTH));
401       title.setCustomRatio (HEIGHT, true, getRatio (HEIGHT));
402       title.setAutoSizes (getAutoSize (MAXMODEL), false);
403       title.setSizeLocation (MAX, new Point (
404         getSpaceSizeLocation (MAX).x, getSpaceSizeLocation (MAX).y));
405       Dimension titleSize = new Dimension (
406         getSpaceSize (MAX).width, getSpaceSize (MAX).height);
407       title.setSize (MAX, titleSize);
408       title.setFontPointModel (getFontPointModel());
409       title.setFontColor (getFontColor());
410       title.setFontName (getFont().getName());
411       title.setFontStyle (getFont().getStyle());
412     }
413     else title.setSize (MAX, new Dimension());
414   }
415
416
417   private void updateGap() {
418
419     if (betweenTitleAndSpaceGapExistence) {
420
421       float ratio;
422       int available;
423       if (!title.getRotateLeft()) {
424         ratio = getRatio (HEIGHT);
425         available = getSpaceSize (MAX).height - title.getSize (MIN).height;
426       }
427       else {
428         ratio = getRatio (WIDTH);
429         available = getSpaceSize (MAX).width - title.getSize (MIN).width;
430       }
431
432       if (titleExistence &&
433         title.getSize (MIN).width > 0 && title.getSize (MIN).height > 0) {
434         betweenTitleAndSpaceGapThickness =
435           applyRatio (betweenTitleAndSpaceGapThicknessModel, ratio);
436         betweenTitleAndSpaceGapThickness =
437           betweenTitleAndSpaceGapThickness < available ?
438           betweenTitleAndSpaceGapThickness : available;
439       }
440       else betweenTitleAndSpaceGapThickness = 0;
441     }
442
443     else betweenTitleAndSpaceGapThickness = 0;
444   }
445
446
447   private void updateMaxBounds (Graphics2D g2D) {
448
449     int spaceX;
450     int spaceY;
451     int spaceWidth;
452     int spaceHeight;
453     if (!title.getRotateLeft()) {
454       spaceX = getSpaceSizeLocation (MAX).x;
455       spaceWidth = getSpaceSize (MAX).width;
456       spaceHeight = getSpaceSize (MAX).height -
457         (title.getSize (MIN).height + betweenTitleAndSpaceGapThickness);
458       if (title.getJustifications (VERTICAL) == TOP) {
459         spaceY = getSpaceSizeLocation (MAX).y +
460         title.getSize (MIN).height + betweenTitleAndSpaceGapThickness;
461       }
462       else spaceY = getSpaceSizeLocation (MAX).y;
463     }
464     else {
465       spaceY = getSpaceSizeLocation (MAX).y;
466       spaceWidth = getSpaceSize (MAX).width -
467         (title.getSize (MIN).width + betweenTitleAndSpaceGapThickness);
468       spaceHeight = getSpaceSize (MAX).height;
469       if (title.getJustifications (HORIZONTAL) == LEFT) {
470         spaceX = getSpaceSizeLocation (MAX).x +
471         title.getSize (MIN).width + betweenTitleAndSpaceGapThickness;
472       }
473       else spaceX = getSpaceSizeLocation (MAX).x;
474     }
475     maxEntitledSpaceBounds.setBounds (spaceX, spaceY, spaceWidth, spaceHeight);
476   }
477
478
479   private void updateMinBounds (Graphics2D g2D) {
480
481     int spaceX;
482     int spaceY;
483     int spaceWidth;
484     int spaceHeight;
485     if (!title.getRotateLeft()) {
486       spaceX = getSpaceSizeLocation (MIN).x;
487       spaceWidth = getSpaceSize (MIN).width;
488       spaceHeight = getSpaceSize (MIN).height -
489         (title.getSize (MIN).height + betweenTitleAndSpaceGapThickness);
490       if (title.getJustifications (VERTICAL) == TOP) {
491         spaceY = getSpaceSizeLocation (MIN).y +
492         title.getSize (MIN).height + betweenTitleAndSpaceGapThickness;
493       }
494       else spaceY = getSpaceSizeLocation (MIN).y;
495     }
496     else {
497       spaceY = getSpaceSizeLocation (MIN).y;
498       spaceWidth = getSpaceSize (MIN).width -
499         (title.getSize (MIN).width + betweenTitleAndSpaceGapThickness);
500       spaceHeight = getSpaceSize (MIN).height;
501       if (title.getJustifications (HORIZONTAL) == LEFT) {
502         spaceX = getSpaceSizeLocation (MIN).x +
503         title.getSize (MIN).width + betweenTitleAndSpaceGapThickness;
504       }
505       else spaceX = getSpaceSizeLocation (MIN).x;
506     }
507     minEntitledSpaceBounds.setBounds (spaceX, spaceY, spaceWidth, spaceHeight);
508   }
509
510
511   private void updateMinTitle() {
512
513     if (titleAutoLocate) {
514
515       int betweenWidth = title.getSizeLocation (MIN).x -
516         title.getSpaceSizeLocation (MIN).x;
517       int spaceX;
518       if (title.getJustifications (HORIZONTAL) == LEFT) {
519         spaceX = getSpaceSizeLocation (MIN).x + betweenWidth;
520       }
521       else if (title.getJustifications (HORIZONTAL) == RIGHT) {
522         spaceX = getSpaceSizeLocation (MIN).x + getSpaceSize (MIN).width -
523           title.getSpaceSize (MIN).width - betweenWidth;
524       }
525       else {
526         spaceX = getSpaceSizeLocation(MIN).x +
527           (getSpaceSize (MIN).width - title.getSpaceSize (MIN).width) / 2;
528       }
529
530       int betweenHeight =
531         title.getSpaceSizeLocation (MIN).y - title.getSizeLocation (MIN).y;
532       int spaceY;
533       if (title.getJustifications (VERTICAL) == TOP) {
534         spaceY = getSpaceSizeLocation (MIN).y + betweenHeight;
535       }
536       else if (title.getJustifications (VERTICAL) == BOTTOM) {
537         spaceY = getSpaceSizeLocation (MIN).y + getSpaceSize (MIN).height -
538           title.getSpaceSize (MIN).height - betweenHeight;
539       }
540       else {
541         spaceY = getSpaceSizeLocation(MIN).y +
542           (getSpaceSize (MIN).height - title.getSpaceSize (MIN).height) / 2;
543       }
544       title.setSpaceSizeLocation (MIN, new Point (spaceX, spaceY));
545     }
546   }
547 }
Popular Tags