1:
43:
44: package ;
45:
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51:
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66:
67:
74: public class XYBlockRenderer extends AbstractXYItemRenderer
75: implements XYItemRenderer, Cloneable, Serializable {
76:
77:
80: private double blockWidth = 1.0;
81:
82:
85: private double blockHeight = 1.0;
86:
87:
91: private RectangleAnchor blockAnchor = RectangleAnchor.CENTER;
92:
93:
94: private double xOffset;
95:
96:
97: private double yOffset;
98:
99:
100: private PaintScale paintScale;
101:
102:
106: public XYBlockRenderer() {
107: updateOffsets();
108: this.paintScale = new LookupPaintScale();
109: }
110:
111:
118: public double getBlockWidth() {
119: return this.blockWidth;
120: }
121:
122:
129: public void setBlockWidth(double width) {
130: if (width <= 0.0) {
131: throw new IllegalArgumentException(
132: "The 'width' argument must be > 0.0");
133: }
134: this.blockWidth = width;
135: updateOffsets();
136: this.notifyListeners(new RendererChangeEvent(this));
137: }
138:
139:
146: public double getBlockHeight() {
147: return this.blockHeight;
148: }
149:
150:
157: public void setBlockHeight(double height) {
158: if (height <= 0.0) {
159: throw new IllegalArgumentException(
160: "The 'height' argument must be > 0.0");
161: }
162: this.blockHeight = height;
163: updateOffsets();
164: this.notifyListeners(new RendererChangeEvent(this));
165: }
166:
167:
175: public RectangleAnchor getBlockAnchor() {
176: return this.blockAnchor;
177: }
178:
179:
187: public void setBlockAnchor(RectangleAnchor anchor) {
188: if (anchor == null) {
189: throw new IllegalArgumentException("Null 'anchor' argument.");
190: }
191: if (this.blockAnchor.equals(anchor)) {
192: return;
193: }
194: this.blockAnchor = anchor;
195: updateOffsets();
196: notifyListeners(new RendererChangeEvent(this));
197: }
198:
199:
207: public PaintScale getPaintScale() {
208: return this.paintScale;
209: }
210:
211:
219: public void setPaintScale(PaintScale scale) {
220: if (scale == null) {
221: throw new IllegalArgumentException("Null 'scale' argument.");
222: }
223: this.paintScale = scale;
224: notifyListeners(new RendererChangeEvent(this));
225: }
226:
227:
231: private void updateOffsets() {
232: if (this.blockAnchor.equals(RectangleAnchor.BOTTOM_LEFT)) {
233: this.xOffset = 0.0;
234: this.yOffset = 0.0;
235: }
236: else if (this.blockAnchor.equals(RectangleAnchor.BOTTOM)) {
237: this.xOffset = -this.blockWidth / 2.0;
238: this.yOffset = 0.0;
239: }
240: else if (this.blockAnchor.equals(RectangleAnchor.BOTTOM_RIGHT)) {
241: this.xOffset = -this.blockWidth;
242: this.yOffset = 0.0;
243: }
244: else if (this.blockAnchor.equals(RectangleAnchor.LEFT)) {
245: this.xOffset = 0.0;
246: this.yOffset = -this.blockHeight / 2.0;
247: }
248: else if (this.blockAnchor.equals(RectangleAnchor.CENTER)) {
249: this.xOffset = -this.blockWidth / 2.0;
250: this.yOffset = -this.blockHeight / 2.0;
251: }
252: else if (this.blockAnchor.equals(RectangleAnchor.RIGHT)) {
253: this.xOffset = -this.blockWidth;
254: this.yOffset = -this.blockHeight / 2.0;
255: }
256: else if (this.blockAnchor.equals(RectangleAnchor.TOP_LEFT)) {
257: this.xOffset = 0.0;
258: this.yOffset = -this.blockHeight;
259: }
260: else if (this.blockAnchor.equals(RectangleAnchor.TOP)) {
261: this.xOffset = -this.blockWidth / 2.0;
262: this.yOffset = -this.blockHeight;
263: }
264: else if (this.blockAnchor.equals(RectangleAnchor.TOP_RIGHT)) {
265: this.xOffset = -this.blockWidth;
266: this.yOffset = -this.blockHeight;
267: }
268: }
269:
270:
281: public Range findDomainBounds(XYDataset dataset) {
282: if (dataset != null) {
283: Range r = DatasetUtilities.findDomainBounds(dataset, false);
284: if (r == null) {
285: return null;
286: }
287: else {
288: return new Range(r.getLowerBound() + this.xOffset,
289: r.getUpperBound() + this.blockWidth + this.xOffset);
290: }
291: }
292: else {
293: return null;
294: }
295: }
296:
297:
308: public Range findRangeBounds(XYDataset dataset) {
309: if (dataset != null) {
310: Range r = DatasetUtilities.findRangeBounds(dataset, false);
311: if (r == null) {
312: return null;
313: }
314: else {
315: return new Range(r.getLowerBound() + this.yOffset,
316: r.getUpperBound() + this.blockHeight + this.yOffset);
317: }
318: }
319: else {
320: return null;
321: }
322: }
323:
324:
340: public void drawItem(Graphics2D g2, XYItemRendererState state,
341: Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot,
342: ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset,
343: int series, int item, CrosshairState crosshairState, int pass) {
344:
345: double x = dataset.getXValue(series, item);
346: double y = dataset.getYValue(series, item);
347: double z = 0.0;
348: if (dataset instanceof XYZDataset) {
349: z = ((XYZDataset) dataset).getZValue(series, item);
350: }
351: Paint p = this.paintScale.getPaint(z);
352: double xx0 = domainAxis.valueToJava2D(x + this.xOffset, dataArea,
353: plot.getDomainAxisEdge());
354: double yy0 = rangeAxis.valueToJava2D(y + this.yOffset, dataArea,
355: plot.getRangeAxisEdge());
356: double xx1 = domainAxis.valueToJava2D(x + this.blockWidth
357: + this.xOffset, dataArea, plot.getDomainAxisEdge());
358: double yy1 = rangeAxis.valueToJava2D(y + this.blockHeight
359: + this.yOffset, dataArea, plot.getRangeAxisEdge());
360: Rectangle2D block;
361: PlotOrientation orientation = plot.getOrientation();
362: if (orientation.equals(PlotOrientation.HORIZONTAL)) {
363: block = new Rectangle2D.Double(Math.min(yy0, yy1),
364: Math.min(xx0, xx1), Math.abs(yy1 - yy0),
365: Math.abs(xx0 - xx1));
366: }
367: else {
368: block = new Rectangle2D.Double(Math.min(xx0, xx1),
369: Math.min(yy0, yy1), Math.abs(xx1 - xx0),
370: Math.abs(yy1 - yy0));
371: }
372: g2.setPaint(p);
373: g2.fill(block);
374: g2.setStroke(new BasicStroke(1.0f));
375: g2.draw(block);
376: }
377:
378:
392: public boolean equals(Object obj) {
393: if (obj == this) {
394: return true;
395: }
396: if (!(obj instanceof XYBlockRenderer)) {
397: return false;
398: }
399: XYBlockRenderer that = (XYBlockRenderer) obj;
400: if (this.blockHeight != that.blockHeight) {
401: return false;
402: }
403: if (this.blockWidth != that.blockWidth) {
404: return false;
405: }
406: if (!this.blockAnchor.equals(that.blockAnchor)) {
407: return false;
408: }
409: if (!this.paintScale.equals(that.paintScale)) {
410: return false;
411: }
412: return super.equals(obj);
413: }
414:
415:
423: public Object clone() throws CloneNotSupportedException {
424: XYBlockRenderer clone = (XYBlockRenderer) super.clone();
425: if (this.paintScale instanceof PublicCloneable) {
426: PublicCloneable pc = (PublicCloneable) this.paintScale;
427: clone.paintScale = (PaintScale) pc.clone();
428: }
429: return clone;
430: }
431:
432: }