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