1:
60:
61: package ;
62:
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: import ;
79:
80: import ;
81:
82: import ;
83: import ;
84: import ;
85: import ;
86: import ;
87: import ;
88: import ;
89: import ;
90: import ;
91: import ;
92:
93:
100: public class MinMaxCategoryRenderer extends AbstractCategoryItemRenderer {
101:
102:
103: private static final long serialVersionUID = 2935615937671064911L;
104:
105:
106: private boolean plotLines = false;
107:
108:
111: private transient Paint groupPaint = Color.black;
112:
113:
116: private transient Stroke groupStroke = new BasicStroke(1.0f);
117:
118:
119: private transient Icon minIcon = getIcon(new Arc2D.Double(-4, -4, 8, 8, 0,
120: 360, Arc2D.OPEN), null, Color.black);
121:
122:
123: private transient Icon maxIcon = getIcon(new Arc2D.Double(-4, -4, 8, 8, 0,
124: 360, Arc2D.OPEN), null, Color.black);
125:
126:
127: private transient Icon objectIcon = getIcon(new Line2D.Double(-4, 0, 4, 0),
128: false, true);
129:
130:
131: private int lastCategory = -1;
132:
133:
134: private double min;
135:
136:
137: private double max;
138:
139:
142: public MinMaxCategoryRenderer() {
143: super();
144: }
145:
146:
154: public boolean isDrawLines() {
155: return this.plotLines;
156: }
157:
158:
167: public void setDrawLines(boolean draw) {
168: if (this.plotLines != draw) {
169: this.plotLines = draw;
170: this.notifyListeners(new RendererChangeEvent(this));
171: }
172:
173: }
174:
175:
183: public Paint getGroupPaint() {
184: return this.groupPaint;
185: }
186:
187:
196: public void setGroupPaint(Paint paint) {
197: if (paint == null) {
198: throw new IllegalArgumentException("Null 'paint' argument.");
199: }
200: this.groupPaint = paint;
201: notifyListeners(new RendererChangeEvent(this));
202: }
203:
204:
212: public Stroke getGroupStroke() {
213: return this.groupStroke;
214: }
215:
216:
222: public void setGroupStroke(Stroke groupStroke) {
223: this.groupStroke = groupStroke;
224: }
225:
226:
233: public Icon getObjectIcon() {
234: return this.objectIcon;
235: }
236:
237:
244: public void setObjectIcon(Icon icon) {
245: if (icon == null) {
246: throw new IllegalArgumentException("Null 'icon' argument.");
247: }
248: this.objectIcon = icon;
249: notifyListeners(new RendererChangeEvent(this));
250: }
251:
252:
260: public Icon getMaxIcon() {
261: return this.maxIcon;
262: }
263:
264:
273: public void setMaxIcon(Icon icon) {
274: if (icon == null) {
275: throw new IllegalArgumentException("Null 'icon' argument.");
276: }
277: this.maxIcon = icon;
278: notifyListeners(new RendererChangeEvent(this));
279: }
280:
281:
289: public Icon getMinIcon() {
290: return this.minIcon;
291: }
292:
293:
302: public void setMinIcon(Icon icon) {
303: if (icon == null) {
304: throw new IllegalArgumentException("Null 'icon' argument.");
305: }
306: this.minIcon = icon;
307: notifyListeners(new RendererChangeEvent(this));
308: }
309:
310:
324: public void drawItem(Graphics2D g2, CategoryItemRendererState state,
325: Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis,
326: ValueAxis rangeAxis, CategoryDataset dataset, int row, int column,
327: int pass) {
328:
329:
330: Number value = dataset.getValue(row, column);
331: if (value != null) {
332:
333: double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(),
334: dataArea, plot.getDomainAxisEdge());
335: double y1 = rangeAxis.valueToJava2D(value.doubleValue(), dataArea,
336: plot.getRangeAxisEdge());
337: g2.setPaint(getItemPaint(row, column));
338: g2.setStroke(getItemStroke(row, column));
339: Shape shape = null;
340: shape = new Rectangle2D.Double(x1 - 4, y1 - 4, 8.0, 8.0);
341:
342: PlotOrientation orient = plot.getOrientation();
343: if (orient == PlotOrientation.VERTICAL) {
344: this.objectIcon.paintIcon(null, g2, (int) x1, (int) y1);
345: }
346: else {
347: this.objectIcon.paintIcon(null, g2, (int) y1, (int) x1);
348: }
349:
350: if (this.lastCategory == column) {
351: if (this.min > value.doubleValue()) {
352: this.min = value.doubleValue();
353: }
354: if (this.max < value.doubleValue()) {
355: this.max = value.doubleValue();
356: }
357:
358:
359: if (dataset.getRowCount() - 1 == row) {
360: g2.setPaint(this.groupPaint);
361: g2.setStroke(this.groupStroke);
362: double minY = rangeAxis.valueToJava2D(this.min, dataArea,
363: plot.getRangeAxisEdge());
364: double maxY = rangeAxis.valueToJava2D(this.max, dataArea,
365: plot.getRangeAxisEdge());
366:
367: if (orient == PlotOrientation.VERTICAL) {
368: g2.draw(new Line2D.Double(x1, minY, x1, maxY));
369: this.minIcon.paintIcon(null, g2, (int) x1, (int) minY);
370: this.maxIcon.paintIcon(null, g2, (int) x1, (int) maxY);
371: }
372: else {
373: g2.draw(new Line2D.Double(minY, x1, maxY, x1));
374: this.minIcon.paintIcon(null, g2, (int) minY, (int) x1);
375: this.maxIcon.paintIcon(null, g2, (int) maxY, (int) x1);
376: }
377: }
378: }
379: else {
380: this.lastCategory = column;
381: this.min = value.doubleValue();
382: this.max = value.doubleValue();
383: }
384:
385:
386: if (this.plotLines) {
387: if (column != 0) {
388: Number previousValue = dataset.getValue(row, column - 1);
389: if (previousValue != null) {
390:
391: double previous = previousValue.doubleValue();
392: double x0 = domainAxis.getCategoryMiddle(column - 1,
393: getColumnCount(), dataArea,
394: plot.getDomainAxisEdge());
395: double y0 = rangeAxis.valueToJava2D(previous, dataArea,
396: plot.getRangeAxisEdge());
397: g2.setPaint(getItemPaint(row, column));
398: g2.setStroke(getItemStroke(row, column));
399: Line2D line;
400: if (orient == PlotOrientation.VERTICAL) {
401: line = new Line2D.Double(x0, y0, x1, y1);
402: }
403: else {
404: line = new Line2D.Double(y0, x0, y1, x1);
405: }
406: g2.draw(line);
407: }
408: }
409: }
410:
411:
412: if (state.getInfo() != null) {
413: EntityCollection entities = state.getEntityCollection();
414: if (entities != null && shape != null) {
415: String tip = null;
416: CategoryToolTipGenerator tipster = getToolTipGenerator(row,
417: column);
418: if (tipster != null) {
419: tip = tipster.generateToolTip(dataset, row, column);
420: }
421: CategoryItemEntity entity = new CategoryItemEntity(
422: shape, tip, null, dataset, row,
423: dataset.getColumnKey(column), column);
424: entities.add(entity);
425: }
426: }
427: }
428: }
429:
430:
439: private Icon getIcon(Shape shape, final Paint fillPaint,
440: final Paint outlinePaint) {
441:
442: final int width = shape.getBounds().width;
443: final int height = shape.getBounds().height;
444: final GeneralPath path = new GeneralPath(shape);
445: return new Icon() {
446: public void paintIcon(Component c, Graphics g, int x, int y) {
447: Graphics2D g2 = (Graphics2D) g;
448: path.transform(AffineTransform.getTranslateInstance(x, y));
449: if (fillPaint != null) {
450: g2.setPaint(fillPaint);
451: g2.fill(path);
452: }
453: if (outlinePaint != null) {
454: g2.setPaint(outlinePaint);
455: g2.draw(path);
456: }
457: path.transform(AffineTransform.getTranslateInstance(-x, -y));
458: }
459:
460: public int getIconWidth() {
461: return width;
462: }
463:
464: public int getIconHeight() {
465: return height;
466: }
467:
468: };
469: }
470:
471:
480: private Icon getIcon(Shape shape, final boolean fill,
481: final boolean outline) {
482: final int width = shape.getBounds().width;
483: final int height = shape.getBounds().height;
484: final GeneralPath path = new GeneralPath(shape);
485: return new Icon() {
486: public void paintIcon(Component c, Graphics g, int x, int y) {
487: Graphics2D g2 = (Graphics2D) g;
488: path.transform(AffineTransform.getTranslateInstance(x, y));
489: if (fill) {
490: g2.fill(path);
491: }
492: if (outline) {
493: g2.draw(path);
494: }
495: path.transform(AffineTransform.getTranslateInstance(-x, -y));
496: }
497:
498: public int getIconWidth() {
499: return width;
500: }
501:
502: public int getIconHeight() {
503: return height;
504: }
505: };
506: }
507:
508:
515: private void writeObject(ObjectOutputStream stream) throws IOException {
516: stream.defaultWriteObject();
517: SerialUtilities.writeStroke(this.groupStroke, stream);
518: SerialUtilities.writePaint(this.groupPaint, stream);
519: }
520:
521:
529: private void readObject(ObjectInputStream stream)
530: throws IOException, ClassNotFoundException {
531: stream.defaultReadObject();
532: this.groupStroke = SerialUtilities.readStroke(stream);
533: this.groupPaint = SerialUtilities.readPaint(stream);
534:
535: this.minIcon = getIcon(new Arc2D.Double(-4, -4, 8, 8, 0, 360,
536: Arc2D.OPEN), null, Color.black);
537: this.maxIcon = getIcon(new Arc2D.Double(-4, -4, 8, 8, 0, 360,
538: Arc2D.OPEN), null, Color.black);
539: this.objectIcon = getIcon(new Line2D.Double(-4, 0, 4, 0), false, true);
540: }
541:
542: }