1:
79:
80: package ;
81:
82: import ;
83: import ;
84: import ;
85: import ;
86: import ;
87: import ;
88: import ;
89: import ;
90: import ;
91:
92: import ;
93: import ;
94: import ;
95: import ;
96: import ;
97: import ;
98: import ;
99: import ;
100: import ;
101: import ;
102: import ;
103: import ;
104: import ;
105: import ;
106: import ;
107: import ;
108: import ;
109: import ;
110: import ;
111: import ;
112: import ;
113: import ;
114:
115:
119: public class TextTitle extends Title
120: implements Serializable, Cloneable, PublicCloneable {
121:
122:
123: private static final long serialVersionUID = 8372008692127477443L;
124:
125:
126: public static final Font DEFAULT_FONT = new Font("SansSerif", Font.BOLD,
127: 12);
128:
129:
130: public static final Paint DEFAULT_TEXT_PAINT = Color.black;
131:
132:
133: private String text;
134:
135:
136: private Font font;
137:
138:
139: private HorizontalAlignment textAlignment;
140:
141:
142: private transient Paint paint;
143:
144:
145: private transient Paint backgroundPaint;
146:
147:
148: private String toolTipText;
149:
150:
151: private String urlText;
152:
153:
154: private TextBlock content;
155:
156:
160: private boolean expandToFitSpace = false;
161:
162:
165: public TextTitle() {
166: this("");
167: }
168:
169:
174: public TextTitle(String text) {
175: this(text, TextTitle.DEFAULT_FONT, TextTitle.DEFAULT_TEXT_PAINT,
176: Title.DEFAULT_POSITION, Title.DEFAULT_HORIZONTAL_ALIGNMENT,
177: Title.DEFAULT_VERTICAL_ALIGNMENT, Title.DEFAULT_PADDING);
178: }
179:
180:
186: public TextTitle(String text, Font font) {
187: this(text, font, TextTitle.DEFAULT_TEXT_PAINT, Title.DEFAULT_POSITION,
188: Title.DEFAULT_HORIZONTAL_ALIGNMENT,
189: Title.DEFAULT_VERTICAL_ALIGNMENT, Title.DEFAULT_PADDING);
190: }
191:
192:
205: public TextTitle(String text, Font font, Paint paint,
206: RectangleEdge position,
207: HorizontalAlignment horizontalAlignment,
208: VerticalAlignment verticalAlignment,
209: RectangleInsets padding) {
210:
211: super(position, horizontalAlignment, verticalAlignment, padding);
212:
213: if (text == null) {
214: throw new NullPointerException("Null 'text' argument.");
215: }
216: if (font == null) {
217: throw new NullPointerException("Null 'font' argument.");
218: }
219: if (paint == null) {
220: throw new NullPointerException("Null 'paint' argument.");
221: }
222: this.text = text;
223: this.font = font;
224: this.paint = paint;
225:
226:
227:
228: this.textAlignment = horizontalAlignment;
229: this.backgroundPaint = null;
230: this.content = null;
231: this.toolTipText = null;
232: this.urlText = null;
233:
234: }
235:
236:
243: public String getText() {
244: return this.text;
245: }
246:
247:
253: public void setText(String text) {
254: if (text == null) {
255: throw new IllegalArgumentException("Null 'text' argument.");
256: }
257: if (!this.text.equals(text)) {
258: this.text = text;
259: notifyListeners(new TitleChangeEvent(this));
260: }
261: }
262:
263:
271: public HorizontalAlignment getTextAlignment() {
272: return this.textAlignment;
273: }
274:
275:
280: public void setTextAlignment(HorizontalAlignment alignment) {
281: if (alignment == null) {
282: throw new IllegalArgumentException("Null 'alignment' argument.");
283: }
284: this.textAlignment = alignment;
285: notifyListeners(new TitleChangeEvent(this));
286: }
287:
288:
295: public Font getFont() {
296: return this.font;
297: }
298:
299:
307: public void setFont(Font font) {
308: if (font == null) {
309: throw new IllegalArgumentException("Null 'font' argument.");
310: }
311: if (!this.font.equals(font)) {
312: this.font = font;
313: notifyListeners(new TitleChangeEvent(this));
314: }
315: }
316:
317:
324: public Paint getPaint() {
325: return this.paint;
326: }
327:
328:
336: public void setPaint(Paint paint) {
337: if (paint == null) {
338: throw new IllegalArgumentException("Null 'paint' argument.");
339: }
340: if (!this.paint.equals(paint)) {
341: this.paint = paint;
342: notifyListeners(new TitleChangeEvent(this));
343: }
344: }
345:
346:
351: public Paint getBackgroundPaint() {
352: return this.backgroundPaint;
353: }
354:
355:
362: public void setBackgroundPaint(Paint paint) {
363: this.backgroundPaint = paint;
364: notifyListeners(new TitleChangeEvent(this));
365: }
366:
367:
372: public String getToolTipText() {
373: return this.toolTipText;
374: }
375:
376:
382: public void setToolTipText(String text) {
383: this.toolTipText = text;
384: notifyListeners(new TitleChangeEvent(this));
385: }
386:
387:
392: public String getURLText() {
393: return this.urlText;
394: }
395:
396:
402: public void setURLText(String text) {
403: this.urlText = text;
404: notifyListeners(new TitleChangeEvent(this));
405: }
406:
407:
413: public boolean getExpandToFitSpace() {
414: return this.expandToFitSpace;
415: }
416:
417:
424: public void setExpandToFitSpace(boolean expand) {
425: this.expandToFitSpace = expand;
426: notifyListeners(new TitleChangeEvent(this));
427: }
428:
429:
438: public Size2D arrange(Graphics2D g2, RectangleConstraint constraint) {
439: RectangleConstraint cc = toContentConstraint(constraint);
440: LengthConstraintType w = cc.getWidthConstraintType();
441: LengthConstraintType h = cc.getHeightConstraintType();
442: Size2D contentSize = null;
443: if (w == LengthConstraintType.NONE) {
444: if (h == LengthConstraintType.NONE) {
445: contentSize = arrangeNN(g2);
446: }
447: else if (h == LengthConstraintType.RANGE) {
448: throw new RuntimeException("Not yet implemented.");
449: }
450: else if (h == LengthConstraintType.FIXED) {
451: throw new RuntimeException("Not yet implemented.");
452: }
453: }
454: else if (w == LengthConstraintType.RANGE) {
455: if (h == LengthConstraintType.NONE) {
456: contentSize = arrangeRN(g2, cc.getWidthRange());
457: }
458: else if (h == LengthConstraintType.RANGE) {
459: contentSize = arrangeRR(g2, cc.getWidthRange(),
460: cc.getHeightRange());
461: }
462: else if (h == LengthConstraintType.FIXED) {
463: throw new RuntimeException("Not yet implemented.");
464: }
465: }
466: else if (w == LengthConstraintType.FIXED) {
467: if (h == LengthConstraintType.NONE) {
468: contentSize = arrangeFN(g2, cc.getWidth());
469: }
470: else if (h == LengthConstraintType.RANGE) {
471: throw new RuntimeException("Not yet implemented.");
472: }
473: else if (h == LengthConstraintType.FIXED) {
474: throw new RuntimeException("Not yet implemented.");
475: }
476: }
477: return new Size2D(calculateTotalWidth(contentSize.getWidth()),
478: calculateTotalHeight(contentSize.getHeight()));
479: }
480:
481:
493: protected Size2D arrangeNN(Graphics2D g2) {
494: Range max = new Range(0.0, Float.MAX_VALUE);
495: return arrangeRR(g2, max, max);
496: }
497:
498:
511: protected Size2D arrangeFN(Graphics2D g2, double w) {
512: RectangleEdge position = getPosition();
513: if (position == RectangleEdge.TOP || position == RectangleEdge.BOTTOM) {
514: float maxWidth = (float) w;
515: g2.setFont(this.font);
516: this.content = TextUtilities.createTextBlock(this.text, this.font,
517: this.paint, maxWidth, new G2TextMeasurer(g2));
518: this.content.setLineAlignment(this.textAlignment);
519: Size2D contentSize = this.content.calculateDimensions(g2);
520: if (this.expandToFitSpace) {
521: return new Size2D(maxWidth, contentSize.getHeight());
522: }
523: else {
524: return contentSize;
525: }
526: }
527: else if (position == RectangleEdge.LEFT || position
528: == RectangleEdge.RIGHT) {
529: float maxWidth = Float.MAX_VALUE;
530: g2.setFont(this.font);
531: this.content = TextUtilities.createTextBlock(this.text, this.font,
532: this.paint, maxWidth, new G2TextMeasurer(g2));
533: this.content.setLineAlignment(this.textAlignment);
534: Size2D contentSize = this.content.calculateDimensions(g2);
535:
536:
537: if (this.expandToFitSpace) {
538: return new Size2D(contentSize.getHeight(), maxWidth);
539: }
540: else {
541: return new Size2D(contentSize.height, contentSize.width);
542: }
543: }
544: else {
545: throw new RuntimeException("Unrecognised exception.");
546: }
547: }
548:
549:
562: protected Size2D arrangeRN(Graphics2D g2, Range widthRange) {
563: Size2D s = arrangeNN(g2);
564: if (widthRange.contains(s.getWidth())) {
565: return s;
566: }
567: double ww = widthRange.constrain(s.getWidth());
568: return arrangeFN(g2, ww);
569: }
570:
571:
582: protected Size2D arrangeRR(Graphics2D g2, Range widthRange,
583: Range heightRange) {
584: RectangleEdge position = getPosition();
585: if (position == RectangleEdge.TOP || position == RectangleEdge.BOTTOM) {
586: float maxWidth = (float) widthRange.getUpperBound();
587: g2.setFont(this.font);
588: this.content = TextUtilities.createTextBlock(this.text, this.font,
589: this.paint, maxWidth, new G2TextMeasurer(g2));
590: this.content.setLineAlignment(this.textAlignment);
591: Size2D contentSize = this.content.calculateDimensions(g2);
592: if (this.expandToFitSpace) {
593: return new Size2D(maxWidth, contentSize.getHeight());
594: }
595: else {
596: return contentSize;
597: }
598: }
599: else if (position == RectangleEdge.LEFT || position
600: == RectangleEdge.RIGHT) {
601: float maxWidth = (float) heightRange.getUpperBound();
602: g2.setFont(this.font);
603: this.content = TextUtilities.createTextBlock(this.text, this.font,
604: this.paint, maxWidth, new G2TextMeasurer(g2));
605: this.content.setLineAlignment(this.textAlignment);
606: Size2D contentSize = this.content.calculateDimensions(g2);
607:
608:
609: if (this.expandToFitSpace) {
610: return new Size2D(contentSize.getHeight(), maxWidth);
611: }
612: else {
613: return new Size2D(contentSize.height, contentSize.width);
614: }
615: }
616: else {
617: throw new RuntimeException("Unrecognised exception.");
618: }
619: }
620:
621:
628: public void draw(Graphics2D g2, Rectangle2D area) {
629: draw(g2, area, null);
630: }
631:
632:
644: public Object draw(Graphics2D g2, Rectangle2D area, Object params) {
645: if (this.content == null) {
646: return null;
647: }
648: area = trimMargin(area);
649: drawBorder(g2, area);
650: if (this.text.equals("")) {
651: return null;
652: }
653: ChartEntity entity = null;
654: if (params instanceof EntityBlockParams) {
655: EntityBlockParams p = (EntityBlockParams) params;
656: if (p.getGenerateEntities()) {
657: entity = new ChartEntity(area, this.toolTipText, this.urlText);
658: }
659: }
660: area = trimBorder(area);
661: if (this.backgroundPaint != null) {
662: g2.setPaint(this.backgroundPaint);
663: g2.fill(area);
664: }
665: area = trimPadding(area);
666: RectangleEdge position = getPosition();
667: if (position == RectangleEdge.TOP || position == RectangleEdge.BOTTOM) {
668: drawHorizontal(g2, area);
669: }
670: else if (position == RectangleEdge.LEFT
671: || position == RectangleEdge.RIGHT) {
672: drawVertical(g2, area);
673: }
674: BlockResult result = new BlockResult();
675: if (entity != null) {
676: StandardEntityCollection sec = new StandardEntityCollection();
677: sec.add(entity);
678: result.setEntityCollection(sec);
679: }
680: return result;
681: }
682:
683:
691: protected void drawHorizontal(Graphics2D g2, Rectangle2D area) {
692: Rectangle2D titleArea = (Rectangle2D) area.clone();
693: g2.setFont(this.font);
694: g2.setPaint(this.paint);
695: TextBlockAnchor anchor = null;
696: float x = 0.0f;
697: HorizontalAlignment horizontalAlignment = getHorizontalAlignment();
698: if (horizontalAlignment == HorizontalAlignment.LEFT) {
699: x = (float) titleArea.getX();
700: anchor = TextBlockAnchor.TOP_LEFT;
701: }
702: else if (horizontalAlignment == HorizontalAlignment.RIGHT) {
703: x = (float) titleArea.getMaxX();
704: anchor = TextBlockAnchor.TOP_RIGHT;
705: }
706: else if (horizontalAlignment == HorizontalAlignment.CENTER) {
707: x = (float) titleArea.getCenterX();
708: anchor = TextBlockAnchor.TOP_CENTER;
709: }
710: float y = 0.0f;
711: RectangleEdge position = getPosition();
712: if (position == RectangleEdge.TOP) {
713: y = (float) titleArea.getY();
714: }
715: else if (position == RectangleEdge.BOTTOM) {
716: y = (float) titleArea.getMaxY();
717: if (horizontalAlignment == HorizontalAlignment.LEFT) {
718: anchor = TextBlockAnchor.BOTTOM_LEFT;
719: }
720: else if (horizontalAlignment == HorizontalAlignment.CENTER) {
721: anchor = TextBlockAnchor.BOTTOM_CENTER;
722: }
723: else if (horizontalAlignment == HorizontalAlignment.RIGHT) {
724: anchor = TextBlockAnchor.BOTTOM_RIGHT;
725: }
726: }
727: this.content.draw(g2, x, y, anchor);
728: }
729:
730:
738: protected void drawVertical(Graphics2D g2, Rectangle2D area) {
739: Rectangle2D titleArea = (Rectangle2D) area.clone();
740: g2.setFont(this.font);
741: g2.setPaint(this.paint);
742: TextBlockAnchor anchor = null;
743: float y = 0.0f;
744: VerticalAlignment verticalAlignment = getVerticalAlignment();
745: if (verticalAlignment == VerticalAlignment.TOP) {
746: y = (float) titleArea.getY();
747: anchor = TextBlockAnchor.TOP_RIGHT;
748: }
749: else if (verticalAlignment == VerticalAlignment.BOTTOM) {
750: y = (float) titleArea.getMaxY();
751: anchor = TextBlockAnchor.TOP_LEFT;
752: }
753: else if (verticalAlignment == VerticalAlignment.CENTER) {
754: y = (float) titleArea.getCenterY();
755: anchor = TextBlockAnchor.TOP_CENTER;
756: }
757: float x = 0.0f;
758: RectangleEdge position = getPosition();
759: if (position == RectangleEdge.LEFT) {
760: x = (float) titleArea.getX();
761: }
762: else if (position == RectangleEdge.RIGHT) {
763: x = (float) titleArea.getMaxX();
764: if (verticalAlignment == VerticalAlignment.TOP) {
765: anchor = TextBlockAnchor.BOTTOM_RIGHT;
766: }
767: else if (verticalAlignment == VerticalAlignment.CENTER) {
768: anchor = TextBlockAnchor.BOTTOM_CENTER;
769: }
770: else if (verticalAlignment == VerticalAlignment.BOTTOM) {
771: anchor = TextBlockAnchor.BOTTOM_LEFT;
772: }
773: }
774: this.content.draw(g2, x, y, anchor, x, y, -Math.PI / 2.0);
775: }
776:
777:
784: public boolean equals(Object obj) {
785: if (obj == this) {
786: return true;
787: }
788: if (!(obj instanceof TextTitle)) {
789: return false;
790: }
791: if (!super.equals(obj)) {
792: return false;
793: }
794: TextTitle that = (TextTitle) obj;
795: if (!ObjectUtilities.equal(this.text, that.text)) {
796: return false;
797: }
798: if (!ObjectUtilities.equal(this.font, that.font)) {
799: return false;
800: }
801: if (!PaintUtilities.equal(this.paint, that.paint)) {
802: return false;
803: }
804: if (this.textAlignment != that.textAlignment) {
805: return false;
806: }
807: if (!PaintUtilities.equal(this.backgroundPaint, that.backgroundPaint)) {
808: return false;
809: }
810: return true;
811: }
812:
813:
818: public int hashCode() {
819: int result = super.hashCode();
820: result = 29 * result + (this.text != null ? this.text.hashCode() : 0);
821: result = 29 * result + (this.font != null ? this.font.hashCode() : 0);
822: result = 29 * result + (this.paint != null ? this.paint.hashCode() : 0);
823: result = 29 * result + (this.backgroundPaint != null
824: ? this.backgroundPaint.hashCode() : 0);
825: return result;
826: }
827:
828:
835: public Object clone() throws CloneNotSupportedException {
836: return super.clone();
837: }
838:
839:
846: private void writeObject(ObjectOutputStream stream) throws IOException {
847: stream.defaultWriteObject();
848: SerialUtilities.writePaint(this.paint, stream);
849: SerialUtilities.writePaint(this.backgroundPaint, stream);
850: }
851:
852:
860: private void readObject(ObjectInputStream stream)
861: throws IOException, ClassNotFoundException
862: {
863: stream.defaultReadObject();
864: this.paint = SerialUtilities.readPaint(stream);
865: this.backgroundPaint = SerialUtilities.readPaint(stream);
866: }
867:
868: }
869: