KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > wizard > WizardDialog


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Chris Gross (schtoo@schtoo.com) - patch for bug 16179
11  *******************************************************************************/

12 package org.eclipse.jface.wizard;
13
14 import java.lang.reflect.InvocationTargetException JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Map JavaDoc;
18
19 import org.eclipse.core.runtime.Assert;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.ListenerList;
23 import org.eclipse.jface.dialogs.ControlEnableState;
24 import org.eclipse.jface.dialogs.IDialogConstants;
25 import org.eclipse.jface.dialogs.IMessageProvider;
26 import org.eclipse.jface.dialogs.IPageChangeProvider;
27 import org.eclipse.jface.dialogs.IPageChangedListener;
28 import org.eclipse.jface.dialogs.IPageChangingListener;
29 import org.eclipse.jface.dialogs.MessageDialog;
30 import org.eclipse.jface.dialogs.PageChangedEvent;
31 import org.eclipse.jface.dialogs.PageChangingEvent;
32 import org.eclipse.jface.dialogs.TitleAreaDialog;
33 import org.eclipse.jface.operation.IRunnableWithProgress;
34 import org.eclipse.jface.operation.ModalContext;
35 import org.eclipse.jface.resource.JFaceResources;
36 import org.eclipse.jface.util.SafeRunnable;
37 import org.eclipse.swt.SWT;
38 import org.eclipse.swt.custom.BusyIndicator;
39 import org.eclipse.swt.events.HelpEvent;
40 import org.eclipse.swt.events.HelpListener;
41 import org.eclipse.swt.events.SelectionAdapter;
42 import org.eclipse.swt.events.SelectionEvent;
43 import org.eclipse.swt.graphics.Cursor;
44 import org.eclipse.swt.graphics.Point;
45 import org.eclipse.swt.graphics.Rectangle;
46 import org.eclipse.swt.layout.GridData;
47 import org.eclipse.swt.layout.GridLayout;
48 import org.eclipse.swt.widgets.Button;
49 import org.eclipse.swt.widgets.Composite;
50 import org.eclipse.swt.widgets.Control;
51 import org.eclipse.swt.widgets.Display;
52 import org.eclipse.swt.widgets.Label;
53 import org.eclipse.swt.widgets.Layout;
54 import org.eclipse.swt.widgets.Shell;
55
56 /**
57  * A dialog to show a wizard to the end user.
58  * <p>
59  * In typical usage, the client instantiates this class with a particular
60  * wizard. The dialog serves as the wizard container and orchestrates the
61  * presentation of its pages.
62  * <p>
63  * The standard layout is roughly as follows: it has an area at the top
64  * containing both the wizard's title, description, and image; the actual wizard
65  * page appears in the middle; below that is a progress indicator (which is made
66  * visible if needed); and at the bottom of the page is message line and a
67  * button bar containing Help, Next, Back, Finish, and Cancel buttons (or some
68  * subset).
69  * </p>
70  * <p>
71  * Clients may subclass <code>WizardDialog</code>, although this is rarely
72  * required.
73  * </p>
74  */

75 public class WizardDialog extends TitleAreaDialog implements IWizardContainer2,
76         IPageChangeProvider {
77     /**
78      * Image registry key for error message image (value
79      * <code>"dialog_title_error_image"</code>).
80      */

81     public static final String JavaDoc WIZ_IMG_ERROR = "dialog_title_error_image"; //$NON-NLS-1$
82

83     // The wizard the dialog is currently showing.
84
private IWizard wizard;
85
86     // Wizards to dispose
87
private ArrayList JavaDoc createdWizards = new ArrayList JavaDoc();
88
89     // Current nested wizards
90
private ArrayList JavaDoc nestedWizards = new ArrayList JavaDoc();
91
92     // The currently displayed page.
93
private IWizardPage currentPage = null;
94
95     // The number of long running operation executed from the dialog.
96
private long activeRunningOperations = 0;
97
98     // The current page message and description
99
private String JavaDoc pageMessage;
100
101     private int pageMessageType = IMessageProvider.NONE;
102
103     private String JavaDoc pageDescription;
104
105     // The progress monitor
106
private ProgressMonitorPart progressMonitorPart;
107
108     private Cursor waitCursor;
109
110     private Cursor arrowCursor;
111
112     private MessageDialog windowClosingDialog;
113
114     // Navigation buttons
115
private Button backButton;
116
117     private Button nextButton;
118
119     private Button finishButton;
120
121     private Button cancelButton;
122
123     private Button helpButton;
124
125     private SelectionAdapter cancelListener;
126
127     private boolean isMovingToPreviousPage = false;
128
129     private Composite pageContainer;
130
131     private PageContainerFillLayout pageContainerLayout = new PageContainerFillLayout(
132             5, 5, 300, 225);
133
134     private int pageWidth = SWT.DEFAULT;
135
136     private int pageHeight = SWT.DEFAULT;
137
138     private static final String JavaDoc FOCUS_CONTROL = "focusControl"; //$NON-NLS-1$
139

140     private boolean lockedUI = false;
141
142     private ListenerList pageChangedListeners = new ListenerList();
143
144     private ListenerList pageChangingListeners = new ListenerList();
145
146     /**
147      * A layout for a container which includes several pages, like a notebook,
148      * wizard, or preference dialog. The size computed by this layout is the
149      * maximum width and height of all pages currently inserted into the
150      * container.
151      */

152     protected class PageContainerFillLayout extends Layout {
153         /**
154          * The margin width; <code>5</code> pixels by default.
155          */

156         public int marginWidth = 5;
157
158         /**
159          * The margin height; <code>5</code> pixels by default.
160          */

161         public int marginHeight = 5;
162
163         /**
164          * The minimum width; <code>0</code> pixels by default.
165          */

166         public int minimumWidth = 0;
167
168         /**
169          * The minimum height; <code>0</code> pixels by default.
170          */

171         public int minimumHeight = 0;
172
173         /**
174          * Creates new layout object.
175          *
176          * @param mw
177          * the margin width
178          * @param mh
179          * the margin height
180          * @param minW
181          * the minimum width
182          * @param minH
183          * the minimum height
184          */

185         public PageContainerFillLayout(int mw, int mh, int minW, int minH) {
186             marginWidth = mw;
187             marginHeight = mh;
188             minimumWidth = minW;
189             minimumHeight = minH;
190         }
191
192         /*
193          * (non-Javadoc) Method declared on Layout.
194          */

195         public Point computeSize(Composite composite, int wHint, int hHint,
196                 boolean force) {
197             if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) {
198                 return new Point(wHint, hHint);
199             }
200             Point result = null;
201             Control[] children = composite.getChildren();
202             if (children.length > 0) {
203                 result = new Point(0, 0);
204                 for (int i = 0; i < children.length; i++) {
205                     Point cp = children[i].computeSize(wHint, hHint, force);
206                     result.x = Math.max(result.x, cp.x);
207                     result.y = Math.max(result.y, cp.y);
208                 }
209                 result.x = result.x + 2 * marginWidth;
210                 result.y = result.y + 2 * marginHeight;
211             } else {
212                 Rectangle rect = composite.getClientArea();
213                 result = new Point(rect.width, rect.height);
214             }
215             result.x = Math.max(result.x, minimumWidth);
216             result.y = Math.max(result.y, minimumHeight);
217             if (wHint != SWT.DEFAULT) {
218                 result.x = wHint;
219             }
220             if (hHint != SWT.DEFAULT) {
221                 result.y = hHint;
222             }
223             return result;
224         }
225
226         /**
227          * Returns the client area for the given composite according to this
228          * layout.
229          *
230          * @param c
231          * the composite
232          * @return the client area rectangle
233          */

234         public Rectangle getClientArea(Composite c) {
235             Rectangle rect = c.getClientArea();
236             rect.x = rect.x + marginWidth;
237             rect.y = rect.y + marginHeight;
238             rect.width = rect.width - 2 * marginWidth;
239             rect.height = rect.height - 2 * marginHeight;
240             return rect;
241         }
242
243         /*
244          * (non-Javadoc) Method declared on Layout.
245          */

246         public void layout(Composite composite, boolean force) {
247             Rectangle rect = getClientArea(composite);
248             Control[] children = composite.getChildren();
249             for (int i = 0; i < children.length; i++) {
250                 children[i].setBounds(rect);
251             }
252         }
253
254         /**
255          * Lays outs the page according to this layout.
256          *
257          * @param w
258          * the control
259          */

260         public void layoutPage(Control w) {
261             w.setBounds(getClientArea(w.getParent()));
262         }
263
264         /**
265          * Sets the location of the page so that its origin is in the upper left
266          * corner.
267          *
268          * @param w
269          * the control
270          */

271         public void setPageLocation(Control w) {
272             w.setLocation(marginWidth, marginHeight);
273         }
274     }
275
276     /**
277      * Creates a new wizard dialog for the given wizard.
278      *
279      * @param parentShell
280      * the parent shell
281      * @param newWizard
282      * the wizard this dialog is working on
283      */

284     public WizardDialog(Shell parentShell, IWizard newWizard) {
285         super(parentShell);
286         setShellStyle(SWT.CLOSE | SWT.MAX | SWT.TITLE | SWT.BORDER
287                 | SWT.APPLICATION_MODAL | SWT.RESIZE | getDefaultOrientation());
288         setWizard(newWizard);
289         // since VAJava can't initialize an instance var with an anonymous
290
// class outside a constructor we do it here:
291
cancelListener = new SelectionAdapter() {
292             public void widgetSelected(SelectionEvent e) {
293                 cancelPressed();
294             }
295         };
296     }
297
298     /**
299      * About to start a long running operation triggered through the wizard.
300      * Shows the progress monitor and disables the wizard's buttons and
301      * controls.
302      *
303      * @param enableCancelButton
304      * <code>true</code> if the Cancel button should be enabled,
305      * and <code>false</code> if it should be disabled
306      * @return the saved UI state
307      */

308     private Object JavaDoc aboutToStart(boolean enableCancelButton) {
309         Map JavaDoc savedState = null;
310         if (getShell() != null) {
311             // Save focus control
312
Control focusControl = getShell().getDisplay().getFocusControl();
313             if (focusControl != null && focusControl.getShell() != getShell()) {
314                 focusControl = null;
315             }
316             boolean needsProgressMonitor = wizard.needsProgressMonitor();
317             cancelButton.removeSelectionListener(cancelListener);
318             // Set the busy cursor to all shells.
319
Display d = getShell().getDisplay();
320             waitCursor = new Cursor(d, SWT.CURSOR_WAIT);
321             setDisplayCursor(waitCursor);
322             // Set the arrow cursor to the cancel component.
323
arrowCursor = new Cursor(d, SWT.CURSOR_ARROW);
324             cancelButton.setCursor(arrowCursor);
325             // Deactivate shell
326
savedState = saveUIState(needsProgressMonitor && enableCancelButton);
327             if (focusControl != null) {
328                 savedState.put(FOCUS_CONTROL, focusControl);
329             }
330             // Attach the progress monitor part to the cancel button
331
if (needsProgressMonitor) {
332                 progressMonitorPart.attachToCancelComponent(cancelButton);
333                 progressMonitorPart.setVisible(true);
334             }
335         }
336         return savedState;
337     }
338
339     /**
340      * The Back button has been pressed.
341      */

342     protected void backPressed() {
343         IWizardPage page = currentPage.getPreviousPage();
344         if (page == null) {
345             // should never happen since we have already visited the page
346
return;
347         }
348
349         // set flag to indicate that we are moving back
350
isMovingToPreviousPage = true;
351         // show the page
352
showPage(page);
353     }
354
355     /*
356      * (non-Javadoc) Method declared on Dialog.
357      */

358     protected void buttonPressed(int buttonId) {
359         switch (buttonId) {
360         case IDialogConstants.HELP_ID: {
361             helpPressed();
362             break;
363         }
364         case IDialogConstants.BACK_ID: {
365             backPressed();
366             break;
367         }
368         case IDialogConstants.NEXT_ID: {
369             nextPressed();
370             break;
371         }
372         case IDialogConstants.FINISH_ID: {
373             finishPressed();
374             break;
375         }
376             // The Cancel button has a listener which calls cancelPressed
377
// directly
378
}
379     }
380
381     /**
382      * Calculates the difference in size between the given page and the page
383      * container. A larger page results in a positive delta.
384      *
385      * @param page
386      * the page
387      * @return the size difference encoded as a
388      * <code>new Point(deltaWidth,deltaHeight)</code>
389      */

390     private Point calculatePageSizeDelta(IWizardPage page) {
391         Control pageControl = page.getControl();
392         if (pageControl == null) {
393             // control not created yet
394
return new Point(0, 0);
395         }
396         Point contentSize = pageControl.computeSize(SWT.DEFAULT, SWT.DEFAULT,
397                 true);
398         Rectangle rect = pageContainerLayout.getClientArea(pageContainer);
399         Point containerSize = new Point(rect.width, rect.height);
400         return new Point(Math.max(0, contentSize.x - containerSize.x), Math
401                 .max(0, contentSize.y - containerSize.y));
402     }
403
404     /*
405      * (non-Javadoc) Method declared on Dialog.
406      */

407     protected void cancelPressed() {
408         if (activeRunningOperations <= 0) {
409             // Close the dialog. The check whether the dialog can be
410
// closed or not is done in <code>okToClose</code>.
411
// This ensures that the check is also evaluated when the user
412
// presses the window's close button.
413
setReturnCode(CANCEL);
414             close();
415         } else {
416             cancelButton.setEnabled(false);
417         }
418     }
419
420     /*
421      * (non-Javadoc)
422      *
423      * @see org.eclipse.jface.window.Window#close()
424      */

425     public boolean close() {
426         if (okToClose()) {
427             return hardClose();
428         }
429         return false;
430     }
431
432     /*
433      * (non-Javadoc) Method declared on Window.
434      */

435     protected void configureShell(Shell newShell) {
436         super.configureShell(newShell);
437         // Register help listener on the shell
438
newShell.addHelpListener(new HelpListener() {
439             public void helpRequested(HelpEvent event) {
440                 // call perform help on the current page
441
if (currentPage != null) {
442                     currentPage.performHelp();
443                 }
444             }
445         });
446     }
447
448     /**
449      * Creates the buttons for this dialog's button bar.
450      * <p>
451      * The <code>WizardDialog</code> implementation of this framework method
452      * prevents the parent composite's columns from being made equal width in
453      * order to remove the margin between the Back and Next buttons.
454      * </p>
455      *
456      * @param parent
457      * the parent composite to contain the buttons
458      */

459     protected void createButtonsForButtonBar(Composite parent) {
460         ((GridLayout) parent.getLayout()).makeColumnsEqualWidth = false;
461         if (wizard.isHelpAvailable()) {
462             helpButton = createButton(parent, IDialogConstants.HELP_ID,
463                     IDialogConstants.HELP_LABEL, false);
464         }
465         if (wizard.needsPreviousAndNextButtons()) {
466             createPreviousAndNextButtons(parent);
467         }
468         finishButton = createButton(parent, IDialogConstants.FINISH_ID,
469                 IDialogConstants.FINISH_LABEL, true);
470         cancelButton = createCancelButton(parent);
471     }
472
473     /*
474      * (non-Javadoc)
475      *
476      * @see org.eclipse.jface.dialogs.Dialog#setButtonLayoutData(org.eclipse.swt.widgets.Button)
477      */

478     protected void setButtonLayoutData(Button button) {
479         GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
480         int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
481
482         // On large fonts this can make this dialog huge
483
widthHint = Math.min(widthHint,
484                 button.getDisplay().getBounds().width / 5);
485         Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
486         data.widthHint = Math.max(widthHint, minSize.x);
487
488         button.setLayoutData(data);
489     }
490
491     /**
492      * Creates the Cancel button for this wizard dialog. Creates a standard (<code>SWT.PUSH</code>)
493      * button and registers for its selection events. Note that the number of
494      * columns in the button bar composite is incremented. The Cancel button is
495      * created specially to give it a removeable listener.
496      *
497      * @param parent
498      * the parent button bar
499      * @return the new Cancel button
500      */

501     private Button createCancelButton(Composite parent) {
502         // increment the number of columns in the button bar
503
((GridLayout) parent.getLayout()).numColumns++;
504         Button button = new Button(parent, SWT.PUSH);
505         button.setText(IDialogConstants.CANCEL_LABEL);
506         setButtonLayoutData(button);
507         button.setFont(parent.getFont());
508         button.setData(new Integer JavaDoc(IDialogConstants.CANCEL_ID));
509         button.addSelectionListener(cancelListener);
510         return button;
511     }
512
513     /**
514      * Return the cancel button if the id is a the cancel id.
515      *
516      * @param id
517      * the button id
518      * @return the button corresponding to the button id
519      */

520     protected Button getButton(int id) {
521         if (id == IDialogConstants.CANCEL_ID) {
522             return cancelButton;
523         }
524         return super.getButton(id);
525     }
526
527     /**
528      * The <code>WizardDialog</code> implementation of this
529      * <code>Window</code> method calls call <code>IWizard.addPages</code>
530      * to allow the current wizard to add extra pages, then
531      * <code>super.createContents</code> to create the controls. It then calls
532      * <code>IWizard.createPageControls</code> to allow the wizard to
533      * pre-create their page controls prior to opening, so that the wizard opens
534      * to the correct size. And finally it shows the first page.
535      */

536     protected Control createContents(Composite parent) {
537         // Allow the wizard to add pages to itself
538
// Need to call this now so page count is correct
539
// for determining if next/previous buttons are needed
540
wizard.addPages();
541         Control contents = super.createContents(parent);
542         // Allow the wizard pages to precreate their page controls
543
createPageControls();
544         // Show the first page
545
showStartingPage();
546         return contents;
547     }
548
549     /*
550      * (non-Javadoc) Method declared on Dialog.
551      */

552     protected Control createDialogArea(Composite parent) {
553         Composite composite = (Composite) super.createDialogArea(parent);
554         // Build the Page container
555
pageContainer = createPageContainer(composite);
556         GridData gd = new GridData(GridData.FILL_BOTH);
557         gd.widthHint = pageWidth;
558         gd.heightHint = pageHeight;
559         pageContainer.setLayoutData(gd);
560         pageContainer.setFont(parent.getFont());
561         // Insert a progress monitor
562
GridLayout pmlayout = new GridLayout();
563         pmlayout.numColumns = 1;
564         progressMonitorPart = createProgressMonitorPart(composite, pmlayout);
565         GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
566         progressMonitorPart.setLayoutData(gridData);
567         progressMonitorPart.setVisible(false);
568         // Build the separator line
569
Label separator = new Label(composite, SWT.HORIZONTAL | SWT.SEPARATOR);
570         separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
571
572         applyDialogFont(progressMonitorPart);
573         return composite;
574     }
575
576     /**
577      * Create the progress monitor part in the receiver.
578      *
579      * @param composite
580      * @param pmlayout
581      * @return ProgressMonitorPart
582      */

583     protected ProgressMonitorPart createProgressMonitorPart(
584             Composite composite, GridLayout pmlayout) {
585         return new ProgressMonitorPart(composite, pmlayout, SWT.DEFAULT) {
586             String JavaDoc currentTask = null;
587
588             /*
589              * (non-Javadoc)
590              *
591              * @see org.eclipse.jface.wizard.ProgressMonitorPart#setBlocked(org.eclipse.core.runtime.IStatus)
592              */

593             public void setBlocked(IStatus reason) {
594                 super.setBlocked(reason);
595                 if (!lockedUI) {
596                     getBlockedHandler().showBlocked(getShell(), this, reason,
597                             currentTask);
598                 }
599             }
600
601             /*
602              * (non-Javadoc)
603              *
604              * @see org.eclipse.jface.wizard.ProgressMonitorPart#clearBlocked()
605              */

606             public void clearBlocked() {
607                 super.clearBlocked();
608                 if (!lockedUI) {
609                     getBlockedHandler().clearBlocked();
610                 }
611             }
612
613             /*
614              * (non-Javadoc)
615              *
616              * @see org.eclipse.jface.wizard.ProgressMonitorPart#beginTask(java.lang.String,
617              * int)
618              */

619             public void beginTask(String JavaDoc name, int totalWork) {
620                 super.beginTask(name, totalWork);
621                 currentTask = name;
622             }
623
624             /*
625              * (non-Javadoc)
626              *
627              * @see org.eclipse.jface.wizard.ProgressMonitorPart#setTaskName(java.lang.String)
628              */

629             public void setTaskName(String JavaDoc name) {
630                 super.setTaskName(name);
631                 currentTask = name;
632             }
633
634             /*
635              * (non-Javadoc)
636              *
637              * @see org.eclipse.jface.wizard.ProgressMonitorPart#subTask(java.lang.String)
638              */

639             public void subTask(String JavaDoc name) {
640                 super.subTask(name);
641                 // If we haven't got anything yet use this value for more
642
// context
643
if (currentTask == null) {
644                     currentTask = name;
645                 }
646             }
647         };
648     }
649
650     /**
651      * Creates the container that holds all pages.
652      *
653      * @param parent
654      * @return Composite
655      */

656     private Composite createPageContainer(Composite parent) {
657         Composite result = new Composite(parent, SWT.NULL);
658         result.setLayout(pageContainerLayout);
659         return result;
660     }
661
662     /**
663      * Allow the wizard's pages to pre-create their page controls. This allows
664      * the wizard dialog to open to the correct size.
665      */

666     private void createPageControls() {
667         // Allow the wizard pages to precreate their page controls
668
// This allows the wizard to open to the correct size
669
wizard.createPageControls(pageContainer);
670         // Ensure that all of the created pages are initially not visible
671
IWizardPage[] pages = wizard.getPages();
672         for (int i = 0; i < pages.length; i++) {
673             IWizardPage page = pages[i];
674             if (page.getControl() != null) {
675                 page.getControl().setVisible(false);
676             }
677         }
678     }
679
680     /**
681      * Creates the Previous and Next buttons for this wizard dialog. Creates
682      * standard (<code>SWT.PUSH</code>) buttons and registers for their
683      * selection events. Note that the number of columns in the button bar
684      * composite is incremented. These buttons are created specially to prevent
685      * any space between them.
686      *
687      * @param parent
688      * the parent button bar
689      * @return a composite containing the new buttons
690      */

691     private Composite createPreviousAndNextButtons(Composite parent) {
692         // increment the number of columns in the button bar
693
((GridLayout) parent.getLayout()).numColumns++;
694         Composite composite = new Composite(parent, SWT.NONE);
695         // create a layout with spacing and margins appropriate for the font
696
// size.
697
GridLayout layout = new GridLayout();
698         layout.numColumns = 0; // will be incremented by createButton
699
layout.marginWidth = 0;
700         layout.marginHeight = 0;
701         layout.horizontalSpacing = 0;
702         layout.verticalSpacing = 0;
703         composite.setLayout(layout);
704         GridData data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER
705                 | GridData.VERTICAL_ALIGN_CENTER);
706         composite.setLayoutData(data);
707         composite.setFont(parent.getFont());
708         backButton = createButton(composite, IDialogConstants.BACK_ID,
709                 IDialogConstants.BACK_LABEL, false);
710         nextButton = createButton(composite, IDialogConstants.NEXT_ID,
711                 IDialogConstants.NEXT_LABEL, false);
712         return composite;
713     }
714
715     /**
716      * Creates and return a new wizard closing dialog without openiong it.
717      *
718      * @return MessageDalog
719      */

720     private MessageDialog createWizardClosingDialog() {
721         MessageDialog result = new MessageDialog(getShell(),
722                 JFaceResources.getString("WizardClosingDialog.title"), //$NON-NLS-1$
723
null,
724                 JFaceResources.getString("WizardClosingDialog.message"), //$NON-NLS-1$
725
MessageDialog.QUESTION,
726                 new String JavaDoc[] { IDialogConstants.OK_LABEL }, 0);
727         return result;
728     }
729
730     /**
731      * The Finish button has been pressed.
732      */

733     protected void finishPressed() {
734         // Wizards are added to the nested wizards list in setWizard.
735
// This means that the current wizard is always the last wizard in the
736
// list.
737
// Note that we first call the current wizard directly (to give it a
738
// chance to
739
// abort, do work, and save state) then call the remaining n-1 wizards
740
// in the
741
// list (to save state).
742
if (wizard.performFinish()) {
743             // Call perform finish on outer wizards in the nested chain
744
// (to allow them to save state for example)
745
for (int i = 0; i < nestedWizards.size() - 1; i++) {
746                 ((IWizard) nestedWizards.get(i)).performFinish();
747             }
748             // Hard close the dialog.
749
setReturnCode(OK);
750             hardClose();
751         }
752     }
753
754     /*
755      * (non-Javadoc) Method declared on IWizardContainer.
756      */

757     public IWizardPage getCurrentPage() {
758         return currentPage;
759     }
760
761     /**
762      * Returns the progress monitor for this wizard dialog (if it has one).
763      *
764      * @return the progress monitor, or <code>null</code> if this wizard
765      * dialog does not have one
766      */

767     protected IProgressMonitor getProgressMonitor() {
768         return progressMonitorPart;
769     }
770
771     /**
772      * Returns the wizard this dialog is currently displaying.
773      *
774      * @return the current wizard
775      */

776     protected IWizard getWizard() {
777         return wizard;
778     }
779
780     /**
781      * Closes this window.
782      *
783      * @return <code>true</code> if the window is (or was already) closed, and
784      * <code>false</code> if it is still open
785      */

786     private boolean hardClose() {
787         // inform wizards
788
for (int i = 0; i < createdWizards.size(); i++) {
789             IWizard createdWizard = (IWizard) createdWizards.get(i);
790             createdWizard.dispose();
791             // Remove this dialog as a parent from the managed wizard.
792
// Note that we do this after calling dispose as the wizard or
793
// its pages may need access to the container during
794
// dispose code
795
createdWizard.setContainer(null);
796         }
797         return super.close();
798     }
799
800     /**
801      * The Help button has been pressed.
802      */

803     protected void helpPressed() {
804         if (currentPage != null) {
805             currentPage.performHelp();
806         }
807     }
808
809     /**
810      * The Next button has been pressed.
811      */

812     protected void nextPressed() {
813         IWizardPage page = currentPage.getNextPage();
814         if (page == null) {
815             // something must have happend getting the next page
816
return;
817         }
818
819         // show the next page
820
showPage(page);
821     }
822
823     /**
824      * Notifies page changing listeners and returns result of page changing
825      * processing to the sender.
826      *
827      * @param eventType
828      * @return <code>true</code> if page changing listener completes
829      * successfully, <code>false</code> otherwise
830      */

831     private boolean doPageChanging(IWizardPage targetPage) {
832         PageChangingEvent e = new PageChangingEvent(this, getCurrentPage(),
833                 targetPage);
834         firePageChanging(e);
835         // Prevent navigation if necessary
836
return e.doit;
837     }
838
839     /**
840      * Checks whether it is alright to close this wizard dialog and performed
841      * standard cancel processing. If there is a long running operation in
842      * progress, this method posts an alert message saying that the wizard
843      * cannot be closed.
844      *
845      * @return <code>true</code> if it is alright to close this dialog, and
846      * <code>false</code> if it is not
847      */

848     private boolean okToClose() {
849         if (activeRunningOperations > 0) {
850             synchronized (this) {
851                 windowClosingDialog = createWizardClosingDialog();
852             }
853             windowClosingDialog.open();
854             synchronized (this) {
855                 windowClosingDialog = null;
856             }
857             return false;
858         }
859         return wizard.performCancel();
860     }
861
862     /**
863      * Restores the enabled/disabled state of the given control.
864      *
865      * @param w
866      * the control
867      * @param h
868      * the map (key type: <code>String</code>, element type:
869      * <code>Boolean</code>)
870      * @param key
871      * the key
872      * @see #saveEnableStateAndSet
873      */

874     private void restoreEnableState(Control w, Map JavaDoc h, String JavaDoc key) {
875         if (w != null) {
876             Boolean JavaDoc b = (Boolean JavaDoc) h.get(key);
877             if (b != null) {
878                 w.setEnabled(b.booleanValue());
879             }
880         }
881     }
882
883     /**
884      * Restores the enabled/disabled state of the wizard dialog's buttons and
885      * the tree of controls for the currently showing page.
886      *
887      * @param state
888      * a map containing the saved state as returned by
889      * <code>saveUIState</code>
890      * @see #saveUIState
891      */

892     private void restoreUIState(Map JavaDoc state) {
893         restoreEnableState(backButton, state, "back"); //$NON-NLS-1$
894
restoreEnableState(nextButton, state, "next"); //$NON-NLS-1$
895
restoreEnableState(finishButton, state, "finish"); //$NON-NLS-1$
896
restoreEnableState(cancelButton, state, "cancel"); //$NON-NLS-1$
897
restoreEnableState(helpButton, state, "help"); //$NON-NLS-1$
898
Object JavaDoc pageValue = state.get("page"); //$NON-NLS-1$
899
if (pageValue != null) {
900             ((ControlEnableState) pageValue).restore();
901         }
902     }
903
904     /**
905      * This implementation of IRunnableContext#run(boolean, boolean,
906      * IRunnableWithProgress) blocks until the runnable has been run, regardless
907      * of the value of <code>fork</code>. It is recommended that
908      * <code>fork</code> is set to true in most cases. If <code>fork</code>
909      * is set to <code>false</code>, the runnable will run in the UI thread
910      * and it is the runnable's responsibility to call
911      * <code>Display.readAndDispatch()</code> to ensure UI responsiveness.
912      *
913      * UI state is saved prior to executing the long-running operation and is
914      * restored after the long-running operation completes executing. Any
915      * attempt to change the UI state of the wizard in the long-running
916      * operation will be nullified when original UI state is restored.
917      *
918      */

919     public void run(boolean fork, boolean cancelable,
920             IRunnableWithProgress runnable) throws InvocationTargetException JavaDoc,
921             InterruptedException JavaDoc {
922         // The operation can only be canceled if it is executed in a separate
923
// thread.
924
// Otherwise the UI is blocked anyway.
925
Object JavaDoc state = null;
926         if (activeRunningOperations == 0) {
927             state = aboutToStart(fork && cancelable);
928         }
929         activeRunningOperations++;
930         try {
931             if (!fork) {
932                 lockedUI = true;
933             }
934             ModalContext.run(runnable, fork, getProgressMonitor(), getShell()
935                     .getDisplay());
936             lockedUI = false;
937         } finally {
938             activeRunningOperations--;
939             // Stop if this is the last one
940
if (state != null) {
941                 stopped(state);
942             }
943         }
944     }
945
946     /**
947      * Saves the enabled/disabled state of the given control in the given map,
948      * which must be modifiable.
949      *
950      * @param w
951      * the control, or <code>null</code> if none
952      * @param h
953      * the map (key type: <code>String</code>, element type:
954      * <code>Boolean</code>)
955      * @param key
956      * the key
957      * @param enabled
958      * <code>true</code> to enable the control, and
959      * <code>false</code> to disable it
960      * @see #restoreEnableState(Control, Map, String)
961      */

962     private void saveEnableStateAndSet(Control w, Map JavaDoc h, String JavaDoc key,
963             boolean enabled) {
964         if (w != null) {
965             h.put(key, w.getEnabled() ? Boolean.TRUE : Boolean.FALSE);
966             w.setEnabled(enabled);
967         }
968     }
969
970     /**
971      * Captures and returns the enabled/disabled state of the wizard dialog's
972      * buttons and the tree of controls for the currently showing page. All
973      * these controls are disabled in the process, with the possible exception
974      * of the Cancel button.
975      *
976      * @param keepCancelEnabled
977      * <code>true</code> if the Cancel button should remain
978      * enabled, and <code>false</code> if it should be disabled
979      * @return a map containing the saved state suitable for restoring later
980      * with <code>restoreUIState</code>
981      * @see #restoreUIState
982      */

983     private Map JavaDoc saveUIState(boolean keepCancelEnabled) {
984         Map JavaDoc savedState = new HashMap JavaDoc(10);
985         saveEnableStateAndSet(backButton, savedState, "back", false); //$NON-NLS-1$
986
saveEnableStateAndSet(nextButton, savedState, "next", false); //$NON-NLS-1$
987
saveEnableStateAndSet(finishButton, savedState, "finish", false); //$NON-NLS-1$
988
saveEnableStateAndSet(cancelButton, savedState,
989                 "cancel", keepCancelEnabled); //$NON-NLS-1$
990
saveEnableStateAndSet(helpButton, savedState, "help", false); //$NON-NLS-1$
991
if (currentPage != null) {
992             savedState
993                     .put(
994                             "page", ControlEnableState.disable(currentPage.getControl())); //$NON-NLS-1$
995
}
996         return savedState;
997     }
998
999     /**
1000     * Sets the given cursor for all shells currently active for this window's
1001     * display.
1002     *
1003     * @param c
1004     * the cursor
1005     */

1006    private void setDisplayCursor(Cursor c) {
1007        Shell[] shells = getShell().getDisplay().getShells();
1008        for (int i = 0; i < shells.length; i++) {
1009            shells[i].setCursor(c);
1010        }
1011    }
1012
1013    /**
1014     * Sets the minimum page size used for the pages.
1015     *
1016     * @param minWidth
1017     * the minimum page width
1018     * @param minHeight
1019     * the minimum page height
1020     * @see #setMinimumPageSize(Point)
1021     */

1022    public void setMinimumPageSize(int minWidth, int minHeight) {
1023        Assert.isTrue(minWidth >= 0 && minHeight >= 0);
1024        pageContainerLayout.minimumWidth = minWidth;
1025        pageContainerLayout.minimumHeight = minHeight;
1026    }
1027
1028    /**
1029     * Sets the minimum page size used for the pages.
1030     *
1031     * @param size
1032     * the page size encoded as <code>new Point(width,height)</code>
1033     * @see #setMinimumPageSize(int,int)
1034     */

1035    public void setMinimumPageSize(Point size) {
1036        setMinimumPageSize(size.x, size.y);
1037    }
1038
1039    /**
1040     * Sets the size of all pages. The given size takes precedence over computed
1041     * sizes.
1042     *
1043     * @param width
1044     * the page width
1045     * @param height
1046     * the page height
1047     * @see #setPageSize(Point)
1048     */

1049    public void setPageSize(int width, int height) {
1050        pageWidth = width;
1051        pageHeight = height;
1052    }
1053
1054    /**
1055     * Sets the size of all pages. The given size takes precedence over computed
1056     * sizes.
1057     *
1058     * @param size
1059     * the page size encoded as <code>new Point(width,height)</code>
1060     * @see #setPageSize(int,int)
1061     */

1062    public void setPageSize(Point size) {
1063        setPageSize(size.x, size.y);
1064    }
1065
1066    /**
1067     * Sets the wizard this dialog is currently displaying.
1068     *
1069     * @param newWizard
1070     * the wizard
1071     */

1072    protected void setWizard(IWizard newWizard) {
1073        wizard = newWizard;
1074        wizard.setContainer(this);
1075        if (!createdWizards.contains(wizard)) {
1076            createdWizards.add(wizard);
1077            // New wizard so just add it to the end of our nested list
1078
nestedWizards.add(wizard);
1079            if (pageContainer != null) {
1080                // Dialog is already open
1081
// Allow the wizard pages to precreate their page controls
1082
// This allows the wizard to open to the correct size
1083
createPageControls();
1084                // Ensure the dialog is large enough for the wizard
1085
updateSizeForWizard(wizard);
1086                pageContainer.layout(true);
1087            }
1088        } else {
1089            // We have already seen this wizard, if it is the previous wizard
1090
// on the nested list then we assume we have gone back and remove
1091
// the last wizard from the list
1092
int size = nestedWizards.size();
1093            if (size >= 2 && nestedWizards.get(size - 2) == wizard) {
1094                nestedWizards.remove(size - 1);
1095            } else {
1096                // Assume we are going forward to revisit a wizard
1097
nestedWizards.add(wizard);
1098            }
1099        }
1100    }
1101
1102    /*
1103     * (non-Javadoc) Method declared on IWizardContainer.
1104     */

1105    public void showPage(IWizardPage page) {
1106        if (page == null || page == currentPage) {
1107            return;
1108        }
1109
1110        if (!isMovingToPreviousPage) {
1111            // remember my previous page.
1112
page.setPreviousPage(currentPage);
1113        } else {
1114            isMovingToPreviousPage = false;
1115        }
1116
1117        // If page changing evaluation unsuccessful, do not change the page
1118
if (!doPageChanging(page))
1119            return;
1120
1121        // Update for the new page in a busy cursor if possible
1122
if (getContents() == null) {
1123            updateForPage(page);
1124        } else {
1125            final IWizardPage finalPage = page;
1126            BusyIndicator.showWhile(getContents().getDisplay(), new Runnable JavaDoc() {
1127                public void run() {
1128                    updateForPage(finalPage);
1129                }
1130            });
1131        }
1132    }
1133
1134    /**
1135     * Update the receiver for the new page.
1136     *
1137     * @param page
1138     */

1139    private void updateForPage(IWizardPage page) {
1140        // ensure this page belongs to the current wizard
1141
if (wizard != page.getWizard()) {
1142            setWizard(page.getWizard());
1143        }
1144        // ensure that page control has been created
1145
// (this allows lazy page control creation)
1146
if (page.getControl() == null) {
1147            page.createControl(pageContainer);
1148            // the page is responsible for ensuring the created control is
1149
// accessable
1150
// via getControl.
1151
Assert.isNotNull(page.getControl(), JFaceResources.format(
1152                    JFaceResources.getString("WizardDialog.missingSetControl"), //$NON-NLS-1$
1153
new Object JavaDoc[] { page.getName() }));
1154            // ensure the dialog is large enough for this page
1155
updateSize(page);
1156        }
1157        // make the new page visible
1158
IWizardPage oldPage = currentPage;
1159        currentPage = page;
1160
1161        currentPage.setVisible(true);
1162        if (oldPage != null) {
1163            oldPage.setVisible(false);
1164        }
1165        // update the dialog controls
1166
update();
1167    }
1168
1169    /**
1170     * Shows the starting page of the wizard.
1171     */

1172    private void showStartingPage() {
1173        currentPage = wizard.getStartingPage();
1174        if (currentPage == null) {
1175            // something must have happend getting the page
1176
return;
1177        }
1178        // ensure the page control has been created
1179
if (currentPage.getControl() == null) {
1180            currentPage.createControl(pageContainer);
1181            // the page is responsible for ensuring the created control is
1182
// accessable
1183
// via getControl.
1184
Assert.isNotNull(currentPage.getControl());
1185            // we do not need to update the size since the call
1186
// to initialize bounds has not been made yet.
1187
}
1188        // make the new page visible
1189
currentPage.setVisible(true);
1190        // update the dialog controls
1191
update();
1192    }
1193
1194    /**
1195     * A long running operation triggered through the wizard was stopped either
1196     * by user input or by normal end. Hides the progress monitor and restores
1197     * the enable state wizard's buttons and controls.
1198     *
1199     * @param savedState
1200     * the saved UI state as returned by <code>aboutToStart</code>
1201     * @see #aboutToStart
1202     */

1203    private void stopped(Object JavaDoc savedState) {
1204        if (getShell() != null) {
1205            if (wizard.needsProgressMonitor()) {
1206                progressMonitorPart.setVisible(false);
1207                progressMonitorPart.removeFromCancelComponent(cancelButton);
1208            }
1209            Map JavaDoc state = (Map JavaDoc) savedState;
1210            restoreUIState(state);
1211            cancelButton.addSelectionListener(cancelListener);
1212            setDisplayCursor(null);
1213            cancelButton.setCursor(null);
1214            waitCursor.dispose();
1215            waitCursor = null;
1216            arrowCursor.dispose();
1217            arrowCursor = null;
1218            Control focusControl = (Control) state.get(FOCUS_CONTROL);
1219            if (focusControl != null) {
1220                focusControl.setFocus();
1221            }
1222        }
1223    }
1224
1225    /**
1226     * Updates this dialog's controls to reflect the current page.
1227     */

1228    protected void update() {
1229        // Update the window title
1230
updateWindowTitle();
1231        // Update the title bar
1232
updateTitleBar();
1233        // Update the buttons
1234
updateButtons();
1235
1236        // Fires the page change event
1237
firePageChanged(new PageChangedEvent(this, getCurrentPage()));
1238    }
1239
1240    /*
1241     * (non-Javadoc) Method declared on IWizardContainer.
1242     */

1243    public void updateButtons() {
1244        boolean canFlipToNextPage = false;
1245        boolean canFinish = wizard.canFinish();
1246        if (backButton != null) {
1247            backButton.setEnabled(currentPage.getPreviousPage() != null);
1248        }
1249        if (nextButton != null) {
1250            canFlipToNextPage = currentPage.canFlipToNextPage();
1251            nextButton.setEnabled(canFlipToNextPage);
1252        }
1253        finishButton.setEnabled(canFinish);
1254        // finish is default unless it is diabled and next is enabled
1255
if (canFlipToNextPage && !canFinish) {
1256            getShell().setDefaultButton(nextButton);
1257        } else {
1258            getShell().setDefaultButton(finishButton);
1259        }
1260    }
1261
1262    /**
1263     * Update the message line with the page's description.
1264     * <p>
1265     * A discription is shown only if there is no message or error message.
1266     * </p>
1267     */

1268    private void updateDescriptionMessage() {
1269        pageDescription = currentPage.getDescription();
1270        setMessage(pageDescription);
1271    }
1272
1273    /*
1274     * (non-Javadoc) Method declared on IWizardContainer.
1275     */

1276    public void updateMessage() {
1277
1278        if (currentPage == null) {
1279            return;
1280        }
1281
1282        pageMessage = currentPage.getMessage();
1283        if (pageMessage != null && currentPage instanceof IMessageProvider) {
1284            pageMessageType = ((IMessageProvider) currentPage).getMessageType();
1285        } else {
1286            pageMessageType = IMessageProvider.NONE;
1287        }
1288        if (pageMessage == null) {
1289            setMessage(pageDescription);
1290        } else {
1291            setMessage(pageMessage, pageMessageType);
1292        }
1293        setErrorMessage(currentPage.getErrorMessage());
1294    }
1295
1296    /**
1297     * Changes the shell size to the given size, ensuring that it is no larger
1298     * than the display bounds.
1299     *
1300     * @param width
1301     * the shell width
1302     * @param height
1303     * the shell height
1304     */

1305    private void setShellSize(int width, int height) {
1306        Rectangle size = getShell().getBounds();
1307        size.height = height;
1308        size.width = width;
1309        getShell().setBounds(getConstrainedShellBounds(size));
1310    }
1311
1312    /**
1313     * Computes the correct dialog size for the current page and resizes its
1314     * shell if nessessary. Also causes the container to refresh its layout.
1315     *
1316     * @param page
1317     * the wizard page to use to resize the dialog
1318     * @since 2.0
1319     */

1320    protected void updateSize(IWizardPage page) {
1321        if (page == null || page.getControl() == null) {
1322            return;
1323        }
1324        updateSizeForPage(page);
1325        pageContainerLayout.layoutPage(page.getControl());
1326    }
1327
1328    /*
1329     * (non-Javadoc)
1330     *
1331     * @see org.eclipse.jface.wizard.IWizardContainer2#updateSize()
1332     */

1333    public void updateSize() {
1334        updateSize(currentPage);
1335    }
1336
1337    /**
1338     * Computes the correct dialog size for the given page and resizes its shell
1339     * if nessessary.
1340     *
1341     * @param page
1342     * the wizard page
1343     */

1344    private void updateSizeForPage(IWizardPage page) {
1345        // ensure the page container is large enough
1346
Point delta = calculatePageSizeDelta(page);
1347        if (delta.x > 0 || delta.y > 0) {
1348            // increase the size of the shell
1349
Shell shell = getShell();
1350            Point shellSize = shell.getSize();
1351            setShellSize(shellSize.x + delta.x, shellSize.y + delta.y);
1352            constrainShellSize();
1353        }
1354    }
1355
1356    /**
1357     * Computes the correct dialog size for the given wizard and resizes its
1358     * shell if nessessary.
1359     *
1360     * @param sizingWizard
1361     * the wizard
1362     */

1363    private void updateSizeForWizard(IWizard sizingWizard) {
1364        Point delta = new Point(0, 0);
1365        IWizardPage[] pages = sizingWizard.getPages();
1366        for (int i = 0; i < pages.length; i++) {
1367            // ensure the page container is large enough
1368
Point pageDelta = calculatePageSizeDelta(pages[i]);
1369            delta.x = Math.max(delta.x, pageDelta.x);
1370            delta.y = Math.max(delta.y, pageDelta.y);
1371        }
1372        if (delta.x > 0 || delta.y > 0) {
1373            // increase the size of the shell
1374
Shell shell = getShell();
1375            Point shellSize = shell.getSize();
1376            setShellSize(shellSize.x + delta.x, shellSize.y + delta.y);
1377        }
1378    }
1379
1380    /*
1381     * (non-Javadoc) Method declared on IWizardContainer.
1382     */

1383    public void updateTitleBar() {
1384        String JavaDoc s = null;
1385        if (currentPage != null) {
1386            s = currentPage.getTitle();
1387        }
1388        if (s == null) {
1389            s = ""; //$NON-NLS-1$
1390
}
1391        setTitle(s);
1392        if (currentPage != null) {
1393            setTitleImage(currentPage.getImage());
1394            updateDescriptionMessage();
1395        }
1396        updateMessage();
1397    }
1398
1399    /*
1400     * (non-Javadoc) Method declared on IWizardContainer.
1401     */

1402    public void updateWindowTitle() {
1403        if (getShell() == null) {
1404            // Not created yet
1405
return;
1406        }
1407        String JavaDoc title = wizard.getWindowTitle();
1408        if (title == null) {
1409            title = ""; //$NON-NLS-1$
1410
}
1411        getShell().setText(title);
1412    }
1413
1414    /*
1415     * (non-Javadoc)
1416     *
1417     * @see org.eclipse.jface.dialogs.IPageChangeProvider#getSelectedPage()
1418     */

1419    public Object JavaDoc getSelectedPage() {
1420        return getCurrentPage();
1421    }
1422
1423    /*
1424     * (non-Javadoc)
1425     *
1426     * @see org.eclipse.jface.dialog.IPageChangeProvider#addPageChangedListener()
1427     */

1428    public void addPageChangedListener(IPageChangedListener listener) {
1429        pageChangedListeners.add(listener);
1430    }
1431
1432    /*
1433     * (non-Javadoc)
1434     *
1435     * @see org.eclipse.jface.dialog.IPageChangeProvider#removePageChangedListener()
1436     */

1437    public void removePageChangedListener(IPageChangedListener listener) {
1438        pageChangedListeners.remove(listener);
1439    }
1440
1441    /**
1442     * Notifies any selection changed listeners that the selected page has
1443     * changed. Only listeners registered at the time this method is called are
1444     * notified.
1445     *
1446     * @param event
1447     * a selection changed event
1448     *
1449     * @see IPageChangedListener#pageChanged
1450     *
1451     * @since 3.1
1452     */

1453    protected void firePageChanged(final PageChangedEvent event) {
1454        Object JavaDoc[] listeners = pageChangedListeners.getListeners();
1455        for (int i = 0; i < listeners.length; ++i) {
1456            final IPageChangedListener l = (IPageChangedListener) listeners[i];
1457            SafeRunnable.run(new SafeRunnable() {
1458                public void run() {
1459                    l.pageChanged(event);
1460                }
1461            });
1462        }
1463    }
1464
1465    /**
1466     * Adds a listener for page changes to the list of page changing listeners
1467     * registered for this dialog. Has no effect if an identical listener is
1468     * already registered.
1469     *
1470     * @param listener
1471     * a page changing listener
1472     * @since 3.3
1473     */

1474    public void addPageChangingListener(IPageChangingListener listener) {
1475        pageChangingListeners.add(listener);
1476    }
1477
1478    /**
1479     * Removes the provided page changing listener from the list of page
1480     * changing listeners registered for the dialog.
1481     *
1482     * @param listener
1483     * a page changing listener
1484     * @since 3.3
1485     */

1486    public void removePageChangingListener(IPageChangingListener listener) {
1487        pageChangingListeners.remove(listener);
1488    }
1489
1490    /**
1491     * Notifies any page changing listeners that the currently selected dialog
1492     * page is changing. Only listeners registered at the time this method is
1493     * called are notified.
1494     *
1495     * @param event
1496     * a selection changing event
1497     *
1498     * @see IPageChangingListener#handlePageChanging(PageChangingEvent)
1499     * @since 3.3
1500     */

1501    protected void firePageChanging(final PageChangingEvent event) {
1502        Object JavaDoc[] listeners = pageChangingListeners.getListeners();
1503        for (int i = 0; i < listeners.length; ++i) {
1504            final IPageChangingListener l = (IPageChangingListener) listeners[i];
1505            SafeRunnable.run(new SafeRunnable() {
1506                public void run() {
1507                    l.handlePageChanging(event);
1508                }
1509            });
1510        }
1511    }
1512}
1513
Popular Tags