1:
40:
41: package ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52:
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68:
69:
75: public class PaintScaleLegend extends Title implements PublicCloneable {
76:
77:
78: static final long serialVersionUID = -1365146490993227503L;
79:
80:
81: private PaintScale scale;
82:
83:
84: private ValueAxis axis;
85:
86:
90: private AxisLocation axisLocation;
91:
92:
93: private double axisOffset;
94:
95:
96: private double stripWidth;
97:
98:
102: private boolean stripOutlineVisible;
103:
104:
105: private transient Paint stripOutlinePaint;
106:
107:
108: private transient Stroke stripOutlineStroke;
109:
110:
111: private transient Paint backgroundPaint;
112:
113:
119: public PaintScaleLegend(PaintScale scale, ValueAxis axis) {
120: if (axis == null) {
121: throw new IllegalArgumentException("Null 'axis' argument.");
122: }
123: this.scale = scale;
124: this.axis = axis;
125: this.axisLocation = AxisLocation.BOTTOM_OR_LEFT;
126: this.axisOffset = 0.0;
127: this.stripWidth = 15.0;
128: this.stripOutlineVisible = false;
129: this.stripOutlinePaint = Color.gray;
130: this.stripOutlineStroke = new BasicStroke(0.5f);
131: this.backgroundPaint = Color.white;
132: }
133:
134:
141: public PaintScale getScale() {
142: return this.scale;
143: }
144:
145:
153: public void setScale(PaintScale scale) {
154: if (scale == null) {
155: throw new IllegalArgumentException("Null 'scale' argument.");
156: }
157: this.scale = scale;
158: notifyListeners(new TitleChangeEvent(this));
159: }
160:
161:
168: public ValueAxis getAxis() {
169: return this.axis;
170: }
171:
172:
180: public void setAxis(ValueAxis axis) {
181: if (axis == null) {
182: throw new IllegalArgumentException("Null 'axis' argument.");
183: }
184: this.axis = axis;
185: notifyListeners(new TitleChangeEvent(this));
186: }
187:
188:
195: public AxisLocation getAxisLocation() {
196: return this.axisLocation;
197: }
198:
199:
207: public void setAxisLocation(AxisLocation location) {
208: if (location == null) {
209: throw new IllegalArgumentException("Null 'location' argument.");
210: }
211: this.axisLocation = location;
212: notifyListeners(new TitleChangeEvent(this));
213: }
214:
215:
222: public double getAxisOffset() {
223: return this.axisOffset;
224: }
225:
226:
232: public void setAxisOffset(double offset) {
233: this.axisOffset = offset;
234: notifyListeners(new TitleChangeEvent(this));
235: }
236:
237:
244: public double getStripWidth() {
245: return this.stripWidth;
246: }
247:
248:
256: public void setStripWidth(double width) {
257: this.stripWidth = width;
258: notifyListeners(new TitleChangeEvent(this));
259: }
260:
261:
269: public boolean isStripOutlineVisible() {
270: return this.stripOutlineVisible;
271: }
272:
273:
282: public void setStripOutlineVisible(boolean visible) {
283: this.stripOutlineVisible = visible;
284: notifyListeners(new TitleChangeEvent(this));
285: }
286:
287:
294: public Paint getStripOutlinePaint() {
295: return this.stripOutlinePaint;
296: }
297:
298:
306: public void setStripOutlinePaint(Paint paint) {
307: if (paint == null) {
308: throw new IllegalArgumentException("Null 'paint' argument.");
309: }
310: this.stripOutlinePaint = paint;
311: notifyListeners(new TitleChangeEvent(this));
312: }
313:
314:
321: public Stroke getStripOutlineStroke() {
322: return this.stripOutlineStroke;
323: }
324:
325:
333: public void setStripOutlineStroke(Stroke stroke) {
334: if (stroke == null) {
335: throw new IllegalArgumentException("Null 'stroke' argument.");
336: }
337: this.stripOutlineStroke = stroke;
338: notifyListeners(new TitleChangeEvent(this));
339: }
340:
341:
346: public Paint getBackgroundPaint() {
347: return this.backgroundPaint;
348: }
349:
350:
356: public void setBackgroundPaint(Paint paint) {
357: this.backgroundPaint = paint;
358: notifyListeners(new TitleChangeEvent(this));
359: }
360:
361:
370: public Size2D arrange(Graphics2D g2, RectangleConstraint constraint) {
371: RectangleConstraint cc = toContentConstraint(constraint);
372: LengthConstraintType w = cc.getWidthConstraintType();
373: LengthConstraintType h = cc.getHeightConstraintType();
374: Size2D contentSize = null;
375: if (w == LengthConstraintType.NONE) {
376: if (h == LengthConstraintType.NONE) {
377: contentSize = new Size2D(getWidth(), getHeight());
378: }
379: else if (h == LengthConstraintType.RANGE) {
380: throw new RuntimeException("Not yet implemented.");
381: }
382: else if (h == LengthConstraintType.FIXED) {
383: throw new RuntimeException("Not yet implemented.");
384: }
385: }
386: else if (w == LengthConstraintType.RANGE) {
387: if (h == LengthConstraintType.NONE) {
388: throw new RuntimeException("Not yet implemented.");
389: }
390: else if (h == LengthConstraintType.RANGE) {
391: contentSize = arrangeRR(g2, cc.getWidthRange(),
392: cc.getHeightRange());
393: }
394: else if (h == LengthConstraintType.FIXED) {
395: throw new RuntimeException("Not yet implemented.");
396: }
397: }
398: else if (w == LengthConstraintType.FIXED) {
399: if (h == LengthConstraintType.NONE) {
400: throw new RuntimeException("Not yet implemented.");
401: }
402: else if (h == LengthConstraintType.RANGE) {
403: throw new RuntimeException("Not yet implemented.");
404: }
405: else if (h == LengthConstraintType.FIXED) {
406: throw new RuntimeException("Not yet implemented.");
407: }
408: }
409: return new Size2D(calculateTotalWidth(contentSize.getWidth()),
410: calculateTotalHeight(contentSize.getHeight()));
411: }
412:
413:
424: protected Size2D arrangeRR(Graphics2D g2, Range widthRange,
425: Range heightRange) {
426:
427: RectangleEdge position = getPosition();
428: if (position == RectangleEdge.TOP || position == RectangleEdge.BOTTOM) {
429:
430:
431: float maxWidth = (float) widthRange.getUpperBound();
432:
433:
434: AxisSpace space = this.axis.reserveSpace(g2, null,
435: new Rectangle2D.Double(0, 0, maxWidth, 100),
436: RectangleEdge.BOTTOM, null);
437:
438: return new Size2D(maxWidth, this.stripWidth + this.axisOffset
439: + space.getTop() + space.getBottom());
440: }
441: else if (position == RectangleEdge.LEFT || position
442: == RectangleEdge.RIGHT) {
443: float maxHeight = (float) heightRange.getUpperBound();
444: AxisSpace space = this.axis.reserveSpace(g2, null,
445: new Rectangle2D.Double(0, 0, 100, maxHeight),
446: RectangleEdge.RIGHT, null);
447: return new Size2D(this.stripWidth + this.axisOffset
448: + space.getLeft() + space.getRight(), maxHeight);
449: }
450: else {
451: throw new RuntimeException("Unrecognised position.");
452: }
453: }
454:
455:
461: public void draw(Graphics2D g2, Rectangle2D area) {
462: draw(g2, area, null);
463: }
464:
465:
469: private static final int SUBDIVISIONS = 200;
470:
471:
480: public Object draw(Graphics2D g2, Rectangle2D area, Object params) {
481:
482: Rectangle2D target = (Rectangle2D) area.clone();
483: target = trimMargin(target);
484: if (this.backgroundPaint != null) {
485: g2.setPaint(this.backgroundPaint);
486: g2.fill(target);
487: }
488: getBorder().draw(g2, target);
489: getBorder().getInsets().trim(target);
490: target = trimPadding(target);
491: double base = this.axis.getLowerBound();
492: double increment = this.axis.getRange().getLength() / SUBDIVISIONS;
493: Rectangle2D r = new Rectangle2D.Double();
494:
495:
496: if (RectangleEdge.isTopOrBottom(getPosition())) {
497: RectangleEdge axisEdge = Plot.resolveRangeAxisLocation(
498: this.axisLocation, PlotOrientation.HORIZONTAL);
499: double ww = Math.ceil(target.getWidth() / SUBDIVISIONS);
500: if (axisEdge == RectangleEdge.TOP) {
501: for (int i = 0; i < SUBDIVISIONS; i++) {
502: double v = base + (i * increment);
503: Paint p = this.scale.getPaint(v);
504: double vv = this.axis.valueToJava2D(v, target,
505: RectangleEdge.BOTTOM);
506: r.setRect(vv, target.getMaxY() - this.stripWidth, ww,
507: this.stripWidth);
508: g2.setPaint(p);
509: g2.fill(r);
510: }
511: g2.setPaint(this.stripOutlinePaint);
512: g2.setStroke(this.stripOutlineStroke);
513: g2.draw(new Rectangle2D.Double(target.getMinX(),
514: target.getMaxY() - this.stripWidth, target.getWidth(),
515: this.stripWidth));
516: this.axis.draw(g2, target.getMaxY() - this.stripWidth
517: - this.axisOffset, target, target, RectangleEdge.TOP,
518: null);
519: }
520: else if (axisEdge == RectangleEdge.BOTTOM) {
521: for (int i = 0; i < SUBDIVISIONS; i++) {
522: double v = base + (i * increment);
523: Paint p = this.scale.getPaint(v);
524: double vv = this.axis.valueToJava2D(v, target,
525: RectangleEdge.BOTTOM);
526: r.setRect(vv, target.getMinY(), ww, this.stripWidth);
527: g2.setPaint(p);
528: g2.fill(r);
529: }
530: g2.setPaint(this.stripOutlinePaint);
531: g2.setStroke(this.stripOutlineStroke);
532: g2.draw(new Rectangle2D.Double(target.getMinX(),
533: target.getMinY(), target.getWidth(), this.stripWidth));
534: this.axis.draw(g2, target.getMinY() + this.stripWidth
535: + this.axisOffset, target, target,
536: RectangleEdge.BOTTOM, null);
537: }
538: }
539: else {
540: RectangleEdge axisEdge = Plot.resolveRangeAxisLocation(
541: this.axisLocation, PlotOrientation.VERTICAL);
542: double hh = Math.ceil(target.getHeight() / SUBDIVISIONS);
543: if (axisEdge == RectangleEdge.LEFT) {
544: for (int i = 0; i < SUBDIVISIONS; i++) {
545: double v = base + (i * increment);
546: Paint p = this.scale.getPaint(v);
547: double vv = this.axis.valueToJava2D(v, target,
548: RectangleEdge.LEFT);
549: r.setRect(target.getMaxX() - this.stripWidth, vv - hh,
550: this.stripWidth, hh);
551: g2.setPaint(p);
552: g2.fill(r);
553: }
554: g2.setPaint(this.stripOutlinePaint);
555: g2.setStroke(this.stripOutlineStroke);
556: g2.draw(new Rectangle2D.Double(target.getMaxX()
557: - this.stripWidth, target.getMinY(), this.stripWidth,
558: target.getHeight()));
559: this.axis.draw(g2, target.getMaxX() - this.stripWidth
560: - this.axisOffset, target, target, RectangleEdge.LEFT,
561: null);
562: }
563: else if (axisEdge == RectangleEdge.RIGHT) {
564: for (int i = 0; i < SUBDIVISIONS; i++) {
565: double v = base + (i * increment);
566: Paint p = this.scale.getPaint(v);
567: double vv = this.axis.valueToJava2D(v, target,
568: RectangleEdge.LEFT);
569: r.setRect(target.getMinX(), vv - hh, this.stripWidth, hh);
570: g2.setPaint(p);
571: g2.fill(r);
572: }
573: g2.setPaint(this.stripOutlinePaint);
574: g2.setStroke(this.stripOutlineStroke);
575: g2.draw(new Rectangle2D.Double(target.getMinX(),
576: target.getMinY(), this.stripWidth, target.getHeight()));
577: this.axis.draw(g2, target.getMinX() + this.stripWidth
578: + this.axisOffset, target, target, RectangleEdge.RIGHT,
579: null);
580: }
581: }
582: return null;
583: }
584:
585:
592: public boolean equals(Object obj) {
593: if (!(obj instanceof PaintScaleLegend)) {
594: return false;
595: }
596: PaintScaleLegend that = (PaintScaleLegend) obj;
597: if (!this.scale.equals(that.scale)) {
598: return false;
599: }
600: if (!this.axis.equals(that.axis)) {
601: return false;
602: }
603: if (!this.axisLocation.equals(that.axisLocation)) {
604: return false;
605: }
606: if (this.axisOffset != that.axisOffset) {
607: return false;
608: }
609: if (this.stripWidth != that.stripWidth) {
610: return false;
611: }
612: if (this.stripOutlineVisible != that.stripOutlineVisible) {
613: return false;
614: }
615: if (!PaintUtilities.equal(this.stripOutlinePaint,
616: that.stripOutlinePaint)) {
617: return false;
618: }
619: if (!this.stripOutlineStroke.equals(that.stripOutlineStroke)) {
620: return false;
621: }
622: if (!PaintUtilities.equal(this.backgroundPaint, that.backgroundPaint)) {
623: return false;
624: }
625: return super.equals(obj);
626: }
627:
628:
635: private void writeObject(ObjectOutputStream stream) throws IOException {
636: stream.defaultWriteObject();
637: SerialUtilities.writePaint(this.backgroundPaint, stream);
638: SerialUtilities.writePaint(this.stripOutlinePaint, stream);
639: SerialUtilities.writeStroke(this.stripOutlineStroke, stream);
640: }
641:
642:
650: private void readObject(ObjectInputStream stream)
651: throws IOException, ClassNotFoundException {
652: stream.defaultReadObject();
653: this.backgroundPaint = SerialUtilities.readPaint(stream);
654: this.stripOutlinePaint = SerialUtilities.readPaint(stream);
655: this.stripOutlineStroke = SerialUtilities.readStroke(stream);
656: }
657:
658: }