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