1:
59:
60: package ;
61:
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78:
79: import ;
80:
81: import ;
82: import ;
83: import ;
84: import ;
85: import ;
86: import ;
87: import ;
88: import ;
89: import ;
90:
91:
98: public class MinMaxCategoryRenderer extends AbstractCategoryItemRenderer {
99:
100:
101: private static final long serialVersionUID = 2935615937671064911L;
102:
103:
104: private boolean plotLines = false;
105:
106:
109: private transient Paint groupPaint = Color.black;
110:
111:
114: private transient Stroke groupStroke = new BasicStroke(1.0f);
115:
116:
117: private transient Icon minIcon = getIcon(new Arc2D.Double(-4, -4, 8, 8, 0,
118: 360, Arc2D.OPEN), null, Color.black);
119:
120:
121: private transient Icon maxIcon = getIcon(new Arc2D.Double(-4, -4, 8, 8, 0,
122: 360, Arc2D.OPEN), null, Color.black);
123:
124:
125: private transient Icon objectIcon = getIcon(new Line2D.Double(-4, 0, 4, 0),
126: false, true);
127:
128:
129: private int lastCategory = -1;
130:
131:
132: private double min;
133:
134:
135: private double max;
136:
137:
140: public MinMaxCategoryRenderer() {
141: super();
142: }
143:
144:
152: public boolean isDrawLines() {
153: return this.plotLines;
154: }
155:
156:
165: public void setDrawLines(boolean draw) {
166: if (this.plotLines != draw) {
167: this.plotLines = draw;
168: this.notifyListeners(new RendererChangeEvent(this));
169: }
170:
171: }
172:
173:
181: public Paint getGroupPaint() {
182: return this.groupPaint;
183: }
184:
185:
194: public void setGroupPaint(Paint paint) {
195: if (paint == null) {
196: throw new IllegalArgumentException("Null 'paint' argument.");
197: }
198: this.groupPaint = paint;
199: notifyListeners(new RendererChangeEvent(this));
200: }
201:
202:
210: public Stroke getGroupStroke() {
211: return this.groupStroke;
212: }
213:
214:
221: public void setGroupStroke(Stroke stroke) {
222: if (stroke == null) {
223: throw new IllegalArgumentException("Null 'stroke' argument.");
224: }
225: this.groupStroke = stroke;
226: notifyListeners(new RendererChangeEvent(this));
227: }
228:
229:
236: public Icon getObjectIcon() {
237: return this.objectIcon;
238: }
239:
240:
247: public void setObjectIcon(Icon icon) {
248: if (icon == null) {
249: throw new IllegalArgumentException("Null 'icon' argument.");
250: }
251: this.objectIcon = icon;
252: notifyListeners(new RendererChangeEvent(this));
253: }
254:
255:
263: public Icon getMaxIcon() {
264: return this.maxIcon;
265: }
266:
267:
276: public void setMaxIcon(Icon icon) {
277: if (icon == null) {
278: throw new IllegalArgumentException("Null 'icon' argument.");
279: }
280: this.maxIcon = icon;
281: notifyListeners(new RendererChangeEvent(this));
282: }
283:
284:
292: public Icon getMinIcon() {
293: return this.minIcon;
294: }
295:
296:
305: public void setMinIcon(Icon icon) {
306: if (icon == null) {
307: throw new IllegalArgumentException("Null 'icon' argument.");
308: }
309: this.minIcon = icon;
310: notifyListeners(new RendererChangeEvent(this));
311: }
312:
313:
327: public void drawItem(Graphics2D g2, CategoryItemRendererState state,
328: Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis,
329: ValueAxis rangeAxis, CategoryDataset dataset, int row, int column,
330: int pass) {
331:
332:
333: Number value = dataset.getValue(row, column);
334: if (value != null) {
335:
336: double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(),
337: dataArea, plot.getDomainAxisEdge());
338: double y1 = rangeAxis.valueToJava2D(value.doubleValue(), dataArea,
339: plot.getRangeAxisEdge());
340: g2.setPaint(getItemPaint(row, column));
341: g2.setStroke(getItemStroke(row, column));
342: Shape shape = null;
343: shape = new Rectangle2D.Double(x1 - 4, y1 - 4, 8.0, 8.0);
344:
345: PlotOrientation orient = plot.getOrientation();
346: if (orient == PlotOrientation.VERTICAL) {
347: this.objectIcon.paintIcon(null, g2, (int) x1, (int) y1);
348: }
349: else {
350: this.objectIcon.paintIcon(null, g2, (int) y1, (int) x1);
351: }
352:
353: if (this.lastCategory == column) {
354: if (this.min > value.doubleValue()) {
355: this.min = value.doubleValue();
356: }
357: if (this.max < value.doubleValue()) {
358: this.max = value.doubleValue();
359: }
360:
361:
362: if (dataset.getRowCount() - 1 == row) {
363: g2.setPaint(this.groupPaint);
364: g2.setStroke(this.groupStroke);
365: double minY = rangeAxis.valueToJava2D(this.min, dataArea,
366: plot.getRangeAxisEdge());
367: double maxY = rangeAxis.valueToJava2D(this.max, dataArea,
368: plot.getRangeAxisEdge());
369:
370: if (orient == PlotOrientation.VERTICAL) {
371: g2.draw(new Line2D.Double(x1, minY, x1, maxY));
372: this.minIcon.paintIcon(null, g2, (int) x1, (int) minY);
373: this.maxIcon.paintIcon(null, g2, (int) x1, (int) maxY);
374: }
375: else {
376: g2.draw(new Line2D.Double(minY, x1, maxY, x1));
377: this.minIcon.paintIcon(null, g2, (int) minY, (int) x1);
378: this.maxIcon.paintIcon(null, g2, (int) maxY, (int) x1);
379: }
380: }
381: }
382: else {
383: this.lastCategory = column;
384: this.min = value.doubleValue();
385: this.max = value.doubleValue();
386: }
387:
388:
389: if (this.plotLines) {
390: if (column != 0) {
391: Number previousValue = dataset.getValue(row, column - 1);
392: if (previousValue != null) {
393:
394: double previous = previousValue.doubleValue();
395: double x0 = domainAxis.getCategoryMiddle(column - 1,
396: getColumnCount(), dataArea,
397: plot.getDomainAxisEdge());
398: double y0 = rangeAxis.valueToJava2D(previous, dataArea,
399: plot.getRangeAxisEdge());
400: g2.setPaint(getItemPaint(row, column));
401: g2.setStroke(getItemStroke(row, column));
402: Line2D line;
403: if (orient == PlotOrientation.VERTICAL) {
404: line = new Line2D.Double(x0, y0, x1, y1);
405: }
406: else {
407: line = new Line2D.Double(y0, x0, y1, x1);
408: }
409: g2.draw(line);
410: }
411: }
412: }
413:
414:
415: EntityCollection entities = state.getEntityCollection();
416: if (entities != null && shape != null) {
417: addItemEntity(entities, dataset, row, column, shape);
418: }
419: }
420: }
421:
422:
433: public boolean equals(Object obj) {
434: if (obj == this) {
435: return true;
436: }
437: if (!(obj instanceof MinMaxCategoryRenderer)) {
438: return false;
439: }
440: MinMaxCategoryRenderer that = (MinMaxCategoryRenderer) obj;
441: if (this.plotLines != that.plotLines) {
442: return false;
443: }
444: if (!PaintUtilities.equal(this.groupPaint, that.groupPaint)) {
445: return false;
446: }
447: if (!this.groupStroke.equals(that.groupStroke)) {
448: return false;
449: }
450: return super.equals(obj);
451: }
452:
453:
462: private Icon getIcon(Shape shape, final Paint fillPaint,
463: final Paint outlinePaint) {
464:
465: final int width = shape.getBounds().width;
466: final int height = shape.getBounds().height;
467: final GeneralPath path = new GeneralPath(shape);
468: return new Icon() {
469: public void paintIcon(Component c, Graphics g, int x, int y) {
470: Graphics2D g2 = (Graphics2D) g;
471: path.transform(AffineTransform.getTranslateInstance(x, y));
472: if (fillPaint != null) {
473: g2.setPaint(fillPaint);
474: g2.fill(path);
475: }
476: if (outlinePaint != null) {
477: g2.setPaint(outlinePaint);
478: g2.draw(path);
479: }
480: path.transform(AffineTransform.getTranslateInstance(-x, -y));
481: }
482:
483: public int getIconWidth() {
484: return width;
485: }
486:
487: public int getIconHeight() {
488: return height;
489: }
490:
491: };
492: }
493:
494:
503: private Icon getIcon(Shape shape, final boolean fill,
504: final boolean outline) {
505: final int width = shape.getBounds().width;
506: final int height = shape.getBounds().height;
507: final GeneralPath path = new GeneralPath(shape);
508: return new Icon() {
509: public void paintIcon(Component c, Graphics g, int x, int y) {
510: Graphics2D g2 = (Graphics2D) g;
511: path.transform(AffineTransform.getTranslateInstance(x, y));
512: if (fill) {
513: g2.fill(path);
514: }
515: if (outline) {
516: g2.draw(path);
517: }
518: path.transform(AffineTransform.getTranslateInstance(-x, -y));
519: }
520:
521: public int getIconWidth() {
522: return width;
523: }
524:
525: public int getIconHeight() {
526: return height;
527: }
528: };
529: }
530:
531:
538: private void writeObject(ObjectOutputStream stream) throws IOException {
539: stream.defaultWriteObject();
540: SerialUtilities.writeStroke(this.groupStroke, stream);
541: SerialUtilities.writePaint(this.groupPaint, stream);
542: }
543:
544:
552: private void readObject(ObjectInputStream stream)
553: throws IOException, ClassNotFoundException {
554: stream.defaultReadObject();
555: this.groupStroke = SerialUtilities.readStroke(stream);
556: this.groupPaint = SerialUtilities.readPaint(stream);
557:
558: this.minIcon = getIcon(new Arc2D.Double(-4, -4, 8, 8, 0, 360,
559: Arc2D.OPEN), null, Color.black);
560: this.maxIcon = getIcon(new Arc2D.Double(-4, -4, 8, 8, 0, 360,
561: Arc2D.OPEN), null, Color.black);
562: this.objectIcon = getIcon(new Line2D.Double(-4, 0, 4, 0), false, true);
563: }
564:
565: }