1:
45:
46: package ;
47:
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57:
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67:
68:
73: public class DialPlot extends Plot implements DialLayerChangeListener {
74:
75:
78: private DialLayer background;
79:
80:
83: private DialLayer cap;
84:
85:
88: private DialFrame dialFrame;
89:
90:
93: private ObjectList datasets;
94:
95:
98: private ObjectList scales;
99:
100:
101: private ObjectList datasetToScaleMap;
102:
103:
106: private List layers;
107:
108:
111: private List pointers;
112:
113:
116: private double viewX;
117:
118:
121: private double viewY;
122:
123:
126: private double viewW;
127:
128:
131: private double viewH;
132:
133:
136: public DialPlot() {
137: this(null);
138: }
139:
140:
145: public DialPlot(ValueDataset dataset) {
146: this.background = null;
147: this.cap = null;
148: this.dialFrame = new ArcDialFrame();
149: this.datasets = new ObjectList();
150: if (dataset != null) {
151: this.setDataset(dataset);
152: }
153: this.scales = new ObjectList();
154: this.datasetToScaleMap = new ObjectList();
155: this.layers = new java.util.ArrayList();
156: this.pointers = new java.util.ArrayList();
157: this.viewX = 0.0;
158: this.viewY = 0.0;
159: this.viewW = 1.0;
160: this.viewH = 1.0;
161: }
162:
163:
170: public DialLayer getBackground() {
171: return this.background;
172: }
173:
174:
182: public void setBackground(DialLayer background) {
183: if (this.background != null) {
184: this.background.removeChangeListener(this);
185: }
186: this.background = background;
187: if (background != null) {
188: background.addChangeListener(this);
189: }
190: fireChangeEvent();
191: }
192:
193:
200: public DialLayer getCap() {
201: return this.cap;
202: }
203:
204:
212: public void setCap(DialLayer cap) {
213: if (this.cap != null) {
214: this.cap.removeChangeListener(this);
215: }
216: this.cap = cap;
217: if (cap != null) {
218: cap.addChangeListener(this);
219: }
220: fireChangeEvent();
221: }
222:
223:
230: public DialFrame getDialFrame() {
231: return this.dialFrame;
232: }
233:
234:
242: public void setDialFrame(DialFrame frame) {
243: if (frame == null) {
244: throw new IllegalArgumentException("Null 'frame' argument.");
245: }
246: this.dialFrame.removeChangeListener(this);
247: this.dialFrame = frame;
248: frame.addChangeListener(this);
249: fireChangeEvent();
250: }
251:
252:
260: public double getViewX() {
261: return this.viewX;
262: }
263:
264:
272: public double getViewY() {
273: return this.viewY;
274: }
275:
276:
284: public double getViewWidth() {
285: return this.viewW;
286: }
287:
288:
296: public double getViewHeight() {
297: return this.viewH;
298: }
299:
300:
314: public void setView(double x, double y, double w, double h) {
315: this.viewX = x;
316: this.viewY = y;
317: this.viewW = w;
318: this.viewH = h;
319: fireChangeEvent();
320: }
321:
322:
328: public void addLayer(DialLayer layer) {
329: if (layer == null) {
330: throw new IllegalArgumentException("Null 'layer' argument.");
331: }
332: this.layers.add(layer);
333: layer.addChangeListener(this);
334: fireChangeEvent();
335: }
336:
337:
344: public int getLayerIndex(DialLayer layer) {
345: if (layer == null) {
346: throw new IllegalArgumentException("Null 'layer' argument.");
347: }
348: return this.layers.indexOf(layer);
349: }
350:
351:
357: public void removeLayer(int index) {
358: DialLayer layer = (DialLayer) this.layers.get(index);
359: if (layer != null) {
360: layer.removeChangeListener(this);
361: }
362: this.layers.remove(index);
363: fireChangeEvent();
364: }
365:
366:
372: public void removeLayer(DialLayer layer) {
373:
374: removeLayer(getLayerIndex(layer));
375: }
376:
377:
383: public void addPointer(DialPointer pointer) {
384: if (pointer == null) {
385: throw new IllegalArgumentException("Null 'pointer' argument.");
386: }
387: this.pointers.add(pointer);
388: pointer.addChangeListener(this);
389: fireChangeEvent();
390: }
391:
392:
399: public int getPointerIndex(DialPointer pointer) {
400: if (pointer == null) {
401: throw new IllegalArgumentException("Null 'pointer' argument.");
402: }
403: return this.pointers.indexOf(pointer);
404: }
405:
406:
412: public void removePointer(int index) {
413: DialPointer pointer = (DialPointer) this.pointers.get(index);
414: if (pointer != null) {
415: pointer.removeChangeListener(this);
416: }
417: this.pointers.remove(index);
418: fireChangeEvent();
419: }
420:
421:
427: public void removePointer(DialPointer pointer) {
428:
429: removeLayer(getPointerIndex(pointer));
430: }
431:
432:
440: public DialPointer getPointerForDataset(int datasetIndex) {
441: DialPointer result = null;
442: Iterator iterator = this.pointers.iterator();
443: while (iterator.hasNext()) {
444: DialPointer p = (DialPointer) iterator.next();
445: if (p.getDatasetIndex() == datasetIndex) {
446: return p;
447: }
448: }
449: return result;
450: }
451:
452:
457: public ValueDataset getDataset() {
458: return getDataset(0);
459: }
460:
461:
468: public ValueDataset getDataset(int index) {
469: ValueDataset result = null;
470: if (this.datasets.size() > index) {
471: result = (ValueDataset) this.datasets.get(index);
472: }
473: return result;
474: }
475:
476:
483: public void setDataset(ValueDataset dataset) {
484: setDataset(0, dataset);
485: }
486:
487:
493: public void setDataset(int index, ValueDataset dataset) {
494:
495: ValueDataset existing = (ValueDataset) this.datasets.get(index);
496: if (existing != null) {
497: existing.removeChangeListener(this);
498: }
499: this.datasets.set(index, dataset);
500: if (dataset != null) {
501: dataset.addChangeListener(this);
502: }
503:
504:
505: DatasetChangeEvent event = new DatasetChangeEvent(this, dataset);
506: datasetChanged(event);
507:
508: }
509:
510:
515: public int getDatasetCount() {
516: return this.datasets.size();
517: }
518:
519:
531: public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor,
532: PlotState parentState, PlotRenderingInfo info) {
533:
534: Shape origClip = g2.getClip();
535: g2.setClip(area);
536:
537:
538: Rectangle2D frame = viewToFrame(area);
539:
540:
541: if (this.background != null && this.background.isVisible()) {
542: if (this.background.isClippedToWindow()) {
543: Shape savedClip = g2.getClip();
544: g2.clip(this.dialFrame.getWindow(frame));
545: this.background.draw(g2, this, frame, area);
546: g2.setClip(savedClip);
547: }
548: else {
549: this.background.draw(g2, this, frame, area);
550: }
551: }
552:
553: Iterator iterator = this.layers.iterator();
554: while (iterator.hasNext()) {
555: DialLayer current = (DialLayer) iterator.next();
556: if (current.isVisible()) {
557: if (current.isClippedToWindow()) {
558: Shape savedClip = g2.getClip();
559: g2.clip(this.dialFrame.getWindow(frame));
560: current.draw(g2, this, frame, area);
561: g2.setClip(savedClip);
562: }
563: else {
564: current.draw(g2, this, frame, area);
565: }
566: }
567: }
568:
569:
570: iterator = this.pointers.iterator();
571: while (iterator.hasNext()) {
572: DialPointer current = (DialPointer) iterator.next();
573: if (current.isVisible()) {
574: if (current.isClippedToWindow()) {
575: Shape savedClip = g2.getClip();
576: g2.clip(this.dialFrame.getWindow(frame));
577: current.draw(g2, this, frame, area);
578: g2.setClip(savedClip);
579: }
580: else {
581: current.draw(g2, this, frame, area);
582: }
583: }
584: }
585:
586:
587: if (this.cap != null && this.cap.isVisible()) {
588: if (this.cap.isClippedToWindow()) {
589: Shape savedClip = g2.getClip();
590: g2.clip(this.dialFrame.getWindow(frame));
591: this.cap.draw(g2, this, frame, area);
592: g2.setClip(savedClip);
593: }
594: else {
595: this.cap.draw(g2, this, frame, area);
596: }
597: }
598:
599: if (this.dialFrame.isVisible()) {
600: this.dialFrame.draw(g2, this, frame, area);
601: }
602:
603: g2.setClip(origClip);
604:
605: }
606:
607:
614: private Rectangle2D viewToFrame(Rectangle2D view) {
615: double width = view.getWidth() / this.viewW;
616: double height = view.getHeight() / this.viewH;
617: double x = view.getX() - (width * this.viewX);
618: double y = view.getY() - (height * this.viewY);
619: return new Rectangle2D.Double(x, y, width, height);
620: }
621:
622:
629: public double getValue(int datasetIndex) {
630: double result = Double.NaN;
631: ValueDataset dataset = getDataset(datasetIndex);
632: if (dataset != null) {
633: Number n = dataset.getValue();
634: if (n != null) {
635: result = n.doubleValue();
636: }
637: }
638: return result;
639: }
640:
641:
648: public void addScale(int index, DialScale scale) {
649: if (scale == null) {
650: throw new IllegalArgumentException("Null 'scale' argument.");
651: }
652: DialScale existing = (DialScale) this.scales.get(index);
653: if (existing != null) {
654: removeLayer(existing);
655: }
656: this.layers.add(scale);
657: this.scales.set(index, scale);
658: scale.addChangeListener(this);
659: fireChangeEvent();
660: }
661:
662:
669: public DialScale getScale(int index) {
670: DialScale result = null;
671: if (this.scales.size() > index) {
672: result = (DialScale) this.scales.get(index);
673: }
674: return result;
675: }
676:
677:
683: public void mapDatasetToScale(int index, int scaleIndex) {
684: this.datasetToScaleMap.set(index, new Integer(scaleIndex));
685: fireChangeEvent();
686: }
687:
688:
695: public DialScale getScaleForDataset(int datasetIndex) {
696: DialScale result = (DialScale) this.scales.get(0);
697: Integer scaleIndex = (Integer) this.datasetToScaleMap.get(datasetIndex);
698: if (scaleIndex != null) {
699: result = getScale(scaleIndex.intValue());
700: }
701: return result;
702: }
703:
704:
713: public static Rectangle2D rectangleByRadius(Rectangle2D rect,
714: double radiusW, double radiusH) {
715: if (rect == null) {
716: throw new IllegalArgumentException("Null 'rect' argument.");
717: }
718: double x = rect.getCenterX();
719: double y = rect.getCenterY();
720: double w = rect.getWidth() * radiusW;
721: double h = rect.getHeight() * radiusH;
722: return new Rectangle2D.Double(x - w / 2.0, y - h / 2.0, w, h);
723: }
724:
725:
731: public void dialLayerChanged(DialLayerChangeEvent event) {
732: fireChangeEvent();
733: }
734:
735:
744: public boolean equals(Object obj) {
745: if (obj == this) {
746: return true;
747: }
748: if (!(obj instanceof DialPlot)) {
749: return false;
750: }
751: DialPlot that = (DialPlot) obj;
752: if (!ObjectUtilities.equal(this.background, that.background)) {
753: return false;
754: }
755: if (!ObjectUtilities.equal(this.cap, that.cap)) {
756: return false;
757: }
758: if (!this.dialFrame.equals(that.dialFrame)) {
759: return false;
760: }
761: if (this.viewX != that.viewX) {
762: return false;
763: }
764: if (this.viewY != that.viewY) {
765: return false;
766: }
767: if (this.viewW != that.viewW) {
768: return false;
769: }
770: if (this.viewH != that.viewH) {
771: return false;
772: }
773: if (!this.layers.equals(that.layers)) {
774: return false;
775: }
776: if (!this.pointers.equals(that.pointers)) {
777: return false;
778: }
779: return super.equals(obj);
780: }
781:
782:
787: public int hashCode() {
788: int result = 193;
789: result = 37 * result + ObjectUtilities.hashCode(this.background);
790: result = 37 * result + ObjectUtilities.hashCode(this.cap);
791: result = 37 * result + this.dialFrame.hashCode();
792: long temp = Double.doubleToLongBits(this.viewX);
793: result = 37 * result + (int) (temp ^ (temp >>> 32));
794: temp = Double.doubleToLongBits(this.viewY);
795: result = 37 * result + (int) (temp ^ (temp >>> 32));
796: temp = Double.doubleToLongBits(this.viewW);
797: result = 37 * result + (int) (temp ^ (temp >>> 32));
798: temp = Double.doubleToLongBits(this.viewH);
799: result = 37 * result + (int) (temp ^ (temp >>> 32));
800: return result;
801: }
802:
803:
808: public String getPlotType() {
809: return "DialPlot";
810: }
811:
812:
819: private void writeObject(ObjectOutputStream stream) throws IOException {
820: stream.defaultWriteObject();
821: }
822:
823:
831: private void readObject(ObjectInputStream stream)
832: throws IOException, ClassNotFoundException {
833: stream.defaultReadObject();
834: }
835:
836:
837: }