1:
53:
54: package ;
55:
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65:
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: import ;
80:
81:
84: public class GanttRenderer extends IntervalBarRenderer
85: implements Serializable {
86:
87:
88: private static final long serialVersionUID = -4010349116350119512L;
89:
90:
91: private transient Paint completePaint;
92:
93:
94: private transient Paint incompletePaint;
95:
96:
100: private double startPercent;
101:
102:
106: private double endPercent;
107:
108:
111: public GanttRenderer() {
112: super();
113: setIncludeBaseInRange(false);
114: this.completePaint = Color.green;
115: this.incompletePaint = Color.red;
116: this.startPercent = 0.35;
117: this.endPercent = 0.65;
118: }
119:
120:
127: public Paint getCompletePaint() {
128: return this.completePaint;
129: }
130:
131:
139: public void setCompletePaint(Paint paint) {
140: if (paint == null) {
141: throw new IllegalArgumentException("Null 'paint' argument.");
142: }
143: this.completePaint = paint;
144: notifyListeners(new RendererChangeEvent(this));
145: }
146:
147:
154: public Paint getIncompletePaint() {
155: return this.incompletePaint;
156: }
157:
158:
166: public void setIncompletePaint(Paint paint) {
167: if (paint == null) {
168: throw new IllegalArgumentException("Null 'paint' argument.");
169: }
170: this.incompletePaint = paint;
171: notifyListeners(new RendererChangeEvent(this));
172: }
173:
174:
182: public double getStartPercent() {
183: return this.startPercent;
184: }
185:
186:
194: public void setStartPercent(double percent) {
195: this.startPercent = percent;
196: notifyListeners(new RendererChangeEvent(this));
197: }
198:
199:
207: public double getEndPercent() {
208: return this.endPercent;
209: }
210:
211:
219: public void setEndPercent(double percent) {
220: this.endPercent = percent;
221: notifyListeners(new RendererChangeEvent(this));
222: }
223:
224:
238: public void drawItem(Graphics2D g2,
239: CategoryItemRendererState state,
240: Rectangle2D dataArea,
241: CategoryPlot plot,
242: CategoryAxis domainAxis,
243: ValueAxis rangeAxis,
244: CategoryDataset dataset,
245: int row,
246: int column,
247: int pass) {
248:
249: if (dataset instanceof GanttCategoryDataset) {
250: GanttCategoryDataset gcd = (GanttCategoryDataset) dataset;
251: drawTasks(g2, state, dataArea, plot, domainAxis, rangeAxis, gcd,
252: row, column);
253: }
254: else {
255: super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis,
256: dataset, row, column, pass);
257: }
258:
259: }
260:
261:
274: protected void drawTasks(Graphics2D g2,
275: CategoryItemRendererState state,
276: Rectangle2D dataArea,
277: CategoryPlot plot,
278: CategoryAxis domainAxis,
279: ValueAxis rangeAxis,
280: GanttCategoryDataset dataset,
281: int row,
282: int column) {
283:
284: int count = dataset.getSubIntervalCount(row, column);
285: if (count == 0) {
286: drawTask(g2, state, dataArea, plot, domainAxis, rangeAxis,
287: dataset, row, column);
288: }
289:
290: for (int subinterval = 0; subinterval < count; subinterval++) {
291:
292: RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
293:
294:
295: Number value0 = dataset.getStartValue(row, column, subinterval);
296: if (value0 == null) {
297: return;
298: }
299: double translatedValue0 = rangeAxis.valueToJava2D(
300: value0.doubleValue(), dataArea, rangeAxisLocation);
301:
302:
303: Number value1 = dataset.getEndValue(row, column, subinterval);
304: if (value1 == null) {
305: return;
306: }
307: double translatedValue1 = rangeAxis.valueToJava2D(
308: value1.doubleValue(), dataArea, rangeAxisLocation);
309:
310: if (translatedValue1 < translatedValue0) {
311: double temp = translatedValue1;
312: translatedValue1 = translatedValue0;
313: translatedValue0 = temp;
314: }
315:
316: double rectStart = calculateBarW0(plot, plot.getOrientation(),
317: dataArea, domainAxis, state, row, column);
318: double rectLength = Math.abs(translatedValue1 - translatedValue0);
319: double rectBreadth = state.getBarWidth();
320:
321:
322: Rectangle2D bar = null;
323:
324: if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
325: bar = new Rectangle2D.Double(translatedValue0, rectStart,
326: rectLength, rectBreadth);
327: }
328: else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
329: bar = new Rectangle2D.Double(rectStart, translatedValue0,
330: rectBreadth, rectLength);
331: }
332:
333: Rectangle2D completeBar = null;
334: Rectangle2D incompleteBar = null;
335: Number percent = dataset.getPercentComplete(row, column,
336: subinterval);
337: double start = getStartPercent();
338: double end = getEndPercent();
339: if (percent != null) {
340: double p = percent.doubleValue();
341: if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
342: completeBar = new Rectangle2D.Double(translatedValue0,
343: rectStart + start * rectBreadth, rectLength * p,
344: rectBreadth * (end - start));
345: incompleteBar = new Rectangle2D.Double(translatedValue0
346: + rectLength * p, rectStart + start * rectBreadth,
347: rectLength * (1 - p), rectBreadth * (end - start));
348: }
349: else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
350: completeBar = new Rectangle2D.Double(rectStart + start
351: * rectBreadth, translatedValue0 + rectLength
352: * (1 - p), rectBreadth * (end - start),
353: rectLength * p);
354: incompleteBar = new Rectangle2D.Double(rectStart + start
355: * rectBreadth, translatedValue0, rectBreadth
356: * (end - start), rectLength * (1 - p));
357: }
358:
359: }
360:
361: Paint seriesPaint = getItemPaint(row, column);
362: g2.setPaint(seriesPaint);
363: g2.fill(bar);
364: if (completeBar != null) {
365: g2.setPaint(getCompletePaint());
366: g2.fill(completeBar);
367: }
368: if (incompleteBar != null) {
369: g2.setPaint(getIncompletePaint());
370: g2.fill(incompleteBar);
371: }
372: if (isDrawBarOutline()
373: && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
374: g2.setStroke(getItemStroke(row, column));
375: g2.setPaint(getItemOutlinePaint(row, column));
376: g2.draw(bar);
377: }
378:
379:
380: if (state.getInfo() != null) {
381: EntityCollection entities = state.getEntityCollection();
382: if (entities != null) {
383: String tip = null;
384: if (getToolTipGenerator(row, column) != null) {
385: tip = getToolTipGenerator(row, column).generateToolTip(
386: dataset, row, column);
387: }
388: String url = null;
389: if (getItemURLGenerator(row, column) != null) {
390: url = getItemURLGenerator(row, column).generateURL(
391: dataset, row, column);
392: }
393: CategoryItemEntity entity = new CategoryItemEntity(
394: bar, tip, url, dataset, row,
395: dataset.getColumnKey(column), column);
396: entities.add(entity);
397: }
398: }
399: }
400: }
401:
402:
415: protected void drawTask(Graphics2D g2,
416: CategoryItemRendererState state,
417: Rectangle2D dataArea,
418: CategoryPlot plot,
419: CategoryAxis domainAxis,
420: ValueAxis rangeAxis,
421: GanttCategoryDataset dataset,
422: int row,
423: int column) {
424:
425: PlotOrientation orientation = plot.getOrientation();
426:
427: RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
428:
429:
430: Number value0 = dataset.getEndValue(row, column);
431: if (value0 == null) {
432: return;
433: }
434: double java2dValue0 = rangeAxis.valueToJava2D(value0.doubleValue(),
435: dataArea, rangeAxisLocation);
436:
437:
438: Number value1 = dataset.getStartValue(row, column);
439: if (value1 == null) {
440: return;
441: }
442: double java2dValue1 = rangeAxis.valueToJava2D(value1.doubleValue(),
443: dataArea, rangeAxisLocation);
444:
445: if (java2dValue1 < java2dValue0) {
446: double temp = java2dValue1;
447: java2dValue1 = java2dValue0;
448: java2dValue0 = temp;
449: Number tempNum = value1;
450: value1 = value0;
451: value0 = tempNum;
452: }
453:
454: double rectStart = calculateBarW0(plot, orientation, dataArea,
455: domainAxis, state, row, column);
456: double rectBreadth = state.getBarWidth();
457: double rectLength = Math.abs(java2dValue1 - java2dValue0);
458:
459: Rectangle2D bar = null;
460: if (orientation == PlotOrientation.HORIZONTAL) {
461: bar = new Rectangle2D.Double(java2dValue0, rectStart, rectLength,
462: rectBreadth);
463: }
464: else if (orientation == PlotOrientation.VERTICAL) {
465: bar = new Rectangle2D.Double(rectStart, java2dValue1, rectBreadth,
466: rectLength);
467: }
468:
469: Rectangle2D completeBar = null;
470: Rectangle2D incompleteBar = null;
471: Number percent = dataset.getPercentComplete(row, column);
472: double start = getStartPercent();
473: double end = getEndPercent();
474: if (percent != null) {
475: double p = percent.doubleValue();
476: if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
477: completeBar = new Rectangle2D.Double(java2dValue0,
478: rectStart + start * rectBreadth, rectLength * p,
479: rectBreadth * (end - start));
480: incompleteBar = new Rectangle2D.Double(java2dValue0
481: + rectLength * p, rectStart + start * rectBreadth,
482: rectLength * (1 - p), rectBreadth * (end - start));
483: }
484: else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
485: completeBar = new Rectangle2D.Double(rectStart + start
486: * rectBreadth, java2dValue1 + rectLength * (1 - p),
487: rectBreadth * (end - start), rectLength * p);
488: incompleteBar = new Rectangle2D.Double(rectStart + start
489: * rectBreadth, java2dValue1, rectBreadth * (end
490: - start), rectLength * (1 - p));
491: }
492:
493: }
494:
495: Paint seriesPaint = getItemPaint(row, column);
496: g2.setPaint(seriesPaint);
497: g2.fill(bar);
498:
499: if (completeBar != null) {
500: g2.setPaint(getCompletePaint());
501: g2.fill(completeBar);
502: }
503: if (incompleteBar != null) {
504: g2.setPaint(getIncompletePaint());
505: g2.fill(incompleteBar);
506: }
507:
508:
509: if (isDrawBarOutline()
510: && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
511: Stroke stroke = getItemOutlineStroke(row, column);
512: Paint paint = getItemOutlinePaint(row, column);
513: if (stroke != null && paint != null) {
514: g2.setStroke(stroke);
515: g2.setPaint(paint);
516: g2.draw(bar);
517: }
518: }
519:
520: CategoryItemLabelGenerator generator = getItemLabelGenerator(row,
521: column);
522: if (generator != null && isItemLabelVisible(row, column)) {
523: drawItemLabel(g2, dataset, row, column, plot, generator, bar,
524: false);
525: }
526:
527:
528: if (state.getInfo() != null) {
529: EntityCollection entities = state.getEntityCollection();
530: if (entities != null) {
531: String tip = null;
532: CategoryToolTipGenerator tipster = getToolTipGenerator(row,
533: column);
534: if (tipster != null) {
535: tip = tipster.generateToolTip(dataset, row, column);
536: }
537: String url = null;
538: if (getItemURLGenerator(row, column) != null) {
539: url = getItemURLGenerator(row, column).generateURL(
540: dataset, row, column);
541: }
542: CategoryItemEntity entity = new CategoryItemEntity(bar, tip,
543: url, dataset, row, dataset.getColumnKey(column),
544: column);
545: entities.add(entity);
546: }
547: }
548:
549: }
550:
551:
558: public boolean equals(Object obj) {
559: if (obj == this) {
560: return true;
561: }
562: if (!(obj instanceof GanttRenderer)) {
563: return false;
564: }
565: GanttRenderer that = (GanttRenderer) obj;
566: if (!PaintUtilities.equal(this.completePaint, that.completePaint)) {
567: return false;
568: }
569: if (!PaintUtilities.equal(this.incompletePaint, that.incompletePaint)) {
570: return false;
571: }
572: if (this.startPercent != that.startPercent) {
573: return false;
574: }
575: if (this.endPercent != that.endPercent) {
576: return false;
577: }
578: return super.equals(obj);
579: }
580:
581:
588: private void writeObject(ObjectOutputStream stream) throws IOException {
589: stream.defaultWriteObject();
590: SerialUtilities.writePaint(this.completePaint, stream);
591: SerialUtilities.writePaint(this.incompletePaint, stream);
592: }
593:
594:
602: private void readObject(ObjectInputStream stream)
603: throws IOException, ClassNotFoundException {
604: stream.defaultReadObject();
605: this.completePaint = SerialUtilities.readPaint(stream);
606: this.incompletePaint = SerialUtilities.readPaint(stream);
607: }
608:
609: }