001: /**
002: * Wizard Framework
003: * Copyright 2004 - 2005 Andrew Pietsch
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * $Id: AbstractWizardModel.java,v 1.15 2007/09/22 01:34:11 pietschy Exp $
020: */package org.pietschy.wizard;
021:
022: import java.beans.PropertyChangeSupport;
023: import java.beans.PropertyChangeListener;
024: import java.beans.PropertyChangeEvent;
025:
026: /**
027: * This class provides a base for implementors of {@link WizardModel}. It provides the basic
028: * {@link PropertyChangeListener} management and fires the appropriate events when the various
029: * properties are changed.
030: * <p>
031: * Subclasses will generally override {@link #refreshModelState} to update the state of the various
032: * model properties.
033: */
034: public abstract class AbstractWizardModel implements WizardModel {
035: private WizardStep activeStep;
036: private boolean previousAvailable;
037: private boolean nextAvailable;
038: private boolean lastAvailable;
039: private boolean cancelAvailable;
040: private boolean lastVisible = true;
041: private PropertyChangeSupport pcs;
042:
043: private PropertyChangeListener completeListener = new PropertyChangeListener() {
044: public void propertyChange(PropertyChangeEvent evt) {
045: if (evt.getPropertyName().equals("complete")) {
046: // only respond to the complete step when there is an
047: // active step. This catches the case where setComplete is called
048: // while during init before the model has been started.
049: if (getActiveStep() != null) {
050: refreshModelState();
051: }
052: }
053: }
054: };
055:
056: public AbstractWizardModel() {
057: pcs = new PropertyChangeSupport(this );
058: }
059:
060: /**
061: * Gets the current active step the wizard should display.
062: *
063: * @return the active step.
064: */
065: public WizardStep getActiveStep() {
066: return activeStep;
067: }
068:
069: /**
070: * Provided for subclasses to change the current step in response to a call to {@link #nextStep}
071: * or its related methods.
072: *
073: * @param activeStep the new step.
074: */
075: protected void setActiveStep(WizardStep activeStep) {
076: if (this .activeStep != activeStep) {
077: WizardStep old = this .activeStep;
078: this .activeStep = activeStep;
079: pcs.firePropertyChange("activeStep", old, activeStep);
080: refreshModelState();
081: }
082: }
083:
084: /**
085: * Checks if the previous button should be enabled.
086: *
087: * @return <tt>true</tt> if the previou button should be enabled, <tt>false</tt> otherwise.
088: */
089: public boolean isPreviousAvailable() {
090: return previousAvailable;
091: }
092:
093: /**
094: * Checks if the next button should be enabled.
095: *
096: * @return <tt>true</tt> if the next button should be enabled, <tt>false</tt> otherwise.
097: */
098: public boolean isNextAvailable() {
099: return nextAvailable;
100: }
101:
102: /**
103: * Checks if the last button should be enabled.
104: *
105: * @return <tt>true</tt> if the last button should be enabled, <tt>false</tt> otherwise.
106: * @see #isLastVisible
107: */
108: public boolean isLastAvailable() {
109: return lastAvailable;
110: }
111:
112: /**
113: * Configures if the previous button should be enabled.
114: *
115: * @param previousAvailable <tt>true</tt> to enable the previous button, <tt>false</tt> otherwise.
116: */
117: protected void setPreviousAvailable(boolean previousAvailable) {
118: if (this .previousAvailable != previousAvailable) {
119: boolean old = this .previousAvailable;
120: this .previousAvailable = previousAvailable;
121: pcs.firePropertyChange("previousAvailable", old,
122: previousAvailable);
123: }
124: }
125:
126: /**
127: * Configures if the next button should be enabled.
128: *
129: * @param nextAvailable <tt>true</tt> to enable the next button, <tt>false</tt> otherwise.
130: */
131: protected void setNextAvailable(boolean nextAvailable) {
132: if (this .nextAvailable != nextAvailable) {
133: boolean old = this .nextAvailable;
134: this .nextAvailable = nextAvailable;
135: pcs.firePropertyChange("nextAvailable", old, nextAvailable);
136: }
137: }
138:
139: /**
140: * Configures if the last button should be enabled.
141: *
142: * @param lastAvailable <tt>true</tt> to enable the last button, <tt>false</tt> otherwise.
143: */
144: protected void setLastAvailable(boolean lastAvailable) {
145: if (this .lastAvailable != lastAvailable) {
146: boolean old = this .lastAvailable;
147: this .lastAvailable = lastAvailable;
148: pcs.firePropertyChange("lastAvailable", old, lastAvailable);
149: }
150: }
151:
152: /**
153: * Configures if the cncel button should be enabled.
154: *
155: * @param cancelAvailable <tt>true</tt> to enable the cancel button, <tt>false</tt> otherwise.
156: */
157: protected void setCancelAvailable(boolean cancelAvailable) {
158: if (this .cancelAvailable != cancelAvailable) {
159: boolean old = this .cancelAvailable;
160: this .cancelAvailable = cancelAvailable;
161: pcs.firePropertyChange("cancelAvailable", old,
162: cancelAvailable);
163: }
164: }
165:
166: public boolean isCancelAvailable() {
167: return cancelAvailable;
168: }
169:
170: /**
171: * Checks if the last button should be displayed. This method should only return true if
172: * the {@link #isLastAvailable} will return true at any point. Returning false will prevent
173: * the last button from appearing on the wizard at all.
174: *
175: * @return <tt>true</tt> if the previou last should be displayed, <tt>false</tt> otherwise.
176: */
177: public boolean isLastVisible() {
178: return lastVisible;
179: }
180:
181: /**
182: * Configures if the last button should be displayed.
183: *
184: * @param lastVisible <tt>true</tt> to display the last button, <tt>false</tt> otherwise.
185: * @see #isLastVisible
186: */
187: public void setLastVisible(boolean lastVisible) {
188: if (this .lastVisible != lastVisible) {
189: boolean old = this .lastVisible;
190: this .lastVisible = lastVisible;
191: pcs.firePropertyChange("lastVisible", old, lastVisible);
192: }
193: }
194:
195: /**
196: * This is an empty method that is intended for subclasses to override to update their
197: * various properties based on the active step.
198: */
199: public void refreshModelState() {
200: }
201:
202: /**
203: * Adds a {@link PropertyChangeListener} to this model.
204: *
205: * @param listener the listener to add.
206: */
207: public void addPropertyChangeListener(
208: PropertyChangeListener listener) {
209: pcs.addPropertyChangeListener(listener);
210: }
211:
212: /**
213: * Removes a {@link PropertyChangeListener} from this model.
214: *
215: * @param listener the listener to remove.
216: */
217: public void removePropertyChangeListener(
218: PropertyChangeListener listener) {
219: pcs.removePropertyChangeListener(listener);
220: }
221:
222: /**
223: * Adds a {@link PropertyChangeListener} to this model.
224: *
225: * @param propertyName the property to listen to.
226: * @param listener the listener to add.
227: */
228: public void addPropertyChangeListener(String propertyName,
229: PropertyChangeListener listener) {
230: pcs.addPropertyChangeListener(propertyName, listener);
231: }
232:
233: /**
234: * Removes a {@link PropertyChangeListener} from this model.
235: *
236: * @param propertyName the property to stop listening to.
237: * @param listener the listener to remove.
238: */
239: public void removePropertyChangeListener(String propertyName,
240: PropertyChangeListener listener) {
241: pcs.removePropertyChangeListener(propertyName, listener);
242: }
243:
244: /**
245: * Adds a listener to the "complete" property of the {@link WizardStep}. Any changes to this
246: * property will in automatically invoke {@link #refreshModelState()}.
247: *
248: * @param step the {@link WizardStep} to monitor.
249: */
250: protected void addCompleteListener(WizardStep step) {
251: step.addPropertyChangeListener(completeListener);
252: }
253: }
|