1:
44:
45: package ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52:
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: import ;
67:
68:
75: public class XYBlockRenderer extends AbstractXYItemRenderer
76: implements XYItemRenderer, Cloneable, Serializable {
77:
78:
81: private double blockWidth = 1.0;
82:
83:
86: private double blockHeight = 1.0;
87:
88:
92: private RectangleAnchor blockAnchor = RectangleAnchor.CENTER;
93:
94:
95: private double xOffset;
96:
97:
98: private double yOffset;
99:
100:
101: private PaintScale paintScale;
102:
103:
107: public XYBlockRenderer() {
108: updateOffsets();
109: this.paintScale = new LookupPaintScale();
110: }
111:
112:
119: public double getBlockWidth() {
120: return this.blockWidth;
121: }
122:
123:
130: public void setBlockWidth(double width) {
131: if (width <= 0.0) {
132: throw new IllegalArgumentException(
133: "The 'width' argument must be > 0.0");
134: }
135: this.blockWidth = width;
136: updateOffsets();
137: this.notifyListeners(new RendererChangeEvent(this));
138: }
139:
140:
147: public double getBlockHeight() {
148: return this.blockHeight;
149: }
150:
151:
158: public void setBlockHeight(double height) {
159: if (height <= 0.0) {
160: throw new IllegalArgumentException(
161: "The 'height' argument must be > 0.0");
162: }
163: this.blockHeight = height;
164: updateOffsets();
165: this.notifyListeners(new RendererChangeEvent(this));
166: }
167:
168:
176: public RectangleAnchor getBlockAnchor() {
177: return this.blockAnchor;
178: }
179:
180:
188: public void setBlockAnchor(RectangleAnchor anchor) {
189: if (anchor == null) {
190: throw new IllegalArgumentException("Null 'anchor' argument.");
191: }
192: if (this.blockAnchor.equals(anchor)) {
193: return;
194: }
195: this.blockAnchor = anchor;
196: updateOffsets();
197: notifyListeners(new RendererChangeEvent(this));
198: }
199:
200:
208: public PaintScale getPaintScale() {
209: return this.paintScale;
210: }
211:
212:
220: public void setPaintScale(PaintScale scale) {
221: if (scale == null) {
222: throw new IllegalArgumentException("Null 'scale' argument.");
223: }
224: this.paintScale = scale;
225: notifyListeners(new RendererChangeEvent(this));
226: }
227:
228:
232: private void updateOffsets() {
233: if (this.blockAnchor.equals(RectangleAnchor.BOTTOM_LEFT)) {
234: this.xOffset = 0.0;
235: this.yOffset = 0.0;
236: }
237: else if (this.blockAnchor.equals(RectangleAnchor.BOTTOM)) {
238: this.xOffset = -this.blockWidth / 2.0;
239: this.yOffset = 0.0;
240: }
241: else if (this.blockAnchor.equals(RectangleAnchor.BOTTOM_RIGHT)) {
242: this.xOffset = -this.blockWidth;
243: this.yOffset = 0.0;
244: }
245: else if (this.blockAnchor.equals(RectangleAnchor.LEFT)) {
246: this.xOffset = 0.0;
247: this.yOffset = -this.blockHeight / 2.0;
248: }
249: else if (this.blockAnchor.equals(RectangleAnchor.CENTER)) {
250: this.xOffset = -this.blockWidth / 2.0;
251: this.yOffset = -this.blockHeight / 2.0;
252: }
253: else if (this.blockAnchor.equals(RectangleAnchor.RIGHT)) {
254: this.xOffset = -this.blockWidth;
255: this.yOffset = -this.blockHeight / 2.0;
256: }
257: else if (this.blockAnchor.equals(RectangleAnchor.TOP_LEFT)) {
258: this.xOffset = 0.0;
259: this.yOffset = -this.blockHeight;
260: }
261: else if (this.blockAnchor.equals(RectangleAnchor.TOP)) {
262: this.xOffset = -this.blockWidth / 2.0;
263: this.yOffset = -this.blockHeight;
264: }
265: else if (this.blockAnchor.equals(RectangleAnchor.TOP_RIGHT)) {
266: this.xOffset = -this.blockWidth;
267: this.yOffset = -this.blockHeight;
268: }
269: }
270:
271:
280: public Range findDomainBounds(XYDataset dataset) {
281: if (dataset != null) {
282: Range r = DatasetUtilities.findDomainBounds(dataset, false);
283: return new Range(r.getLowerBound() + this.xOffset,
284: r.getUpperBound() + this.blockWidth + this.xOffset);
285: }
286: else {
287: return null;
288: }
289: }
290:
291:
300: public Range findRangeBounds(XYDataset dataset) {
301: if (dataset != null) {
302: Range r = DatasetUtilities.findRangeBounds(dataset, false);
303: return new Range(r.getLowerBound() + this.yOffset,
304: r.getUpperBound() + this.blockHeight + this.yOffset);
305: }
306: else {
307: return null;
308: }
309: }
310:
311:
327: public void drawItem(Graphics2D g2, XYItemRendererState state,
328: Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot,
329: ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset,
330: int series, int item, CrosshairState crosshairState, int pass) {
331:
332: double x = dataset.getXValue(series, item);
333: double y = dataset.getYValue(series, item);
334: double z = 0.0;
335: if (dataset instanceof XYZDataset) {
336: z = ((XYZDataset) dataset).getZValue(series, item);
337: }
338: Paint p = this.paintScale.getPaint(z);
339: double xx0 = domainAxis.valueToJava2D(x + this.xOffset, dataArea,
340: plot.getDomainAxisEdge());
341: double yy0 = rangeAxis.valueToJava2D(y + this.yOffset, dataArea,
342: plot.getRangeAxisEdge());
343: double xx1 = domainAxis.valueToJava2D(x + this.blockWidth
344: + this.xOffset, dataArea, plot.getDomainAxisEdge());
345: double yy1 = rangeAxis.valueToJava2D(y + this.blockHeight
346: + this.yOffset, dataArea, plot.getRangeAxisEdge());
347: Rectangle2D block;
348: PlotOrientation orientation = plot.getOrientation();
349: if (orientation.equals(PlotOrientation.HORIZONTAL)) {
350: block = new Rectangle2D.Double(Math.min(yy0, yy1),
351: Math.min(xx0, xx1), Math.abs(yy1 - yy0),
352: Math.abs(xx0 - xx1));
353: }
354: else {
355: block = new Rectangle2D.Double(Math.min(xx0, xx1),
356: Math.min(yy0, yy1), Math.abs(xx1 - xx0),
357: Math.abs(yy1 - yy0));
358: }
359: g2.setPaint(p);
360: g2.fill(block);
361: g2.setStroke(new BasicStroke(1.0f));
362: g2.draw(block);
363: }
364:
365:
379: public boolean equals(Object obj) {
380: if (obj == this) {
381: return true;
382: }
383: if (!(obj instanceof XYBlockRenderer)) {
384: return false;
385: }
386: XYBlockRenderer that = (XYBlockRenderer) obj;
387: if (this.blockHeight != that.blockHeight) {
388: return false;
389: }
390: if (this.blockWidth != that.blockWidth) {
391: return false;
392: }
393: if (!this.blockAnchor.equals(that.blockAnchor)) {
394: return false;
395: }
396: if (!this.paintScale.equals(that.paintScale)) {
397: return false;
398: }
399: return super.equals(obj);
400: }
401:
402:
410: public Object clone() throws CloneNotSupportedException {
411: XYBlockRenderer clone = (XYBlockRenderer) super.clone();
412: if (this.paintScale instanceof PublicCloneable) {
413: PublicCloneable pc = (PublicCloneable) this.paintScale;
414: clone.paintScale = (PaintScale) pc.clone();
415: }
416: return clone;
417: }
418:
419: }