1:
44:
45: package ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56:
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66:
67:
72: public class DialPlot extends Plot implements DialLayerChangeListener {
73:
74:
77: private DialLayer background;
78:
79:
82: private DialLayer cap;
83:
84:
87: private DialFrame dialFrame;
88:
89:
92: private ObjectList datasets;
93:
94:
97: private ObjectList scales;
98:
99:
100: private ObjectList datasetToScaleMap;
101:
102:
105: private List layers;
106:
107:
110: private List pointers;
111:
112:
115: private double viewX;
116:
117:
120: private double viewY;
121:
122:
125: private double viewW;
126:
127:
130: private double viewH;
131:
132:
135: public DialPlot() {
136: this(null);
137: }
138:
139:
144: public DialPlot(ValueDataset dataset) {
145: this.background = null;
146: this.cap = null;
147: this.dialFrame = new ArcDialFrame();
148: this.datasets = new ObjectList();
149: if (dataset != null) {
150: this.setDataset(dataset);
151: }
152: this.scales = new ObjectList();
153: this.datasetToScaleMap = new ObjectList();
154: this.layers = new java.util.ArrayList();
155: this.pointers = new java.util.ArrayList();
156: this.viewX = 0.0;
157: this.viewY = 0.0;
158: this.viewW = 1.0;
159: this.viewH = 1.0;
160: }
161:
162:
169: public DialLayer getBackground() {
170: return this.background;
171: }
172:
173:
181: public void setBackground(DialLayer background) {
182: if (this.background != null) {
183: this.background.removeChangeListener(this);
184: }
185: this.background = background;
186: if (background != null) {
187: background.addChangeListener(this);
188: }
189: notifyListeners(new PlotChangeEvent(this));
190: }
191:
192:
199: public DialLayer getCap() {
200: return this.cap;
201: }
202:
203:
211: public void setCap(DialLayer cap) {
212: if (this.cap != null) {
213: this.cap.removeChangeListener(this);
214: }
215: this.cap = cap;
216: if (cap != null) {
217: cap.addChangeListener(this);
218: }
219: notifyListeners(new PlotChangeEvent(this));
220: }
221:
222:
229: public DialFrame getDialFrame() {
230: return this.dialFrame;
231: }
232:
233:
241: public void setDialFrame(DialFrame frame) {
242: if (frame == null) {
243: throw new IllegalArgumentException("Null 'frame' argument.");
244: }
245: this.dialFrame.removeChangeListener(this);
246: this.dialFrame = frame;
247: frame.addChangeListener(this);
248: notifyListeners(new PlotChangeEvent(this));
249: }
250:
251:
259: public double getViewX() {
260: return this.viewX;
261: }
262:
263:
271: public double getViewY() {
272: return this.viewY;
273: }
274:
275:
283: public double getViewWidth() {
284: return this.viewW;
285: }
286:
287:
295: public double getViewHeight() {
296: return this.viewH;
297: }
298:
299:
313: public void setView(double x, double y, double w, double h) {
314: this.viewX = x;
315: this.viewY = y;
316: this.viewW = w;
317: this.viewH = h;
318: notifyListeners(new PlotChangeEvent(this));
319: }
320:
321:
327: public void addLayer(DialLayer layer) {
328: if (layer == null) {
329: throw new IllegalArgumentException("Null 'layer' argument.");
330: }
331: this.layers.add(layer);
332: layer.addChangeListener(this);
333: notifyListeners(new PlotChangeEvent(this));
334: }
335:
336:
343: public int getLayerIndex(DialLayer layer) {
344: if (layer == null) {
345: throw new IllegalArgumentException("Null 'layer' argument.");
346: }
347: return this.layers.indexOf(layer);
348: }
349:
350:
356: public void removeLayer(int index) {
357: DialLayer layer = (DialLayer) this.layers.get(index);
358: if (layer != null) {
359: layer.removeChangeListener(this);
360: }
361: this.layers.remove(index);
362: notifyListeners(new PlotChangeEvent(this));
363: }
364:
365:
371: public void removeLayer(DialLayer layer) {
372:
373: removeLayer(getLayerIndex(layer));
374: }
375:
376:
382: public void addPointer(DialPointer pointer) {
383: if (pointer == null) {
384: throw new IllegalArgumentException("Null 'pointer' argument.");
385: }
386: this.pointers.add(pointer);
387: pointer.addChangeListener(this);
388: notifyListeners(new PlotChangeEvent(this));
389: }
390:
391:
398: public int getPointerIndex(DialPointer pointer) {
399: if (pointer == null) {
400: throw new IllegalArgumentException("Null 'pointer' argument.");
401: }
402: return this.pointers.indexOf(pointer);
403: }
404:
405:
411: public void removePointer(int index) {
412: DialPointer pointer = (DialPointer) this.pointers.get(index);
413: if (pointer != null) {
414: pointer.removeChangeListener(this);
415: }
416: this.pointers.remove(index);
417: notifyListeners(new PlotChangeEvent(this));
418: }
419:
420:
426: public void removePointer(DialPointer pointer) {
427:
428: removeLayer(getPointerIndex(pointer));
429: }
430:
431:
439: public DialPointer getPointerForDataset(int datasetIndex) {
440: DialPointer result = null;
441: Iterator iterator = this.pointers.iterator();
442: while (iterator.hasNext()) {
443: DialPointer p = (DialPointer) iterator.next();
444: if (p.getDatasetIndex() == datasetIndex) {
445: return p;
446: }
447: }
448: return result;
449: }
450:
451:
456: public ValueDataset getDataset() {
457: return getDataset(0);
458: }
459:
460:
467: public ValueDataset getDataset(int index) {
468: ValueDataset result = null;
469: if (this.datasets.size() > index) {
470: result = (ValueDataset) this.datasets.get(index);
471: }
472: return result;
473: }
474:
475:
482: public void setDataset(ValueDataset dataset) {
483: setDataset(0, dataset);
484: }
485:
486:
492: public void setDataset(int index, ValueDataset dataset) {
493:
494: ValueDataset existing = (ValueDataset) this.datasets.get(index);
495: if (existing != null) {
496: existing.removeChangeListener(this);
497: }
498: this.datasets.set(index, dataset);
499: if (dataset != null) {
500: dataset.addChangeListener(this);
501: }
502:
503:
504: DatasetChangeEvent event = new DatasetChangeEvent(this, dataset);
505: datasetChanged(event);
506:
507: }
508:
509:
514: public int getDatasetCount() {
515: return this.datasets.size();
516: }
517:
518:
530: public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor,
531: PlotState parentState, PlotRenderingInfo info) {
532:
533:
534: Rectangle2D frame = viewToFrame(area);
535:
536:
537: if (this.background != null && this.background.isVisible()) {
538: if (this.background.isClippedToWindow()) {
539: Shape savedClip = g2.getClip();
540: g2.setClip(this.dialFrame.getWindow(frame));
541: this.background.draw(g2, this, frame, area);
542: g2.setClip(savedClip);
543: }
544: else {
545: this.background.draw(g2, this, frame, area);
546: }
547: }
548:
549: Iterator iterator = this.layers.iterator();
550: while (iterator.hasNext()) {
551: DialLayer current = (DialLayer) iterator.next();
552: if (current.isVisible()) {
553: if (current.isClippedToWindow()) {
554: Shape savedClip = g2.getClip();
555: g2.setClip(this.dialFrame.getWindow(frame));
556: current.draw(g2, this, frame, area);
557: g2.setClip(savedClip);
558: }
559: else {
560: current.draw(g2, this, frame, area);
561: }
562: }
563: }
564:
565:
566: iterator = this.pointers.iterator();
567: while (iterator.hasNext()) {
568: DialPointer current = (DialPointer) iterator.next();
569: if (current.isVisible()) {
570: if (current.isClippedToWindow()) {
571: Shape savedClip = g2.getClip();
572: g2.setClip(this.dialFrame.getWindow(frame));
573: current.draw(g2, this, frame, area);
574: g2.setClip(savedClip);
575: }
576: else {
577: current.draw(g2, this, frame, area);
578: }
579: }
580: }
581:
582:
583: if (this.cap != null && this.cap.isVisible()) {
584: if (this.cap.isClippedToWindow()) {
585: Shape savedClip = g2.getClip();
586: g2.setClip(this.dialFrame.getWindow(frame));
587: this.cap.draw(g2, this, frame, area);
588: g2.setClip(savedClip);
589: }
590: else {
591: this.cap.draw(g2, this, frame, area);
592: }
593: }
594:
595: if (this.dialFrame.isVisible()) {
596: this.dialFrame.draw(g2, this, frame, area);
597: }
598:
599: }
600:
601:
608: private Rectangle2D viewToFrame(Rectangle2D view) {
609: double width = view.getWidth() / this.viewW;
610: double height = view.getHeight() / this.viewH;
611: double x = view.getX() - (width * this.viewX);
612: double y = view.getY() - (height * this.viewY);
613: return new Rectangle2D.Double(x, y, width, height);
614: }
615:
616:
623: public double getValue(int datasetIndex) {
624: double result = Double.NaN;
625: ValueDataset dataset = getDataset(datasetIndex);
626: if (dataset != null) {
627: Number n = dataset.getValue();
628: if (n != null) {
629: result = n.doubleValue();
630: }
631: }
632: return result;
633: }
634:
635:
642: public void addScale(int index, DialScale scale) {
643: if (scale == null) {
644: throw new IllegalArgumentException("Null 'scale' argument.");
645: }
646: DialScale existing = (DialScale) this.scales.get(index);
647: if (existing != null) {
648: removeLayer(existing);
649: }
650: this.layers.add(scale);
651: this.scales.set(index, scale);
652: scale.addChangeListener(this);
653: notifyListeners(new PlotChangeEvent(this));
654: }
655:
656:
663: public DialScale getScale(int index) {
664: DialScale result = null;
665: if (this.scales.size() > index) {
666: result = (DialScale) this.scales.get(index);
667: }
668: return result;
669: }
670:
671:
677: public void mapDatasetToScale(int index, int scaleIndex) {
678: this.datasetToScaleMap.set(index, new Integer(scaleIndex));
679: notifyListeners(new PlotChangeEvent(this));
680: }
681:
682:
689: public DialScale getScaleForDataset(int datasetIndex) {
690: DialScale result = (DialScale) this.scales.get(0);
691: Integer scaleIndex = (Integer) this.datasetToScaleMap.get(datasetIndex);
692: if (scaleIndex != null) {
693: result = getScale(scaleIndex.intValue());
694: }
695: return result;
696: }
697:
698:
707: public static Rectangle2D rectangleByRadius(Rectangle2D rect,
708: double radiusW, double radiusH) {
709: if (rect == null) {
710: throw new IllegalArgumentException("Null 'rect' argument.");
711: }
712: double x = rect.getCenterX();
713: double y = rect.getCenterY();
714: double w = rect.getWidth() * radiusW;
715: double h = rect.getHeight() * radiusH;
716: return new Rectangle2D.Double(x - w / 2.0, y - h / 2.0, w, h);
717: }
718:
719:
725: public void dialLayerChanged(DialLayerChangeEvent event) {
726: this.notifyListeners(new PlotChangeEvent(this));
727: }
728:
729:
738: public boolean equals(Object obj) {
739: if (obj == this) {
740: return true;
741: }
742: if (!(obj instanceof DialPlot)) {
743: return false;
744: }
745: DialPlot that = (DialPlot) obj;
746: if (!ObjectUtilities.equal(this.background, that.background)) {
747: return false;
748: }
749: if (!ObjectUtilities.equal(this.cap, that.cap)) {
750: return false;
751: }
752: if (!this.dialFrame.equals(that.dialFrame)) {
753: return false;
754: }
755: if (this.viewX != that.viewX) {
756: return false;
757: }
758: if (this.viewY != that.viewY) {
759: return false;
760: }
761: if (this.viewW != that.viewW) {
762: return false;
763: }
764: if (this.viewH != that.viewH) {
765: return false;
766: }
767: if (!this.layers.equals(that.layers)) {
768: return false;
769: }
770: if (!this.pointers.equals(that.pointers)) {
771: return false;
772: }
773: return super.equals(obj);
774: }
775:
776:
781: public int hashCode() {
782: int result = 193;
783: result = 37 * result + ObjectUtilities.hashCode(this.background);
784: result = 37 * result + ObjectUtilities.hashCode(this.cap);
785: result = 37 * result + this.dialFrame.hashCode();
786: long temp = Double.doubleToLongBits(this.viewX);
787: result = 37 * result + (int) (temp ^ (temp >>> 32));
788: temp = Double.doubleToLongBits(this.viewY);
789: result = 37 * result + (int) (temp ^ (temp >>> 32));
790: temp = Double.doubleToLongBits(this.viewW);
791: result = 37 * result + (int) (temp ^ (temp >>> 32));
792: temp = Double.doubleToLongBits(this.viewH);
793: result = 37 * result + (int) (temp ^ (temp >>> 32));
794: return result;
795: }
796:
797:
802: public String getPlotType() {
803: return "DialPlot";
804: }
805:
806:
813: private void writeObject(ObjectOutputStream stream) throws IOException {
814: stream.defaultWriteObject();
815: }
816:
817:
825: private void readObject(ObjectInputStream stream)
826: throws IOException, ClassNotFoundException {
827: stream.defaultReadObject();
828: }
829:
830:
831: }