001: /*
002: * $Id: org.eclipse.jdt.ui.prefs 5004 2006-03-17 20:47:08 -0800 (Fri, 17 Mar
003: * 2006) eelco12 $ $Revision: 5004 $ $Date: 2006-03-17 20:47:08 -0800 (Fri, 17
004: * Mar 2006) $
005: *
006: * ==============================================================================
007: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
008: * use this file except in compliance with the License. You may obtain a copy of
009: * the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
015: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
016: * License for the specific language governing permissions and limitations under
017: * the License.
018: */
019: package wicket.extensions.wizard;
020:
021: import java.util.Iterator;
022:
023: import wicket.Component;
024: import wicket.behavior.HeaderContributor;
025: import wicket.feedback.ContainerFeedbackMessageFilter;
026: import wicket.markup.html.WebMarkupContainer;
027: import wicket.markup.html.form.Form;
028: import wicket.markup.html.panel.FeedbackPanel;
029: import wicket.markup.html.panel.Panel;
030:
031: /**
032: * A wizard is a dialog component that takes it's users through a number of
033: * predefined steps. It has common functionality like a next, previous, finish
034: * and cancel button, and it uses a {@link IWizardModel} to navigate through the
035: * steps.
036: *
037: * <p>
038: * This default implementation should be useful for basic cases, if the layout
039: * is exactly what you need. If you want to provide your own layout and/ or have
040: * more or less components (e.g. you want to additionally provide an overview
041: * component), you can override this class and add the components you want
042: * yourself.
043: * </p>
044: * <p>
045: * If that's still not enough flexiblity for you, but you want to use the
046: * {@link IWizardModel wizard model} and {@link IWizardStep wizard step}
047: * functionality provided in this package, you can provde a custom wizard
048: * </p>
049: *
050: * @author Eelco Hillenius
051: */
052: public class Wizard extends Panel implements IWizardModelListener,
053: IWizard {
054: /** Component id of the buttons panel as used by the default wizard panel. */
055: public static final String BUTTONS_ID = "buttons";
056:
057: /** Component id of the feedback panel as used by the default wizard panel. */
058: public static final String FEEDBACK_ID = "feedback";
059:
060: /** Component id of the header panel as used by the default wizard panel. */
061: public static final String HEADER_ID = "header";
062:
063: /** Component id of the overview panel as used by the default wizard panel. */
064: public static final String OVERVIEW_ID = "overview";
065:
066: /**
067: * Component id of the view panel (where the main wizard contents go) as
068: * used by the default wizard panel.
069: */
070: public static final String VIEW_ID = "view";
071:
072: private static final long serialVersionUID = 1L;
073:
074: /** The currently active step. */
075: private IWizardStep activeStep;
076:
077: /**
078: * The form in which the view is nested, and on which the wizard buttons
079: * work.
080: */
081: private Form form;
082:
083: /** The wizard model. */
084: private IWizardModel wizardModel;
085:
086: /**
087: * Construct. Adds the default style.
088: * <p>
089: * If you override this class, it makes sense to call this constructor
090: * (super(id)), then - in your constructor - construct a transition model
091: * and then call {@link #init(IWizardModel)} to initialize the wizard.
092: * </p>
093: * <p>
094: * This constructor is not meant for normal clients of this class
095: * </p>
096: *
097: * @param id
098: * The component model
099: */
100: public Wizard(String id) {
101: this (id, true);
102: }
103:
104: /**
105: * Construct.
106: * <p>
107: * If you override this class, it makes sense to call this constructor
108: * (super(id)), then - in your constructor - construct a transition model
109: * and then call {@link #init(IWizardModel)} to initialize the wizard.
110: * </p>
111: * <p>
112: * This constructor is not meant for normal clients of this class
113: * </p>
114: *
115: * @param id
116: * The component model
117: * @param addDefaultCssStyle
118: * Whether to add the {@link #addDefaultCssStyle() default style}
119: */
120: public Wizard(String id, boolean addDefaultCssStyle) {
121: super (id);
122:
123: if (addDefaultCssStyle) {
124: addDefaultCssStyle();
125: }
126: }
127:
128: /**
129: * Construct with a transition model. Adds the default style.
130: * <p>
131: * For most clients, this is typically the right constructor to use.
132: * </p>
133: *
134: * @param id
135: * The component id
136: * @param wizardModel
137: * The transitions model
138: */
139: public Wizard(String id, IWizardModel wizardModel) {
140: this (id, wizardModel, true);
141: }
142:
143: /**
144: * Construct with a transition model.
145: * <p>
146: * For most clients, this is typically the right constructor to use.
147: * </p>
148: *
149: * @param id
150: * The component id
151: * @param wizardModel
152: * The transitions model
153: * @param addDefaultCssStyle
154: * Whether to add the {@link #addDefaultCssStyle() default style}
155: */
156: public Wizard(String id, IWizardModel wizardModel,
157: boolean addDefaultCssStyle) {
158: super (id);
159:
160: init(wizardModel);
161:
162: if (addDefaultCssStyle) {
163: addDefaultCssStyle();
164: }
165: }
166:
167: /**
168: * Will let the wizard contribute a CSS include to the page's header. It
169: * will add Wizard.css from this package. This method is typically called by
170: * the class that creates the wizard.
171: */
172: public final void addDefaultCssStyle() {
173: add(HeaderContributor.forCss(Wizard.class, "Wizard.css"));
174: }
175:
176: /**
177: * Convenience method to get the active step from the model.
178: *
179: * @return The active step
180: */
181: public final IWizardStep getActiveStep() {
182: return getWizardModel().getActiveStep();
183: }
184:
185: /**
186: * Gets the form in which the view is nested, and on which the wizard
187: * buttons work.
188: *
189: * @return The wizard form
190: */
191: public final Form getForm() {
192: return form;
193: }
194:
195: /**
196: * @see wicket.extensions.wizard.IWizard#getWizardModel()
197: */
198: public final IWizardModel getWizardModel() {
199: return wizardModel;
200: }
201:
202: /**
203: * Turn versioning off for wizards. This works best when the wizard is
204: * <strong>not</strong> accessed from bookmarkable pages, so that the url
205: * doesn't change at all.
206: *
207: * @return False
208: * @see wicket.Component#isVersioned()
209: */
210: public boolean isVersioned() {
211: return false;
212: }
213:
214: /**
215: * @see wicket.extensions.wizard.IWizardModelListener#onActiveStepChanged(wicket.extensions.wizard.IWizardStep)
216: */
217: public void onActiveStepChanged(IWizardStep newStep) {
218: this .activeStep = newStep;
219: form.replace(activeStep.getView(VIEW_ID, this , this ));
220: form.replace(activeStep.getHeader(HEADER_ID, this , this ));
221: }
222:
223: /**
224: * Called when the wizard is cancelled.
225: */
226: public void onCancel() {
227: };
228:
229: /**
230: * Called when the wizard is finished.
231: */
232: public void onFinish() {
233: }
234:
235: /**
236: * Initialize this wizard with a transition model.
237: * <p>
238: * If you constructed this wizard using a constructor without the
239: * transitions model argument, <strong>you must</strong> call this method
240: * prior to actually using it.
241: * </p>
242: *
243: * @param wizardModel
244: */
245: protected void init(IWizardModel wizardModel) {
246: if (wizardModel == null) {
247: throw new IllegalArgumentException(
248: "argument wizardModel must be not null");
249: }
250:
251: this .wizardModel = wizardModel;
252:
253: form = new Form("form");
254: add(form);
255: // dummy view to be replaced
256: form.add(new WebMarkupContainer(HEADER_ID));
257: form.add(newFeedbackPanel(FEEDBACK_ID));
258: // add dummy view; will be replaced on initialization
259: form.add(new WebMarkupContainer(VIEW_ID));
260: form.add(newButtonBar(BUTTONS_ID));
261: form.add(newOverviewBar(OVERVIEW_ID));
262:
263: wizardModel.addListener(this );
264:
265: for (Iterator iter = wizardModel.stepIterator(); iter.hasNext();) {
266: ((IWizardStep) iter.next()).init(wizardModel);
267: }
268:
269: // reset model to prepare for action
270: wizardModel.reset();
271: }
272:
273: /**
274: * Create a new button bar. Clients can override this method to provide a
275: * custom button bar.
276: *
277: * @param id
278: * The id to be used to construct the component
279: *
280: * @return A new button bar
281: */
282: protected Component newButtonBar(String id) {
283: return new WizardButtonBar(id, this );
284: }
285:
286: /**
287: * Create a new feedback panel. Clients can override this method to provide
288: * a custom feedback panel.
289: *
290: * @param id
291: * The id to be used to construct the component
292: *
293: * @return A new feedback panel
294: */
295: protected FeedbackPanel newFeedbackPanel(String id) {
296: return new FeedbackPanel(id,
297: new ContainerFeedbackMessageFilter(this ));
298: }
299:
300: /**
301: * Create a new overview bar. Clients can override this method to provide a
302: * custom bar.
303: *
304: * @param id
305: * The id to be used to construct the component
306: *
307: * @return A new ovewview bar
308: */
309: protected Component newOverviewBar(String id) {
310: // return a dummy component by default as we don't have an overview
311: // component
312: return new WebMarkupContainer(id).setVisible(false);
313: }
314: }
|