KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jasperreports > engine > fill > JRFillCellContents


1 /*
2  * ============================================================================
3  * GNU Lesser General Public License
4  * ============================================================================
5  *
6  * JasperReports - Free Java report-generating library.
7  * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * JasperSoft Corporation
24  * 303 Second Street, Suite 450 North
25  * San Francisco, CA 94107
26  * http://www.jaspersoft.com
27  */

28 package net.sf.jasperreports.engine.fill;
29
30 import java.awt.Color JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35
36 import net.sf.jasperreports.crosstabs.JRCellContents;
37 import net.sf.jasperreports.engine.JRBox;
38 import net.sf.jasperreports.engine.JRDefaultStyleProvider;
39 import net.sf.jasperreports.engine.JRElement;
40 import net.sf.jasperreports.engine.JRException;
41 import net.sf.jasperreports.engine.JRFrame;
42 import net.sf.jasperreports.engine.JRGraphicElement;
43 import net.sf.jasperreports.engine.JRPrintElement;
44 import net.sf.jasperreports.engine.JRPrintFrame;
45 import net.sf.jasperreports.engine.JRStyle;
46 import net.sf.jasperreports.engine.base.JRBaseBox;
47
48 import org.apache.commons.collections.ReferenceMap;
49
50 /**
51  * Crosstab cell contents filler.
52  *
53  * @author Lucian Chirita (lucianc@users.sourceforge.net)
54  * @version $Id: JRFillCellContents.java 1307 2006-06-20 19:01:54 +0300 (Tue, 20 Jun 2006) teodord $
55  */

56 public class JRFillCellContents extends JRFillElementContainer implements JRCellContents, JRCloneable
57 {
58     private final Map JavaDoc transformedContentsCache;
59     private final Map JavaDoc boxContentsCache;
60     private final JRClonePool clonePool;
61     
62     private JRFillCellContents original;
63     
64     private final JRCellContents parentCell;
65     
66     private JRBox box;
67     
68     private int height;
69     private int width;
70     
71     private int x;
72     private int y;
73     private int verticalSpan;
74     private byte verticalPositionType = JRCellContents.POSITION_Y_TOP;
75     
76     private Map JavaDoc templateFrames;
77     
78     private final JRStyle initStyle;
79
80     public JRFillCellContents(JRBaseFiller filler, JRCellContents cell, JRFillObjectFactory factory)
81     {
82         super(filler, cell, factory);
83         
84         parentCell = cell;
85         
86         box = cell.getBox();
87         
88         width = cell.getWidth();
89         height = cell.getHeight();
90         
91         initStyle = factory.getStyle(parentCell.getStyle());
92         
93         initElements();
94         
95         initConditionalStyles();
96         
97         initTemplatesMap();
98         
99         transformedContentsCache = new ReferenceMap();
100         boxContentsCache = new HashMap JavaDoc();
101         clonePool = new JRClonePool(this, true, true);
102     }
103
104     private void initTemplatesMap()
105     {
106         templateFrames = new HashMap JavaDoc();
107     }
108
109     protected JRFillCellContents(JRFillCellContents cellContents, JRFillCloneFactory factory)
110     {
111         super(cellContents, factory);
112         
113         parentCell = cellContents.parentCell;
114         
115         box = cellContents.box;
116         
117         width = cellContents.width;
118         height = cellContents.height;
119         
120         initStyle = cellContents.initStyle;
121         
122         initElements();
123         
124         initConditionalStyles();
125         
126         this.templateFrames = cellContents.templateFrames;
127         
128         transformedContentsCache = new ReferenceMap();
129         boxContentsCache = new HashMap JavaDoc();
130         clonePool = new JRClonePool(this, true, true);
131         
132         verticalPositionType = cellContents.verticalPositionType;
133     }
134
135     public Color JavaDoc getBackcolor()
136     {
137         return parentCell.getBackcolor();
138     }
139
140     public JRBox getBox()
141     {
142         return box;
143     }
144
145     protected void setBox(JRBox box)
146     {
147         this.box = box;
148         
149         initTemplatesMap();
150     }
151     
152     public int getHeight()
153     {
154         return height;
155     }
156     
157     
158     public int getWidth()
159     {
160         return width;
161     }
162     
163     
164     protected void setHeight(int height)
165     {
166         this.height = height;
167     }
168     
169     
170     protected void setWidth(int width)
171     {
172         this.width = width;
173     }
174     
175     
176     public JRFillCellContents getBoxContents(boolean left, boolean top)
177     {
178         if (box == null)
179         {
180             return this;
181         }
182         
183         boolean copyLeft = left && box.getLeftBorder() == JRGraphicElement.PEN_NONE && box.getRightBorder() != JRGraphicElement.PEN_NONE;
184         boolean copyTop = top && box.getTopBorder() == JRGraphicElement.PEN_NONE && box.getBottomBorder() != JRGraphicElement.PEN_NONE;
185         
186         if (!(copyLeft || copyTop))
187         {
188             return this;
189         }
190         
191         Object JavaDoc key = new BoxContents(copyLeft, copyTop);
192         JRFillCellContents boxContents = (JRFillCellContents) boxContentsCache.get(key);
193         if (boxContents == null)
194         {
195             boxContents = (JRFillCellContents) createClone();
196             
197             JRBaseBox newBox = new JRBaseBox(box);
198             
199             if (copyLeft)
200             {
201                 newBox.setLeftBorder(box.getRightBorder());
202                 newBox.setLeftBorderColor(box.getRightBorderColor());
203             }
204             
205             if (copyTop)
206             {
207                 newBox.setTopBorder(box.getBottomBorder());
208                 newBox.setTopBorderColor(box.getBottomBorderColor());
209             }
210             
211             boxContents.setBox(newBox);
212             
213             boxContentsCache.put(key, boxContents);
214         }
215         
216         return boxContents;
217     }
218     
219     
220     public JRFillCellContents getTransformedContents(
221             int newWidth, int newHeight,
222             byte xPosition, byte yPosition) throws JRException
223     {
224         if ((getHeight() == newHeight) &&
225                 (getWidth() == newWidth))
226         {
227             return this;
228         }
229         
230         if (newHeight < getHeight() || newWidth < getWidth())
231         {
232             throw new JRException("Cannot shrink cell contents.");
233         }
234         
235         Object JavaDoc key = new StretchedContents(newWidth, newHeight, xPosition, yPosition);
236         
237         JRFillCellContents transformedCell = (JRFillCellContents) transformedContentsCache.get(key);
238         if (transformedCell == null)
239         {
240             transformedCell = (JRFillCellContents) createClone();
241             transformedCell.transform(newWidth, newHeight, xPosition, yPosition);
242             transformedCell.setElementsBandBottomY();
243             
244             transformedContentsCache.put(key, transformedCell);
245         }
246         
247         return transformedCell;
248     }
249     
250     
251     private void transform(int newWidth, int newHeight, byte xPosition, byte yPosition)
252     {
253         transformElements(newWidth, newHeight, xPosition, yPosition);
254         
255         width = newWidth;
256         height = newHeight;
257     }
258
259     private void transformElements(int newWidth, int newHeight, byte xPosition, byte yPosition)
260     {
261         if ((height == newHeight || yPosition == JRCellContents.POSITION_Y_TOP) &&
262                 (width == newWidth || xPosition == JRCellContents.POSITION_X_LEFT))
263         {
264             return;
265         }
266
267         double scaleX = -1d;
268         int offsetX = 0;
269         switch (xPosition)
270         {
271             case JRCellContents.POSITION_X_CENTER:
272                 offsetX = (newWidth - width) / 2;
273                 break;
274             case JRCellContents.POSITION_X_RIGHT:
275                 offsetX = newWidth - width;
276                 break;
277             case JRCellContents.POSITION_X_STRETCH:
278                 scaleX = ((double) newWidth) / width;
279                 break;
280         }
281         
282         double scaleY = -1d;
283         int offsetY = 0;
284         switch (yPosition)
285         {
286             case JRCellContents.POSITION_Y_MIDDLE:
287                 offsetY = (newHeight - height) / 2;
288                 break;
289             case JRCellContents.POSITION_Y_BOTTOM:
290                 offsetY = newHeight - height;
291                 break;
292             case JRCellContents.POSITION_X_STRETCH:
293                 scaleY = ((double) newHeight) / height;
294                 break;
295         }
296         
297         transformElements(getElements(), scaleX, offsetX, scaleY, offsetY);
298     }
299
300     private static void transformElements(JRElement[] elements, double scaleX, int offsetX, double scaleY, int offsetY)
301     {
302         if (elements != null)
303         {
304             for (int i = 0; i < elements.length; i++)
305             {
306                 JRFillElement element = (JRFillElement) elements[i];
307                 
308                 if (scaleX != -1d)
309                 {
310                     element.setX((int) (element.getX() * scaleX));
311                     element.setWidth((int) (element.getWidth() * scaleX));
312                 }
313                 
314                 if (offsetX != 0)
315                 {
316                     element.setX(element.getX() + offsetX);
317                 }
318                 
319                 if (scaleY != -1d)
320                 {
321                     element.setY((int) (element.getY() * scaleY));
322                     element.setHeight((int) (element.getHeight() * scaleY));
323                 }
324                 
325                 if (offsetY != 0)
326                 {
327                     element.setY(element.getY() + offsetY);
328                 }
329                 
330                 if (element instanceof JRFrame)
331                 {
332                     JRElement[] frameElements = ((JRFrame) element).getElements();
333                     transformElements(frameElements, scaleX, offsetX, scaleY, offsetY);
334                 }
335             }
336         }
337     }
338     
339     
340     protected void prepare(int availableStretchHeight) throws JRException
341     {
342         initFill();
343         resetElements();
344         prepareElements(availableStretchHeight, true);
345     }
346
347     
348     protected JRPrintFrame fill() throws JRException
349     {
350         stretchElements();
351         moveBandBottomElements();
352         removeBlankElements();
353
354         JRTemplatePrintFrame printCell = new JRTemplatePrintFrame(getTemplateFrame());
355         printCell.setX(x);
356         printCell.setY(y);
357         printCell.setWidth(width);
358         
359         fillElements(printCell);
360         
361         verticallyPositionElements(printCell);
362         
363         printCell.setHeight(getPrintHeight());
364         
365         return printCell;
366     }
367
368     
369     private JRTemplateFrame getTemplateFrame()
370     {
371         JRStyle style = getStyle();
372         JRTemplateFrame template = (JRTemplateFrame) templateFrames.get(style);
373         if (template == null)
374         {
375             template = new JRTemplateFrame(filler.getJasperPrint().getDefaultStyleProvider(), this);
376             templateFrames.put(style, template);
377         }
378         return template;
379     }
380
381     
382     protected void verticallyPositionElements(JRTemplatePrintFrame printCell)
383     {
384         int positionOffset;
385         
386         switch (verticalPositionType)
387         {
388             case JRCellContents.POSITION_Y_MIDDLE:
389                 positionOffset = (getStretchHeight() - getContainerHeight()) / 2;
390                 break;
391             case JRCellContents.POSITION_Y_BOTTOM:
392                 positionOffset = getStretchHeight() - getContainerHeight();
393                 break;
394             default:
395                 positionOffset = 0;
396                 break;
397         }
398         
399         if (positionOffset != 0)
400         {
401             List JavaDoc printElements = printCell.getElements();
402             
403             int positionY = getStretchHeight() - positionOffset;
404             boolean outside = false;
405             for (Iterator JavaDoc it = printElements.iterator(); !outside && it.hasNext();)
406             {
407                 JRPrintElement element = (JRPrintElement) it.next();
408                 outside = element.getY() > positionY;
409             }
410             
411             if (!outside)
412             {
413                 for (Iterator JavaDoc it = printElements.iterator(); it.hasNext();)
414                 {
415                     JRPrintElement element = (JRPrintElement) it.next();
416                     element.setY(element.getY() + positionOffset);
417                 }
418             }
419         }
420     }
421
422     protected int getPrintHeight()
423     {
424         return getStretchHeight() + getTopPadding() + getBottomPadding();
425     }
426
427     protected void stretchTo(int stretchHeight)
428     {
429         setStretchHeight(stretchHeight - getTopPadding() - getBottomPadding());
430     }
431     
432     protected static class BoxContents
433     {
434         final boolean left;
435         final boolean top;
436         final int hashCode;
437         
438         public BoxContents(boolean left, boolean top)
439         {
440             this.left = left;
441             this.top = top;
442             
443             int hash = left ? 1231 : 1237;
444             hash = 31*hash + (top ? 1231 : 1237);
445             hashCode = hash;
446         }
447
448         public boolean equals(Object JavaDoc obj)
449         {
450             if (obj == this)
451             {
452                 return true;
453             }
454             
455             BoxContents b = (BoxContents) obj;
456             
457             return
458                 b.left == left && b.top == top;
459         }
460
461         public int hashCode()
462         {
463             return hashCode;
464         }
465     }
466     
467     protected static class StretchedContents
468     {
469         final int newHeight;
470         final int newWidth;
471         final int hashCode;
472         final byte xPosition;
473         final byte yPosition;
474         
475         StretchedContents(
476                 int newWidth, int newHeight, byte xPosition, byte yPosition)
477         {
478             this.newHeight = newHeight;
479             this.newWidth = newWidth;
480             this.xPosition = xPosition;
481             this.yPosition = yPosition;
482             
483             int hash = newHeight;
484             hash = 31*hash + newWidth;
485             hash = 31*hash + xPosition;
486             hash = 31*hash + yPosition;
487             hashCode = hash;
488         }
489         
490         public boolean equals(Object JavaDoc o)
491         {
492             if (o == this)
493             {
494                 return true;
495             }
496             
497             StretchedContents s = (StretchedContents) o;
498             
499             return
500                 s.newHeight == newHeight && s.newWidth == newWidth &&
501                 s.xPosition == xPosition && s.yPosition == yPosition;
502         }
503         
504         public int hashCode()
505         {
506             return hashCode;
507         }
508     }
509
510     protected int getContainerHeight()
511     {
512         return getHeight() - getTopPadding() - getBottomPadding();
513     }
514     
515     protected int getTopPadding()
516     {
517         return box == null ? 0 : box.getTopPadding();
518     }
519     
520     protected int getBottomPadding()
521     {
522         return box == null ? 0 : box.getBottomPadding();
523     }
524
525     public JRCloneable createClone()
526     {
527         JRFillCloneFactory factory = new JRFillCloneFactory();
528         return createClone(factory);
529     }
530
531     public JRCloneable createClone(JRFillCloneFactory factory)
532     {
533         return new JRFillCellContents(this, factory);
534     }
535     
536     public JRFillCellContents getWorkingClone()
537     {
538         JRFillCellContents clone = (JRFillCellContents) clonePool.getClone();
539         clone.original = this;
540         return clone;
541     }
542     
543     public void releaseWorkingClone()
544     {
545         original.clonePool.releaseClone(this);
546     }
547
548     public void setX(int x)
549     {
550         this.x = x;
551     }
552
553     public void setY(int y)
554     {
555         this.y = y;
556     }
557
558     public int getVerticalSpan()
559     {
560         return verticalSpan;
561     }
562
563     public void setVerticalSpan(int span)
564     {
565         verticalSpan = span;
566     }
567
568     public void setVerticalPositionType(byte positionType)
569     {
570         this.verticalPositionType = positionType;
571     }
572
573     protected void evaluate(byte evaluation) throws JRException
574     {
575         super.evaluate(evaluation);
576         evaluateConditionalStyles(evaluation);
577     }
578
579     public JRDefaultStyleProvider getDefaultStyleProvider()
580     {
581         return parentCell.getDefaultStyleProvider();
582     }
583
584     public JRStyle getStyle()
585     {
586         JRStyle crtStyle = initStyle;
587         
588         boolean isUsingDefaultStyle = false;
589
590         if (crtStyle == null)
591         {
592             crtStyle = filler.getDefaultStyle();
593             isUsingDefaultStyle = true;
594         }
595
596         JRStyle evalStyle = getEvaluatedConditionalStyle(crtStyle);
597         
598         if (isUsingDefaultStyle && evalStyle == crtStyle)
599             evalStyle = null;
600         
601         return evalStyle;
602     }
603
604     protected void initConditionalStyles()
605     {
606         super.initConditionalStyles();
607         collectConditionalStyle(initStyle);
608     }
609
610     public Byte JavaDoc getMode()
611     {
612         return parentCell.getMode();
613     }
614 }
615
Popular Tags