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: * RowBandingFunction.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.function;
030:
031: import java.awt.Color;
032:
033: import org.jfree.report.Element;
034: import org.jfree.report.ItemBand;
035: import org.jfree.report.event.PageEventListener;
036: import org.jfree.report.event.ReportEvent;
037: import org.jfree.report.style.ElementStyleKeys;
038: import org.jfree.util.Log;
039:
040: /**
041: * A function that alternates the background-color for each item-band within a group. If the function evaluates to true,
042: * then the background of the named element will be set to the visible-color, else it will be set to the
043: * invisible-color.
044: * <p/>
045: * The ElementVisibilitySwitchFunction defines two parameters: <ul> <li>element <p>The name of the element in the
046: * itemband that should be modified. The element(s) must be named using the "name" attribute, if no name is given here,
047: * the ItemBand's background color is defined instead.</p> <li>initial-state <p>The initial state of the function. (true
048: * or false) defaults to false. This is the reverse of the element's visiblity (set to false to start with an visible
049: * element, set to true to hide the element in the first itemrow).</p> </ul>
050: *
051: * @author Thomas Morgner
052: * @author Michael D'Amour
053: */
054: public class RowBandingFunction extends AbstractFunction implements
055: PageEventListener {
056: /**
057: * The computed visibility value.
058: */
059: private transient boolean trigger;
060: /**
061: * An internal counter that counts the number of rows processed since the last visibility switch.
062: */
063: private transient int count;
064: /**
065: * A internal flag indicating whether a warning has been printed.
066: */
067: private transient boolean warned;
068: /**
069: * If not null, this boolean flag defines the function state that should be used after page breaks. If not
070: * defined, the initial state is used instead.
071: */
072: private Boolean newPageState;
073: /**
074: * A field defining the number of rows that must be processed before the visibility can switch again.
075: */
076: private int numberOfElements;
077: /**
078: * The name of the element that should be formatted.
079: */
080: private String element;
081: /**
082: * The initial visibility that is used on the start of a new report, a new group or a new page.
083: */
084: private boolean initialState;
085:
086: /**
087: * A flag indicating whether the visiblity should be reset to its initial state when a group starts.
088: */
089: private boolean resetOnGroupStart;
090: /**
091: * A flag indicating whether the visiblity should be reset to its initial state when a page starts.
092: */
093: private boolean resetOnPageStart;
094:
095: /**
096: * The background color that is used if the row-banding background should be visible.
097: */
098: private Color visibleBackground;
099: /**
100: * The background color that is used if the row-banding background should be invisible.
101: */
102: private Color invisibleBackground;
103:
104: /**
105: * Default constructor.
106: */
107: public RowBandingFunction() {
108: warned = false;
109: numberOfElements = 1;
110: resetOnGroupStart = true;
111: resetOnPageStart = true;
112: }
113:
114: /**
115: * Receives notification that a page has started.
116: *
117: * @param event the event.
118: */
119: public void pageStarted(final ReportEvent event) {
120: if (resetOnPageStart) {
121: //pagebreak = false;
122: if (newPageState == null) {
123: trigger = getInitialState();
124: } else {
125: trigger = newPageState.booleanValue();
126: }
127: count = 0;
128: triggerVisibleState(event);
129: }
130: }
131:
132: /**
133: * Receives notification that a page is completed.
134: *
135: * @param event The event.
136: */
137: public void pageFinished(final ReportEvent event) {
138: }
139:
140: /**
141: * Receives notification that report generation initializes the current run. <P> The event carries a
142: * ReportState.Started state. Use this to initialize the report.
143: *
144: * @param event The event.
145: */
146: public void reportInitialized(final ReportEvent event) {
147: //pagebreak = false;
148: trigger = !getInitialState();
149: count = 0;
150: }
151:
152: /**
153: * Receives notification that the items are being processed. Sets the function value to false. <P> Following this
154: * event, there will be a sequence of itemsAdvanced events until the itemsFinished event is raised.
155: *
156: * @param event Information about the event.
157: */
158: public void itemsStarted(final ReportEvent event) {
159: if (resetOnGroupStart) {
160: // pagebreak = false;
161: trigger = !getInitialState();
162: count = 0;
163: }
164: }
165:
166: /**
167: * Triggers the visibility of an element. If the named element was visible at the last itemsAdvanced call, it gets now
168: * invisible and vice versa. This creates the effect, that an element is printed every other line.
169: *
170: * @param event the report event.
171: */
172: public void itemsAdvanced(final ReportEvent event) {
173: triggerVisibleState(event);
174: }
175:
176: /**
177: * Triggers the visible state of the specified itemband element. If the named element was visible at the last call, it
178: * gets now invisible and vice versa. This creates the effect, that an element is printed every other line.
179: *
180: * @param event the current report event.
181: */
182: private void triggerVisibleState(final ReportEvent event) {
183: if ((count % numberOfElements) == 0) {
184: trigger = (!trigger);
185: }
186: count += 1;
187:
188: final ItemBand itemBand = event.getReport().getItemBand();
189: if (element == null) {
190: if (trigger) {
191: itemBand.getStyle().setStyleProperty(
192: ElementStyleKeys.BACKGROUND_COLOR,
193: visibleBackground);
194: } else {
195: itemBand.getStyle().setStyleProperty(
196: ElementStyleKeys.BACKGROUND_COLOR,
197: invisibleBackground);
198: }
199: } else {
200: final Element[] e = FunctionUtilities.findAllElements(
201: itemBand, getElement());
202: if (e.length > 0) {
203: for (int i = 0; i < e.length; i++) {
204: if (trigger) {
205: e[i].getStyle().setStyleProperty(
206: ElementStyleKeys.BACKGROUND_COLOR,
207: visibleBackground);
208: } else {
209: e[i].getStyle().setStyleProperty(
210: ElementStyleKeys.BACKGROUND_COLOR,
211: invisibleBackground);
212: }
213: }
214: } else {
215: if (warned == false) {
216: Log
217: .warn("The Band does not contain an element named "
218: + getElement());
219: //Log.warn(new Log.SimpleMessage(Messages.getString("ElementVisibilitySwitchFunction.0"), getElement(), Messages.getString("ElementVisibilitySwitchFunction.1"))); //$NON-NLS-1$ //$NON-NLS-2$
220: warned = true;
221: }
222: }
223: }
224: }
225:
226: /**
227: * Returns the background color that is used if the row-banding background should be invisible.
228: *
229: * @return a color.
230: */
231: public Color getInvisibleBackground() {
232: return invisibleBackground;
233: }
234:
235: /**
236: * Defines the background color that is used if the row-banding background should be invisible.
237: *
238: * @param invisibleBackground a color.
239: */
240: public void setInvisibleBackground(final Color invisibleBackground) {
241: this .invisibleBackground = invisibleBackground;
242: }
243:
244: /**
245: * Returns the background color that is used if the row-banding background should be visible.
246: *
247: * @return a color.
248: */
249: public Color getVisibleBackground() {
250: return visibleBackground;
251: }
252:
253: /**
254: * Defines the background color that is used if the row-banding background should be visible.
255: *
256: * @param visibleBackground a color.
257: */
258: public void setVisibleBackground(final Color visibleBackground) {
259: this .visibleBackground = visibleBackground;
260: }
261:
262: /**
263: * Returns the number of rows that must be processed before the visibility can switch again.
264: *
265: * @return a row count.
266: */
267: public int getNumberOfElements() {
268: return numberOfElements;
269: }
270:
271: /**
272: * Defines the number of rows that must be processed before the visibility can switch again.
273: *
274: * @param numberOfElements a row count.
275: */
276: public void setNumberOfElements(final int numberOfElements) {
277: this .numberOfElements = numberOfElements;
278: }
279:
280: /**
281: * Gets the initial value for the visible trigger, either "true" or "false".
282: *
283: * @return the initial value for the trigger.
284: * @deprecated use getInitialState instead.
285: */
286: public boolean getInitialTriggerValue() {
287: return initialState;
288: }
289:
290: /**
291: * Returns the initial visibility that is used on the start of a new report, a new group or a new page.
292: *
293: * @return the initial value for the trigger.
294: */
295: public boolean getInitialState() {
296: return initialState;
297: }
298:
299: /**
300: * Defines the initial visibility that is used on the start of a new report, a new group or a new page.
301: *
302: * @param initialState the initial value for the trigger.
303: */
304: public void setInitialState(final boolean initialState) {
305: this .initialState = initialState;
306: }
307:
308: /**
309: * Sets the element name. The name denotes an element or band within the root-band or the root-band itself. It is
310: * possible to define multiple elements with the same name to apply the modification to all of these elements.
311: *
312: * @param name The element name.
313: * @see org.jfree.report.function.FunctionUtilities#findAllElements(org.jfree.report.Band,String)
314: */
315: public void setElement(final String name) {
316: this .element = name;
317: }
318:
319: /**
320: * Returns the element name.
321: *
322: * @return The element name.
323: * @see #setElement(String)
324: */
325: public String getElement() {
326: return element;
327: }
328:
329: /**
330: * Returns the visibility state that should be used on new pages. This is only used if resetOnPageStart is set
331: * to true. If this value is not defined, the initialState is used.
332: *
333: * @return the state on new pages.
334: */
335: public Boolean getNewPageState() {
336: return newPageState;
337: }
338:
339: /**
340: * Defines the visibility state that should be used on new pages. This is only used if resetOnPageStart is set
341: * to true. If this value is not defined, the initialState is used.
342: *
343: * @param newPageState the state on new pages or null to use the initialState.
344: */
345: public void setNewPageState(final Boolean newPageState) {
346: this .newPageState = newPageState;
347: }
348:
349: /**
350: * Returns the defined visibility of the element. Returns either true or false as java.lang.Boolean.
351: *
352: * @return the visibility of the element, either Boolean.TRUE or Boolean.FALSE.
353: */
354: public Object getValue() {
355: if (trigger) {
356: return Boolean.TRUE;
357: } else {
358: return Boolean.FALSE;
359: }
360: }
361: }
|