001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * NumberFieldElementFactory.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.elementfactory;
030:
031: import java.awt.Color;
032: import java.awt.geom.Rectangle2D;
033: import java.text.DecimalFormat;
034: import java.text.NumberFormat;
035:
036: import org.jfree.report.Element;
037: import org.jfree.report.ElementAlignment;
038: import org.jfree.report.TextElement;
039: import org.jfree.report.filter.DataRowDataSource;
040: import org.jfree.report.filter.DataSource;
041: import org.jfree.report.filter.NumberFormatFilter;
042: import org.jfree.report.filter.templates.NumberFieldTemplate;
043: import org.jfree.report.style.ElementStyleKeys;
044: import org.jfree.report.style.FontDefinition;
045:
046: /**
047: * The number format factory can be used to create numeric text elements. These text
048: * elements have special abilities to format numeric values.
049: * <p/>
050: * Once the desired properties are set, the factory can be reused to create similiar text
051: * elements.
052: *
053: * @author Thomas Morgner
054: */
055: public class NumberFieldElementFactory extends TextFieldElementFactory {
056: /**
057: * The default format pattern that mimics the Integer.toString() result.
058: */
059: private static final String DECIMALFORMAT_DEFAULT_PATTERN = "#,###.###################################################"
060: + "#########################################################"
061: + "#########################################################"
062: + "#########################################################"
063: + "#########################################################"
064: + "#########################################################"
065: + "####";
066:
067: /**
068: * The number format instance used to format numeric values in the text element.
069: */
070: private NumberFormat format;
071: /** The cell format for the excel export. */
072: private String excelCellFormat;
073:
074: /**
075: * Creates a new number field element factory.
076: */
077: public NumberFieldElementFactory() {
078: }
079:
080: /**
081: * Returns the excel export cell format.
082: *
083: * @return the excel cell format.
084: */
085: public String getExcelCellFormat() {
086: return excelCellFormat;
087: }
088:
089: /**
090: * Defines a special cell format that should be used when exporting the report
091: * into Excel workbooks.
092: *
093: * @param excelCellFormat the excel cell format
094: */
095: public void setExcelCellFormat(final String excelCellFormat) {
096: this .excelCellFormat = excelCellFormat;
097: }
098:
099: /**
100: * Returns the number format used for all generated text elements. The number format is
101: * shared among all generated elements.
102: *
103: * @return the number format used in this factory.
104: */
105: public NumberFormat getFormat() {
106: return format;
107: }
108:
109: /**
110: * Defines the number format used for all generated text elements. The number format is
111: * shared among all generated elements.
112: *
113: * @param format the number format used in this factory.
114: */
115: public void setFormat(final NumberFormat format) {
116: this .format = format;
117: }
118:
119: /**
120: * Returns the format string of the used number format. This method will return null, if
121: * the current number format is no instance of DecimalFormat.
122: *
123: * @return the formatstring of the number format instance.
124: */
125: public String getFormatString() {
126: if (getFormat() instanceof DecimalFormat) {
127: final DecimalFormat decFormat = (DecimalFormat) getFormat();
128: return decFormat.toPattern();
129: }
130: return null;
131: }
132:
133: /**
134: * Defines the format string of the used number format. This method will replace the
135: * number format instance of this factory.
136: *
137: * @param formatString the formatstring of the number format instance.
138: */
139: public void setFormatString(final String formatString) {
140: if (formatString == null) {
141: format = null;
142: } else {
143: if (formatString.length() == 0) {
144: // this is a workaround for a bug in JDK 1.5
145: setFormat(new DecimalFormat(
146: DECIMALFORMAT_DEFAULT_PATTERN));
147: } else {
148: setFormat(new DecimalFormat(formatString));
149: }
150: }
151: }
152:
153: /**
154: * Creates the number text element based on the defined settings. Undefined properties
155: * will not be set in the generated element.
156: *
157: * @return the generated numberic text element
158: *
159: * @see org.jfree.report.elementfactory.ElementFactory#createElement()
160: */
161: public Element createElement() {
162: final DataSource ds;
163: if (format instanceof DecimalFormat) {
164: final NumberFieldTemplate template = new NumberFieldTemplate();
165: template.setDecimalFormat((DecimalFormat) format);
166: if (getFormula() != null) {
167: template.setFormula(getFormula());
168: } else {
169: template.setField(getFieldname());
170: }
171: if (getNullString() != null) {
172: template.setNullValue(getNullString());
173: }
174: ds = template;
175: } else {
176: final NumberFormatFilter dataSource = new NumberFormatFilter();
177: if (format != null) {
178: dataSource.setFormatter(format);
179: }
180: final DataRowDataSource dds = new DataRowDataSource();
181: if (getFormula() != null) {
182: dds.setFormula(getFormula());
183: } else {
184: dds.setDataSourceColumnName(getFieldname());
185: }
186:
187: dataSource.setDataSource(dds);
188: if (getNullString() != null) {
189: dataSource.setNullValue(getNullString());
190: }
191: ds = dataSource;
192: }
193:
194: final TextElement element = new TextElement();
195: applyElementName(element);
196: element.setDataSource(ds);
197:
198: applyStyle(element.getStyle());
199: element.getStyle().setStyleProperty(
200: ElementStyleKeys.EXCEL_DATA_FORMAT_STRING,
201: getExcelCellFormat());
202: return element;
203: }
204:
205: /**
206: * Creates a new TextElement containing a numeric filter structure.
207: *
208: * @param name the name of the new element
209: * @param bounds the bounds of the new element
210: * @param paint the text color of this text element
211: * @param alignment the horizontal text alignment.
212: * @param font the font for this element
213: * @param nullString the text used when the value of this element is null
214: * @param field the field in the datamodel to retrieve values from
215: * @param format the NumberFormat used in this number element
216: * @return a report element for displaying <code>Number</code> objects.
217: *
218: * @throws NullPointerException if bounds, name or function are null
219: * @throws IllegalArgumentException if the given alignment is invalid
220: */
221: public static TextElement createNumberElement(final String name,
222: final Rectangle2D bounds, final Color paint,
223: final ElementAlignment alignment,
224: final FontDefinition font, final String nullString,
225: final NumberFormat format, final String field) {
226: return createNumberElement(name, bounds, paint, alignment,
227: ElementAlignment.TOP, font, nullString, format, field);
228: }
229:
230: /**
231: * Creates a new TextElement containing a numeric filter structure.
232: *
233: * @param name the name of the new element.
234: * @param bounds the bounds of the new element.
235: * @param color the text color of this text element.
236: * @param alignment the horizontal text alignment.
237: * @param valign the vertical alignment.
238: * @param font the font for this element.
239: * @param nullString the text used when the value of this element is null.
240: * @param field the field in the datamodel to retrieve values from.
241: * @param format the NumberFormat used in this number element.
242: * @return a report element for displaying <code>Number</code> objects.
243: *
244: * @throws NullPointerException if bounds, name or function are null
245: * @throws IllegalArgumentException if the given alignment is invalid
246: */
247: public static TextElement createNumberElement(final String name,
248: final Rectangle2D bounds, final Color color,
249: final ElementAlignment alignment,
250: final ElementAlignment valign, final FontDefinition font,
251: final String nullString, final NumberFormat format,
252: final String field) {
253:
254: final NumberFieldElementFactory factory = new NumberFieldElementFactory();
255: factory.setX(new Float(bounds.getX()));
256: factory.setY(new Float(bounds.getY()));
257: factory.setMinimumWidth(new Float(bounds.getWidth()));
258: factory.setMinimumHeight(new Float(bounds.getHeight()));
259: factory.setName(name);
260: factory.setColor(color);
261: factory.setHorizontalAlignment(alignment);
262: factory.setVerticalAlignment(valign);
263:
264: if (font != null) {
265: factory.setFontName(font.getFontName());
266: factory.setFontSize(new Integer(font.getFontSize()));
267: factory.setBold(ElementFactory.getBooleanValue(font
268: .isBold()));
269: factory.setItalic(ElementFactory.getBooleanValue(font
270: .isItalic()));
271: factory.setEncoding(font.getFontEncoding(null));
272: factory.setUnderline(ElementFactory.getBooleanValue(font
273: .isUnderline()));
274: factory.setStrikethrough(ElementFactory
275: .getBooleanValue(font.isStrikeThrough()));
276: factory.setEmbedFont(ElementFactory.getBooleanValue(font
277: .isEmbeddedFont()));
278: }
279: factory.setNullString(nullString);
280: factory.setFormat(format);
281: factory.setFieldname(field);
282: return (TextElement) factory.createElement();
283: }
284:
285: /**
286: * Creates a new TextElement containing a numeric filter structure.
287: *
288: * @param name the name of the new element
289: * @param bounds the bounds of the new element
290: * @param paint the text color of this text element
291: * @param alignment the horizontal text alignment.
292: * @param font the font for this element
293: * @param nullString the text used when the value of this element is null
294: * @param field the fieldname in the datamodel to retrieve values from
295: * @param format the DecimalFormatString used in this text field
296: * @return a report element for displaying <code>Number</code> objects.
297: *
298: * @throws NullPointerException if bounds, name or function are null
299: * @throws IllegalArgumentException if the given alignment is invalid
300: */
301: public static TextElement createNumberElement(final String name,
302: final Rectangle2D bounds, final Color paint,
303: final ElementAlignment alignment,
304: final FontDefinition font, final String nullString,
305: final String format, final String field) {
306: return createNumberElement(name, bounds, paint, alignment,
307: null, font, nullString, format, field);
308: }
309:
310: /**
311: * Creates a new TextElement containing a numeric filter structure.
312: *
313: * @param name the name of the new element.
314: * @param bounds the bounds of the new element.
315: * @param color the text color of the element.
316: * @param alignment the horizontal text alignment.
317: * @param valign the vertical alignment.
318: * @param font the font for this element.
319: * @param nullString t he text used when the value of this element is null.
320: * @param field the fieldname in the datamodel to retrieve values from.
321: * @param format the DecimalFormatString used in this text field.
322: * @return a report element for displaying <code>Number</code> objects.
323: *
324: * @throws NullPointerException if bounds, name or function are null
325: * @throws IllegalArgumentException if the given alignment is invalid
326: */
327: public static TextElement createNumberElement(final String name,
328: final Rectangle2D bounds, final Color color,
329: final ElementAlignment alignment,
330: final ElementAlignment valign, final FontDefinition font,
331: final String nullString, final String format,
332: final String field) {
333:
334: final NumberFieldElementFactory factory = new NumberFieldElementFactory();
335: factory.setX(new Float(bounds.getX()));
336: factory.setY(new Float(bounds.getY()));
337: factory.setMinimumWidth(new Float(bounds.getWidth()));
338: factory.setMinimumHeight(new Float(bounds.getHeight()));
339: factory.setName(name);
340: factory.setColor(color);
341: factory.setHorizontalAlignment(alignment);
342: factory.setVerticalAlignment(valign);
343:
344: if (font != null) {
345: factory.setFontName(font.getFontName());
346: factory.setFontSize(new Integer(font.getFontSize()));
347: factory.setBold(ElementFactory.getBooleanValue(font
348: .isBold()));
349: factory.setItalic(ElementFactory.getBooleanValue(font
350: .isItalic()));
351: factory.setEncoding(font.getFontEncoding(null));
352: factory.setUnderline(ElementFactory.getBooleanValue(font
353: .isUnderline()));
354: factory.setStrikethrough(ElementFactory
355: .getBooleanValue(font.isStrikeThrough()));
356: factory.setEmbedFont(ElementFactory.getBooleanValue(font
357: .isEmbeddedFont()));
358: }
359: factory.setNullString(nullString);
360: factory.setFormatString(format);
361: factory.setFieldname(field);
362: return (TextElement) factory.createElement();
363: }
364:
365: }
|