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:
70: public class DialPlot extends Plot implements DialLayerChangeListener {
71:
72:
75: private DialLayer background;
76:
77:
80: private DialLayer cap;
81:
82:
85: private DialFrame dialFrame;
86:
87:
90: private ObjectList datasets;
91:
92:
95: private ObjectList scales;
96:
97:
98: private ObjectList datasetToScaleMap;
99:
100:
103: private List layers;
104:
105:
108: private List pointers;
109:
110:
113: private double viewX;
114:
115:
118: private double viewY;
119:
120:
123: private double viewW;
124:
125:
128: private double viewH;
129:
130:
133: public DialPlot() {
134: this(null);
135: }
136:
137:
142: public DialPlot(ValueDataset dataset) {
143: this.background = null;
144: this.cap = null;
145: this.dialFrame = new ArcDialFrame();
146: this.datasets = new ObjectList();
147: if (dataset != null) {
148: this.setDataset(dataset);
149: }
150: this.scales = new ObjectList();
151: this.datasetToScaleMap = new ObjectList();
152: this.layers = new java.util.ArrayList();
153: this.pointers = new java.util.ArrayList();
154: this.viewX = 0.0;
155: this.viewY = 0.0;
156: this.viewW = 1.0;
157: this.viewH = 1.0;
158: }
159:
160:
167: public DialLayer getBackground() {
168: return this.background;
169: }
170:
171:
179: public void setBackground(DialLayer background) {
180: if (this.background != null) {
181: this.background.removeChangeListener(this);
182: }
183: this.background = background;
184: if (background != null) {
185: background.addChangeListener(this);
186: }
187: notifyListeners(new PlotChangeEvent(this));
188: }
189:
190:
197: public DialLayer getCap() {
198: return this.cap;
199: }
200:
201:
209: public void setCap(DialLayer cap) {
210: if (this.cap != null) {
211: this.cap.removeChangeListener(this);
212: }
213: this.cap = cap;
214: if (cap != null) {
215: cap.addChangeListener(this);
216: }
217: notifyListeners(new PlotChangeEvent(this));
218: }
219:
220:
227: public DialFrame getDialFrame() {
228: return this.dialFrame;
229: }
230:
231:
239: public void setDialFrame(DialFrame frame) {
240: if (frame == null) {
241: throw new IllegalArgumentException("Null 'frame' argument.");
242: }
243: this.dialFrame.removeChangeListener(this);
244: this.dialFrame = frame;
245: frame.addChangeListener(this);
246: notifyListeners(new PlotChangeEvent(this));
247: }
248:
249:
257: public double getViewX() {
258: return this.viewX;
259: }
260:
261:
269: public double getViewY() {
270: return this.viewY;
271: }
272:
273:
281: public double getViewWidth() {
282: return this.viewW;
283: }
284:
285:
293: public double getViewHeight() {
294: return this.viewH;
295: }
296:
297:
311: public void setView(double x, double y, double w, double h) {
312: this.viewX = x;
313: this.viewY = y;
314: this.viewW = w;
315: this.viewH = h;
316: notifyListeners(new PlotChangeEvent(this));
317: }
318:
319:
325: public void addLayer(DialLayer layer) {
326: if (layer == null) {
327: throw new IllegalArgumentException("Null 'layer' argument.");
328: }
329: this.layers.add(layer);
330: layer.addChangeListener(this);
331: notifyListeners(new PlotChangeEvent(this));
332: }
333:
334:
341: public int getLayerIndex(DialLayer layer) {
342: if (layer == null) {
343: throw new IllegalArgumentException("Null 'layer' argument.");
344: }
345: return this.layers.indexOf(layer);
346: }
347:
348:
354: public void removeLayer(int index) {
355: DialLayer layer = (DialLayer) this.layers.get(index);
356: if (layer != null) {
357: layer.removeChangeListener(this);
358: }
359: this.layers.remove(index);
360: notifyListeners(new PlotChangeEvent(this));
361: }
362:
363:
369: public void removeLayer(DialLayer layer) {
370:
371: removeLayer(getLayerIndex(layer));
372: }
373:
374:
380: public void addPointer(DialPointer pointer) {
381: if (pointer == null) {
382: throw new IllegalArgumentException("Null 'pointer' argument.");
383: }
384: this.pointers.add(pointer);
385: pointer.addChangeListener(this);
386: notifyListeners(new PlotChangeEvent(this));
387: }
388:
389:
396: public int getPointerIndex(DialPointer pointer) {
397: if (pointer == null) {
398: throw new IllegalArgumentException("Null 'pointer' argument.");
399: }
400: return this.pointers.indexOf(pointer);
401: }
402:
403:
409: public void removePointer(int index) {
410: DialPointer pointer = (DialPointer) this.pointers.get(index);
411: if (pointer != null) {
412: pointer.removeChangeListener(this);
413: }
414: this.pointers.remove(index);
415: notifyListeners(new PlotChangeEvent(this));
416: }
417:
418:
424: public void removePointer(DialPointer pointer) {
425:
426: removeLayer(getPointerIndex(pointer));
427: }
428:
429:
437: public DialPointer getPointerForDataset(int datasetIndex) {
438: DialPointer result = null;
439: Iterator iterator = this.pointers.iterator();
440: while (iterator.hasNext()) {
441: DialPointer p = (DialPointer) iterator.next();
442: if (p.getDatasetIndex() == datasetIndex) {
443: return p;
444: }
445: }
446: return result;
447: }
448:
449:
454: public ValueDataset getDataset() {
455: return getDataset(0);
456: }
457:
458:
465: public ValueDataset getDataset(int index) {
466: ValueDataset result = null;
467: if (this.datasets.size() > index) {
468: result = (ValueDataset) this.datasets.get(index);
469: }
470: return result;
471: }
472:
473:
480: public void setDataset(ValueDataset dataset) {
481: setDataset(0, dataset);
482: }
483:
484:
490: public void setDataset(int index, ValueDataset dataset) {
491:
492: ValueDataset existing = (ValueDataset) this.datasets.get(index);
493: if (existing != null) {
494: existing.removeChangeListener(this);
495: }
496: this.datasets.set(index, dataset);
497: if (dataset != null) {
498: dataset.addChangeListener(this);
499: }
500:
501:
502: DatasetChangeEvent event = new DatasetChangeEvent(this, dataset);
503: datasetChanged(event);
504:
505: }
506:
507:
512: public int getDatasetCount() {
513: return this.datasets.size();
514: }
515:
516:
528: public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor,
529: PlotState parentState, PlotRenderingInfo info) {
530:
531:
532: Rectangle2D frame = viewToFrame(area);
533:
534:
535: if (this.background != null && this.background.isVisible()) {
536: if (this.background.isClippedToWindow()) {
537: Shape savedClip = g2.getClip();
538: g2.setClip(this.dialFrame.getWindow(frame));
539: this.background.draw(g2, this, frame, area);
540: g2.setClip(savedClip);
541: }
542: else {
543: this.background.draw(g2, this, frame, area);
544: }
545: }
546:
547: Iterator iterator = this.layers.iterator();
548: while (iterator.hasNext()) {
549: DialLayer current = (DialLayer) iterator.next();
550: if (current.isVisible()) {
551: if (current.isClippedToWindow()) {
552: Shape savedClip = g2.getClip();
553: g2.setClip(this.dialFrame.getWindow(frame));
554: current.draw(g2, this, frame, area);
555: g2.setClip(savedClip);
556: }
557: else {
558: current.draw(g2, this, frame, area);
559: }
560: }
561: }
562:
563:
564: iterator = this.pointers.iterator();
565: while (iterator.hasNext()) {
566: DialPointer current = (DialPointer) iterator.next();
567: if (current.isVisible()) {
568: if (current.isClippedToWindow()) {
569: Shape savedClip = g2.getClip();
570: g2.setClip(this.dialFrame.getWindow(frame));
571: current.draw(g2, this, frame, area);
572: g2.setClip(savedClip);
573: }
574: else {
575: current.draw(g2, this, frame, area);
576: }
577: }
578: }
579:
580:
581: if (this.cap != null && this.cap.isVisible()) {
582: if (this.cap.isClippedToWindow()) {
583: Shape savedClip = g2.getClip();
584: g2.setClip(this.dialFrame.getWindow(frame));
585: this.cap.draw(g2, this, frame, area);
586: g2.setClip(savedClip);
587: }
588: else {
589: this.cap.draw(g2, this, frame, area);
590: }
591: }
592:
593: if (this.dialFrame.isVisible()) {
594: this.dialFrame.draw(g2, this, frame, area);
595: }
596:
597: }
598:
599:
606: private Rectangle2D viewToFrame(Rectangle2D view) {
607: double width = view.getWidth() / this.viewW;
608: double height = view.getHeight() / this.viewH;
609: double x = view.getX() - (width * this.viewX);
610: double y = view.getY() - (height * this.viewY);
611: return new Rectangle2D.Double(x, y, width, height);
612: }
613:
614:
621: public double getValue(int datasetIndex) {
622: double result = Double.NaN;
623: ValueDataset dataset = getDataset(datasetIndex);
624: if (dataset != null) {
625: Number n = dataset.getValue();
626: if (n != null) {
627: result = n.doubleValue();
628: }
629: }
630: return result;
631: }
632:
633:
640: public void addScale(int index, DialScale scale) {
641: if (scale == null) {
642: throw new IllegalArgumentException("Null 'scale' argument.");
643: }
644: DialScale existing = (DialScale) this.scales.get(index);
645: if (existing != null) {
646: removeLayer(existing);
647: }
648: this.layers.add(scale);
649: this.scales.set(index, scale);
650: scale.addChangeListener(this);
651: notifyListeners(new PlotChangeEvent(this));
652: }
653:
654:
661: public DialScale getScale(int index) {
662: DialScale result = null;
663: if (this.scales.size() > index) {
664: result = (DialScale) this.scales.get(index);
665: }
666: return result;
667: }
668:
669:
675: public void mapDatasetToScale(int index, int scaleIndex) {
676: this.datasetToScaleMap.set(index, new Integer(scaleIndex));
677: notifyListeners(new PlotChangeEvent(this));
678: }
679:
680:
687: public DialScale getScaleForDataset(int datasetIndex) {
688: DialScale result = (DialScale) this.scales.get(0);
689: Integer scaleIndex = (Integer) this.datasetToScaleMap.get(datasetIndex);
690: if (scaleIndex != null) {
691: result = getScale(scaleIndex.intValue());
692: }
693: return result;
694: }
695:
696:
705: public static Rectangle2D rectangleByRadius(Rectangle2D rect,
706: double radiusW, double radiusH) {
707: if (rect == null) {
708: throw new IllegalArgumentException("Null 'rect' argument.");
709: }
710: double x = rect.getCenterX();
711: double y = rect.getCenterY();
712: double w = rect.getWidth() * radiusW;
713: double h = rect.getHeight() * radiusH;
714: return new Rectangle2D.Double(x - w / 2.0, y - h / 2.0, w, h);
715: }
716:
717:
723: public void dialLayerChanged(DialLayerChangeEvent event) {
724: this.notifyListeners(new PlotChangeEvent(this));
725: }
726:
727:
736: public boolean equals(Object obj) {
737: if (obj == this) {
738: return true;
739: }
740: if (!(obj instanceof DialPlot)) {
741: return false;
742: }
743: DialPlot that = (DialPlot) obj;
744: if (!ObjectUtilities.equal(this.background, that.background)) {
745: return false;
746: }
747: if (!ObjectUtilities.equal(this.cap, that.cap)) {
748: return false;
749: }
750: if (!this.dialFrame.equals(that.dialFrame)) {
751: return false;
752: }
753: if (this.viewX != that.viewX) {
754: return false;
755: }
756: if (this.viewY != that.viewY) {
757: return false;
758: }
759: if (this.viewW != that.viewW) {
760: return false;
761: }
762: if (this.viewH != that.viewH) {
763: return false;
764: }
765: if (!this.layers.equals(that.layers)) {
766: return false;
767: }
768: if (!this.pointers.equals(that.pointers)) {
769: return false;
770: }
771: return super.equals(obj);
772: }
773:
774:
779: public int hashCode() {
780: int result = 193;
781: result = 37 * result + ObjectUtilities.hashCode(this.background);
782: result = 37 * result + ObjectUtilities.hashCode(this.cap);
783: result = 37 * result + this.dialFrame.hashCode();
784: long temp = Double.doubleToLongBits(this.viewX);
785: result = 37 * result + (int) (temp ^ (temp >>> 32));
786: temp = Double.doubleToLongBits(this.viewY);
787: result = 37 * result + (int) (temp ^ (temp >>> 32));
788: temp = Double.doubleToLongBits(this.viewW);
789: result = 37 * result + (int) (temp ^ (temp >>> 32));
790: temp = Double.doubleToLongBits(this.viewH);
791: result = 37 * result + (int) (temp ^ (temp >>> 32));
792: return result;
793: }
794:
795:
800: public String getPlotType() {
801: return "DialPlot";
802: }
803:
804:
811: private void writeObject(ObjectOutputStream stream) throws IOException {
812: stream.defaultWriteObject();
813: }
814:
815:
823: private void readObject(ObjectInputStream stream)
824: throws IOException, ClassNotFoundException {
825: stream.defaultReadObject();
826: }
827:
828:
829: }