NEW - bug 203343: update "Creating JFace Wizards" article
https://bugs.eclipse.org/bugs/show_bug.cgi?id=203343
diff --git a/.htaccess b/.htaccess
index d306324..9d9c736 100644
--- a/.htaccess
+++ b/.htaccess
@@ -58,4 +58,7 @@
 Redirect permanent "/articles/Article-CustomDrawingTableAndTreeItems/customDraw.htm" http:/articles/article.php?file=Article-CustomDrawingTableAndTreeItems/index.html

 

 #Updated Eclipse DB Apps article.

-Redirect permanent "/articles/Article-EclipseDbWebapps/article.html" http:/articles/article.php?file=Article-EclipseDbWebapps/index.html
\ No newline at end of file
+Redirect permanent "/articles/Article-EclipseDbWebapps/article.html" http:/articles/article.php?file=Article-EclipseDbWebapps/index.html

+

+#Updated JFace Wizards

+Redirect permanent "/articles/Article-JFace Wizards/wizardArticle.html" http:/articles/article.php?file=Article-JFaceWizards/index.html
\ No newline at end of file
diff --git a/Article-JFace Wizards/about.xml b/Article-JFaceWizards/about.xml
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/about.xml
rename to Article-JFaceWizards/about.xml
diff --git a/Article-JFace Wizards/com.xyz.article.wizards.zip b/Article-JFaceWizards/com.xyz.article.wizards.zip
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/com.xyz.article.wizards.zip
rename to Article-JFaceWizards/com.xyz.article.wizards.zip
Binary files differ
diff --git a/Article-JFaceWizards/index.html b/Article-JFaceWizards/index.html
new file mode 100755
index 0000000..15e535e
--- /dev/null
+++ b/Article-JFaceWizards/index.html
@@ -0,0 +1,650 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title>Creating JFace Wizards</title>
+<meta http-equiv="Content-Type"
+	content="text/html; charset=windows-1252">
+<link href="../article.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h1>Creating JFace Wizards</h1>
+<div class="summary">
+<h2>Summary</h2>
+<p>This article shows you how to implement a wizard using the JFace
+toolkit and how to contribute your wizard to the Eclipse workbench. A
+wizard whose page structure changes according to user input is
+implemented to demonstrate the flexibility of wizard support.</p>
+<div class="author">By Doina Klinger, IBM UK</div>
+<div class="copyright">Copyright &copy; 2002 International
+Business Machines Corp.</div>
+<div class="date">December 16, 2002 (Sample code updated July 2007
+for Eclipse 3.3)</div>
+</div>
+
+<div class="content">
+<h2>Introduction</h2>
+<p>Wizards are used extensively throughout Eclipse. You can use
+wizards to create a new Java class or new resources like Projects,
+Folders or Files. A well designed wizard can considerably simplify user
+tasks and increase productivity.</p>
+<p>Wizards are meant to take the hassle out of standard, repetitive,
+or tedious user tasks. For example, the Java New Class wizard can
+collect enough information to generate a skeleton implementation of a
+user's class, including package statements, constructors, inherited
+methods, and other details. Of course, as the wizard developer, you must
+implement the code that makes the wizard useful for your domain.</p>
+
+
+<p>Not only does the platform contain many wizards, but there is a
+lot of support for writing your own. The JFace wizard framework lets you
+concentrate on the specifics of your wizard implementation. You will
+need to use the <code>org.eclipse.jface.wizard</code> package of JFace.
+It is very easy to get started while the support is flexible enough to
+allow you to add more complex logic to your wizards.</p>
+<h2>Wizard sample</h2>
+<p>Our sample wizard will gather some holiday travel choices from
+the user and collect more information based on the user's initial
+choices. Information about the holiday is kept in a model data object
+which is manipulated by the wizard page. The user's holiday data will be
+displayed in an information dialog upon completion of the wizard.</p>
+
+
+<h3>Running the Wizard</h3>
+<p>To run the sample or view its source, unzip the <a
+	href="com.xyz.article.wizards.zip">com.xyz.article.wizards.zip</a>
+(updated July 2007 for Eclipse 3.3) into your eclipse root directory and
+restart the workbench. You can start the sample wizard from the New
+button or from File&gt;New menu of the workbench (<a href="#NewMenu">Figure
+5</a>). Alternatively, you can select the context menu of a folder (in any
+perspective) and start the wizard from there (<a href="#PopupMenu">Figure
+6</a>).</p>
+<p>Let's look at our sample wizard in detail before diving into
+details of implementing it. On the first page the users can select the
+dates of travel, the type of transport for their holiday and enter the
+departure and destination locations:</p>
+<center><img border="0" src="wizards_files/mainPage.gif" alt=""><br>
+Figure 1. Starting page of the wizard</center>
+<p>The next page to be shown depends on the selected mode of
+transport. If the user has selected travel by plane the following page
+is displayed which shows the available flights. To keep the example code
+simple this information will be hard coded, rather than obtained from
+some database. The user can select the type of seat they want and to ask
+for the ticket price by pushing the &quot;Get price&quot; button. The
+base price is hard-coded as well. A discount is offered in conditions
+explained <a href="#Discount">below</a>.</p>
+<center><img border="0" src="wizards_files/plane.gif" alt=""><br>
+Figure 2. Page displayed when the user has selected the plane</center>
+<p>When the user has selected a flight and a type of seat the wizard
+can be finished.</p>
+<p>If the user has selected the car as mode of transport, a
+different page is shown. The user can select the name of a rental
+company. Based on the company name, the price of the rented car is
+displayed. Once again, the prices are hard-coded and depend only on the
+rental company selected but not on dates and destination. The user can
+select whether to buy insurance from the rental company.</p>
+
+<center><img border="0" src="wizards_files/car.gif" alt=""><br>
+Figure 3. Page displayed when the user has selected the car.</center>
+<p>When the user clicks Finish a message dialog is displayed
+summarizing the holiday data collected from the user. The wizard
+responds to various events and reports user errors.</p>
+<p>This article explains the following:</p>
+<ul>
+	<li>how to create, add and initialize wizard pages</li>
+	<li>how to listen for events and control errors</li>
+	<li>how to change the page order</li>
+	<li>what to do on completion of a wizard</li>
+	<li>how to start a wizard</li>
+</ul>
+
+
+<h2>Wizard Pages</h2>
+<p>JFace provides the interfaces <code>org.eclipse.jface.wizard.IWizard</code>
+and <code>org.eclipse.jface.wizard.IWizardPage</code> to describe
+wizards and corresponding implementation classes that handle many of the
+details of implementing wizards. Our wizard class HolidayWizard extends
+<code>org.eclipse.jface.wizard.Wizard</code>, which is a useful abstract
+class to extend. Its main responsibilities are to create the pages
+inside the wizard and perform the work when the wizard is completed.</p>
+
+
+<h3>Adding Pages to a Wizard</h3>
+
+
+<p>Each page is instantiated and added to the wizard. The order in
+which we add the pages to the wizard is the default navigation order.
+The page which is added first will be the starting page when the wizard
+is opened. Later we will look at ways of changing these defaults. The
+corresponding method on the HolidayWizard class is shown below:</p>
+<pre>public void addPages()
+{
+     holidayPage = new HolidayMainPage(workbench, selection);
+     addPage(holidayPage);
+     planePage = new PlanePage(&quot;&quot;);
+     addPage(planePage);
+     carPage = new CarPage(&quot;&quot;);
+     addPage(carPage);
+}</pre>
+
+<h3>Creating the Controls</h3>
+<p>First you need to decide which controls you want to use and then
+how they should appear on the wizard page. Here is a quick guideline on
+common widgets choices:</p>
+<ul>
+	<li>text fields : use them when you cannot predict what the user
+	will enter. In our example, we let the users type in any holiday
+	destination they want.</li>
+	<li>combo boxes : use them to indicate a single selection from
+	several options. The user can select only one type of seat in the
+	plane: window, aisle or center.</li>
+	<li>lists: use them to display many options from which one or more
+	can be selected. We show the available flights in a list widget.</li>
+	<li>buttons: there are three styles of buttons in SWT.
+	<ul>
+		<li>checkboxes: use them to show options with clear
+		&quot;yes&quot; or &quot;no&quot; meaning. When you rent a car, you
+		either take the insurance from the rental company or you don't.</li>
+		<li>radio buttons: use them when you want the user to select one
+		options from two or more options. In our simplified model, you can
+		either travel by car or by plane.</li>
+		<li>push buttons: use them to trigger an event. The button on the
+		plane page retrieves the price for the flight.</li>
+	</ul>
+	</li>
+</ul>
+<p>Widgets of type <code>org.eclipse.swt.widgets.Composite</code>
+are used to hold other widgets. To create a widget of one of the types
+mentioned above, you call its constructor and pass the parent Composite
+and a mask of bits indicating the style.</p>
+
+<p>More information about various widgets can be found in the
+Javadoc for <strong>org.eclipse.swt.widgets</strong>, and <a
+	href="http://help.eclipse.org/help33/topic/org.eclipse.platform.doc.isv/guide/swt.htm"
+	target="_blank"> SWT documentation</a>.</p>
+
+<p>You will need to use layouts to give your wizard page a specific
+look. A layout controls the position and size of children in a
+Composite. In our sample, we use <span lang="EN-US"
+	style="mso-ansi-language: EN-US"><code>org.eclipse.swt.layout.GridLayout</code>,
+which is one of the most flexible standard layouts. With a <code>GridLayout</code>,
+the widget children of a <code>Composite</code> are laid out in a grid,
+left to right, top to bottom. The <code>numColumns</code> specifies the
+number of columns in the grid. GridData is the layout data object
+associated with GridLayout. With a GridData object you can control
+things like the widget's alignment, indent or span, horizontally and
+vertically. Use <code>setLayoutData</code> method to set the grid data
+of a widget</span>. For more details on layouts see the <a
+	href="http://www.eclipse.org/articles/Understanding%20Layouts/Understanding%20Layouts.htm"
+	target="_blank">Understanding Layouts</a> article.</p>
+<p>We start by hand-drawing a rough sketch of each wizard page, to
+find out the number of columns of the grid and the general look of the
+page. For a better organization of the information on the page, we use
+horizontal rules to separate related groups of input fields.</p>
+<p>The place to create the page controls and arrange them on a page
+is the <code>createControl</code> method or each wizard page. The method
+is invoked once for each page when the wizard is first created with a
+parameter of type Composite. A typical implementation of this method is
+shown below. It does the following tasks::</p>
+<ul>
+	<li>create a composite using the specified parent (<img border="0"
+		src="wizards_files/tag_1.gif" alt="">)</li>
+	<li>construct the widgets and, if necessary, their layout data
+	objects (<img border="0" src="wizards_files/tag_2.gif" alt="">)</li>
+
+	<li>construct the widgets and, if neccesary, their layout data
+	objects(<img border="0" src="wizards_files/tag_3.gif" alt="">)</li>
+	<li>set the composite as the control associated with the wizard
+	page (<img border="0" src="wizards_files/tag_4.gif" alt="">).</li>
+</ul>
+<p>Here is a simplified implementation of the createControl method
+for the HolidayMainPage. Some details have been omitted for brevity.</p>
+<pre>public void createControl(Composite parent) {
+    // create the composite to hold the widgets   
+<img border="0" src="wizards_files/tag_1.gif" alt="">  Composite composite = new Composite(parent, SWT.NONE);
+    // create the desired layout for this wizard page
+<img border="0" src="wizards_files/tag_2.gif" alt="">  GridLayout gl = new GridLayout();
+    int ncol = 4;
+    gl.numColumns = ncol;
+    composite.setLayout(gl);		
+    // create the widgets  and their grid data objects 
+    // Date of travel
+<img border="0" src="wizards_files/tag_3.gif" alt="">  new Label (composite, SWT.NONE).setText("Travel on:");						
+    travelDate = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+    GridData gd = new GridData();
+    gd.horizontalAlignment = GridData.BEGINNING;
+    gd.widthHint = 25;
+    travelDate.setLayoutData(gd);
+
+    travelMonth = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+    travelMonth.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    travelYear = new Combo(composite,  SWT.BORDER | SWT.READ_ONLY);
+    travelYear.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    // Similar widgets are constructed for date of return ...
+    createLine(composite, ncol);
+    // Departure				
+    new Label (composite, SWT.NONE).setText("From:");				
+    fromText = new Text(composite, SWT.BORDER);
+    gd = new GridData(GridData.FILL_HORIZONTAL);
+    gd.horizontalSpan = ncol - 1;
+    fromText.setLayoutData(gd);
+
+    // Similar for Destination ...
+    createLine(composite, ncol);
+
+    // Travel by plane		
+    planeButton = new Button(composite, SWT.RADIO);
+    planeButton.setText("Take a plane");
+    gd = new GridData(GridData.FILL_HORIZONTAL);
+    gd.horizontalSpan = ncol;
+    planeButton.setLayoutData(gd);
+    planeButton.setSelection(true);
+
+   // Similar for carButton	...
+   // set the composite as the control for this page
+<img border="0" src="wizards_files/tag_4.gif" alt=""> setControl(composite);		
+}</pre>
+
+<h3>Events</h3>
+<p>Our wizard is not very useful if it is not able to respond to
+changes and user interaction. The simplest way to register events on
+wizard controls is to use the addListener method to register the wizard
+page itself as the handler of the events.The wizard page must implement
+the <code>org.eclipse.swt.widgets.Listener</code> interface with its
+handleEvent method. Classes which implement this interface are described
+within SWT as providing the <em>untyped listener</em> API. <code></code>The
+listeners implement a simple <code>handleEvent(...)</code> method that
+is used internally by SWT to dispatch events.</p>
+<p>In our Plane page we want to know when the user interacts with
+the &quot;Get price&quot; button, with the list of flights and with the
+combo box that holds the seats choices. We add listeners in the
+createControl method for these widgets.The untyped event mechanism uses
+a constant to identify the type of event. In our case we are interested
+in Selection type events for the widgets.</p>
+
+<pre>public void createControl(Composite parent) {
+   // ...
+   // price button
+   priceButton = new Button(composite, SWT.PUSH);
+   priceButton.addListener(SWT.Selection, this);
+   // ...
+
+   // flights
+   flightsList = new List(composite, SWT.BORDER | SWT.READ_ONLY );
+   flightsList.addListener(SWT.Selection, this);
+   // ...
+
+   // seat choice		
+   seatCombo = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+   seatCombo.addListener(SWT.Selection, this);
+   // ...
+}</pre>
+
+<p>When the specified event occurs, the handleEvent method is
+invoked for each registered listener. The listener, in our case the
+WizardPage, implements a "case style" listener in which we check for
+various fields of the event parameter (like its type or source) and
+respond accordingly. For the PlanePage, we do some special action if the
+priceButton has been selected, informing the user of the flight price.</p>
+
+<pre>public void handleEvent(Event e) { 
+   if (e.widget == priceButton) { 
+      if (flightsList.getSelectionCount() &gt;0) { 
+         if (((HolidayWizard)getWizard()).model.discounted) 
+            price *= discountRate;
+            MessageDialog.openInformation(this.getShell(),&quot;&quot;, &quot;Flight price &quot;+ price); 
+      } 
+   } 
+   //... 
+}</pre>
+
+<h3>Processing Errors</h3>
+<p>The data entered by the user on a wizard page can have a number
+of errors caused by wrong choices or invalid values. Where appropriate,
+we should disable the options which are not valid in order to prevent
+such errors. Where this is not possible, we need to inform the user of
+the error. When the user corrects it the error message needs to be
+cleared.</p>
+<p>In the sample we disallow destinations to be the same as the
+departures (not much of a holiday, is it?). No travel back in time is
+allowed either, so the date of return needs to be after the date of
+travel. We won't check that the dates are correct. Hopefully you will
+not find any flight on the 30th of February anyway.</p>
+<center><img border="0" src="wizards_files/error.gif" alt=""><br>
+Figure 4. Reporting an error to the user.</center>
+<p>You can use the <code>setMessage</code> and <code>setErrorMessage</code>
+methods to display information or error messages. The user can interact
+with the controls in any order and, consequently, produce or clear
+various errors. A common way to handle errors is to use a status
+variable for each possible type of event which can create an error, a
+warning or an information message.</p>
+<p>The error handling for the first page is shown below. If the
+destination or departure fields have triggered the event <img border="0"
+	src="wizards_files/tag_5.gif" alt="">, the the corresponding <code>org.eclipse.core.runtime.IStatus</code>
+variable, is either set with an error if the two are the same or
+cleared. If any of the date fields was modified <img border="0"
+	src="wizards_files/tag_6.gif" alt="">, we set the timeStatus
+variable to the right value. At the end of each processing of an event <img
+	border="0" src="wizards_files/tag_7.gif" alt="">, we update the
+page to display the most serious error message. This can be the first
+error or the first warning if there is no error or null if the page is
+correct. When the page is correct, we should see again the page
+description. This is how the sample code looks:</p>
+
+<pre>public void handleEvent(Event event) {
+     // Initialize a variable with the no error status
+     Status status = new Status(IStatus.OK, &quot;not_used&quot;, 0, &quot;&quot;, null);
+     // If the event is triggered by the destination or departure fields
+     // set the corresponding status variable to the right value
+<img border="0" src="wizards_files/tag_5.gif" alt="">   if ((event.widget == fromText) || (event.widget == toText)) {
+	 if (fromText.getText().equals(toText.getText()))
+	       status = new Status(IStatus.ERROR, &quot;not_used&quot;, 0, 
+	           &quot;Departure and destination cannot be the same&quot;, null);        
+	 destinationStatus = status;
+     }
+     // If the event is triggered by any of the date fields  set
+     // corresponding status variable to the right value
+<img border="0" src="wizards_files/tag_6.gif" alt="">  if ((event.widget == returnDate) || (event.widget == returnMonth)
+	  || (event.widget == returnYear) || (event.widget == travelDate)
+	  || (event.widget == travelMonth) || (event.widget == travelYear)) {
+	  if (isReturnDateSet() &amp;&amp; !validDates()) 
+	      status = new Status(IStatus.ERROR, &quot;not_used&quot;, 0, 
+	                &quot;Return date cannot be before the travel date&quot;, null);	                
+	  timeStatus = status;		
+      }
+
+      // Show the most serious error
+<img border="0" src="wizards_files/tag_7.gif" alt="">    applyToStatusLine(findMostSevere())
+      // ...
+}</pre>
+
+<h3>Navigation Buttons</h3>
+<p>Using the JFace wizard support we can easily manage the
+navigation buttons on the wizard pages. These buttons can be Finish and
+Cancel if the wizard has one page, otherwise each wizard page has Back,
+Next, Finish and Cancel. By default, Next is enabled for all but the
+last page and Back for all pages but the first. .</p>
+<p>For correct navigation we need to:</p>
+<ol>
+	<li>implement the <code>canFlipToNextPage</code> method on the
+	page to return true when the user has selected/entered all the required
+	information on the current page.</li>
+	<li>overwrite the <code>canFinish</code> method of of the wizard
+	to return true when the wizard can be completed</li>
+	<li>ensure that the methods from above are called at the right
+	moment to enable/disable the Next and Finish buttons</li>
+</ol>
+<p>We look at each of these steps in a little more detail.</p>
+<ol>
+	<li>
+	<p>To implement the canFlipToNextPage method for the first page of
+	our wizard, we first prevent the user from moving to the next page when
+	the page has any errors. When there are no errors, the destination and
+	departure fields are filled, the return date is set and a mode of
+	transport is selected, the user can move to the next page.</p>
+	<pre>public Boolean canFlipToNextPage(){
+   if (getErrorMessage() != null) return false;
+   if (isTextNonEmpty(fromText)&amp;&amp; isTextNonEmpty(toText) &amp;&amp; (planeButton.getSelection()
+	 || carButton.getSelection()) &amp;&amp; isReturnDateSet())
+        return true;
+    return false;
+}</pre></li>
+	<li>Overwriting the canFinish method on the wizard class is useful
+	when some fields or entire pages are optional. When we have all the
+	required information for the current path through the wizard, canFinish
+	should true and the wizard can be completed at any moment after this.</li>
+	<li>You can force the update of the navigation buttons. The right
+	moment for this depends on your problem and the implementation of
+	canFlipToNextPage and canFinish methods. If we have registered
+	listeners for all type of events that can affect the enabled/disabled
+	status of Next and Finish button, then at the end of the event
+	processing method we force the redraw of the buttons:<pre>public void handleEvent(Event event) {
+    //...
+    getWizard().getContainer().updateButtons();
+}</pre></li>
+
+</ol>
+
+
+<h2>Changing the Page Order</h2>
+<p>We can change the order of the wizard pages by overwriting the <code>getNextPage</code>
+method of any wizard page.Before leaving the page, we save in the model
+the values chosen by the user. In our example, depending on the choice
+of travel the user will next see either the page with flights or the
+page for travelling by car.</p>
+
+<pre>public IWizardPage getNextPage(){
+   saveDataToModel();		
+   if (planeButton.getSelection()) {
+       PlanePage page = ((HolidayWizard)getWizard()).planePage;
+<img border="0" src="wizards_files/tag_1.gif" alt="">     page.onEnterPage();
+       return page;
+   }
+   // Returns the next page depending on the selected button
+   if (carButton.getSelection()) { 
+	return ((HolidayWizard)getWizard()).carPage;
+   }
+   return null;
+}</pre>
+
+<h2>Initializing widgets on wizard pages</h2>
+<p>The widgets can be initialized based on constants, values
+available on the start of the wizard or other user choices. We look at
+each case more closely.</p>
+<ul>
+	<li>constants: the widgets can be initialized immediately after
+	their creation. In the sample, we initialize the travel date with
+	today's date.</li>
+	<li>values available at the start of the wizard.
+	<p><a name="Discount"></a>In our example, if the user starts the
+	wizard when a folder called Discounts is selected, he will get 10% off
+	the price of flights (You would want to get discounts this way,
+	wouldn't you?). To achieve this, we need to overwrite the <code>init</code>
+	method on the wizard class. If the parameter representing the selection
+	is the special folder, we know that we'll offer a discount so we cache
+	this information.</p>
+	<pre>public void init(IWorkbench workbench, IStructuredSelection selection) {
+   this.workbench = workbench;
+   this.selection = selection;
+   if (selection != null && !selection.isEmpty()) {
+      Object obj = selection.getFirstElement();
+      if (obj  instanceof IFolder) {
+          IFolder folder = (IFolder) obj;				
+          if (folder.getName().equals("Discounts"))
+              model.discounted = true;				
+          }
+      }
+}</pre>
+	<p>In our example, we initialize the model data based on the
+	selection field and use it when displaying the flight price, see <a
+		href="#getPrice">above</a> . In other examples, we might need to
+	initialize controls on the page with the selection values.The controls
+	are not created when the init method is called, but we can initialize
+	them as soon as they are created with the cached value.</p>
+	<p>For wizards which are started by defining a wizard contribution
+	(see <a href="#startWizard">Starting a wizard</a> section), the init
+	method is called by the platform, otherwise we need to call it
+	explicitly.</p>
+	</li>
+	<li>user choices</li>
+</ul>
+<p>We can initialize the values of some controls based on values for
+other controls as defined by the user at runtime. For example, in the
+CarPage we assign the value of the price field based on the rental
+company that was selected</p>
+<pre>public void handleEvent(Event e)
+{
+   if (e.widget == companyCombo) {
+     if (companyCombo.getSelectionIndex() &gt;=0)
+      priceText.setText(&quot;£&quot;+prices[companyCombo.getSelectionIndex()]);
+   }
+// ...
+}</pre>
+<p>In another example, the source widgets are on one page and the
+widgets whose values are initialized belong to subsequent page. Such is
+the case in our example, where the departure and destination from the
+first page is used to show.</p>
+
+<p>We define a method to do this initialization for the PlanePage,
+onEnterPage and we invoke this method when moving to the PlanePage, that
+is in the <a href="#initialize">getNextPage (<img border="0"
+	src="wizards_files/tag_1.gif" alt="">)</a> method for the first page.</p>
+<h2>Actions on Completion of the Wizard</h2>
+<p>To complete a wizard, the user can press either the Finish or the
+Cancel buttons. If the Cancel button is pressed, the <code>performCancel</code>
+method is called and you should overwrite this to cleanup any resources
+allocated while running the wizard. The real work is done in <code>performFinish</code>.
+In our case, this method is quite simple:</p>
+<pre>public boolean performFinish() 
+{
+    String summary = model.toString();
+    MessageDialog.openInformation(workbench.getActiveWorkbenchWindow().getShell(), 
+	"Holiday info", summary);
+    return true;
+}</pre>
+
+<p>If possible, it is always best to subclass from an existing
+wizard or wizard page which performs a similar task. A good place to
+look for such wizards for subclassing are <code>org.eclipse.ui.newresource</code>
+package which provides standard wizards for creating files, folders, and
+projects in the workspace and <code>org.eclipse.ui.wizards.datatransfer</code>
+package for the standard Import and Export wizards for moving resources
+into and out of the workspace. &nbsp;</p>
+<p>For example, if we want to save the user choices in a file we
+would have the first page inherit from the class <code>org.eclipse.ui.dialogs.WizardNewFileCreationPage</code>,
+which is the standard main page for a wizard that creates a file
+resource. We would inherit the actual file creation from the parent
+class and could overwrite one of its method getInitialContents() to
+return the user choices to be saved in the file.</p>
+
+<p>The task to be completed at the end of the wizard could be a
+complex operation that modifies many workspace resources, files, classes
+or projects. This sort of operation could take a relatively long time.
+To keep the workbench responsive to user input or to give the user the
+possibility to cancel the operation we might want to run it in a
+different thread. To achieve all these, we create a runnable which
+performs the task and runs it in the context of the container of the
+wizard.</p>
+<pre>getContainer().run(forkable, canceleable, runnable);</pre>
+<p>For more details on this subject see <a
+	href="http://help.eclipse.org/help33/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/operation/package-summary.html"
+	target="_blank"> JFace operations documentation</a>.</p>
+<h2><a name="startWizard"></a>Starting a Wizard</h2>
+<p>You can start a wizard either by defining a wizard contribution
+to the workbench or explicitly in your code. We will look at each of
+these methods in turn.</p>
+<h3>Defining a wizard contribution</h3>
+<p>You can contribute to the extension points for wizards that
+create new resources, import or export resources. When you select the
+new, import, or export menu or when you press the new wizard button, the
+workbench uses a wizard selection dialog to display all the wizards that
+have been contributed for that particular extension point.&nbsp;</p>
+<p><a name="NewMenu"></a></p>
+<center>
+<p><img border="0" src="wizards_files/newWizard.gif" alt=""></p>
+Figure 5. Starting the wizard from the New</center>
+<p>In our sample, we contribute to the new wizard extension point.
+The relevant fragment from plugin.xml is :</p>
+<pre>&lt;extension id=&quot;com.xyz.article.wizards&quot;
+    name=&quot;Holiday&quot;
+   point=&quot;org.eclipse.ui.newWizards&quot;&gt;
+  &lt;category
+         name=&quot;Article Wizards&quot;
+         id=&quot;com.xyz.article.wizards.category1&quot;&gt;
+   &lt;/category&gt;
+   &lt;wizard
+         name=&quot;Holiday Document&quot;
+         icon=&quot;icons/create.gif&quot;
+         category=&quot;com.xyz.article.wizards.category1&quot;
+<img border="0" src="wizards_files/tag_1.gif" alt="">    class=&quot;com.xyz.article.wizards.HolidayDocumentWizard&quot;
+         id=&quot;com.xyz.article.wizards.wizard1&quot;&gt;
+        &lt;description&gt;
+               Creates a holiday document
+        &lt;/description&gt;
+   &lt;/wizard&gt;
+&lt;/extension&gt;</pre>
+<p>We define the category to which we add our wizard, the name,
+description and icon that will be used. The most important entry in the
+extension point is the class field( <img border="0"
+	src="wizards_files/tag_1.gif" alt="">) where we give the name of
+our wizard class. A class used in this way must implement the (empty) <code>org.eclipse.ui.INewWizard</code>
+interface. This is all we need to do in this case. Some details are
+handled by the workbench as we will see below.</p>
+
+<h2>Starting the Wizard Explicitly</h2>
+<p>You may want to launch your wizard as a result of some action
+that you have defined. Typically you use extension points that
+contribute to various menus and toolbars in the workbench and want the
+wizard to be started when the user interacts with these, for example
+when pressing a button or selecting a menu option.</p>
+<p>In our example, we use the popupMenu extension point for a folder
+to start the wizard.</p>
+<p><a name="PopupMenu"></a></p>
+<center>
+<p><img border="0" src="wizards_files/popup.gif" alt=""></p>
+<p>Figure 6. Starting the wizard from the popup menu</p>
+</center>
+<p>In the plugin.xml we have:</p>
+<pre>        &lt;extension point=&quot;org.eclipse.ui.popupMenus&quot;&gt;
+                &lt;objectContribution
+<img border="0" src="wizards_files/tag_2.gif" alt="">              objectClass=&quot;org.eclipse.core.resources.IFolder&quot;
+                    id=&quot;com.xyz.article.wizards.popup1&quot;&gt;
+               &lt;action
+                        label=&quot;Create holiday document&quot;
+                        icon=&quot;icons/create.gif&quot;
+<img border="0" src="wizards_files/tag_3.gif" alt="">                   class=&quot;com.xyz.article.wizards.CreateWizardAction&quot;
+                        id=&quot;com.xyz.article.wizards.action1&quot;&gt;
+               &lt;/action&gt;
+               &lt;/objectContribution&gt;
+        &lt;/extension&gt;</pre>
+<p>The objectClass entry (<img border="0"
+	src="wizards_files/tag_2.gif" alt="">) defines the type of
+objects to which this popupMenu will be added to, in our case a Folder.
+The real work is done by the action class defined on <code><img
+	border="0" src="wizards_files/tag_3.gif" alt=""></code>. Its run method
+is executed when the user selects this new item from the popup menu of a
+folder. The other two methods on the action class, <code>setActivePart</code>
+and <code>selectionChanged</code> cache the workbench part and the
+selection fields respectively for use when the wizard is started, see <img
+	border="0" src="wizards_files/tag_4.gif" alt=""> below. For more
+details on the popup menu extension point see the documentation.</p>
+<p>When you are launching your own wizard, you need to wrap the
+wizard in a <a
+	href="http://dev.eclipse.org/help20/content/help:/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/wizard/WizardDialog.html"
+	target="_blank"><code>org.eclipse.jface.wizard.WizardDialog</code></a>.
+A WizardDialog is a container that can host a wizard and display wizard
+pages. It has a standard layout: an area at the top containing the
+wizard's title, description, and image; the actual wizard page appears
+in the middle; below it is a progress indicator; and at the bottom is an
+area with a message line and a button bar containing Next, Back, Finish,
+Cancel, and Help buttons.</p>
+<p>The relevant code to start the wizard is:</p>
+<pre>    // Instantiates and initializes the wizard
+    HolidayWizard wizard = new HolidayWizard();
+<img border="0" src="wizards_files/tag_4.gif" alt="">  wizard.init(part.getSite().getWorkbenchWindow().getWorkbench(),
+            (IStructuredSelection)selection);
+    // Instantiates the wizard container with the wizard and opens it
+    WizardDialog dialog = new WizardDialog(shell, wizard);
+    dialog.create();
+    dialog.open();</pre>
+<h2>Resources</h2>
+<p>We have seen how to implement a wizard, initialize its contents,
+and perform actions on its completion. For further information about
+wizards and controls, see the following resources:</p>
+<p><a
+	href="http://dev.eclipse.org/help20/content/help:/org.eclipse.platform.doc.isv/guide/swt.htm"
+	target="_blank">Eclipse Platform Plug-in Developer Guide: Standard
+Widget Toolkit (SWT)</a><br>
+<a
+	href="http://dev.eclipse.org/help20/content/help:/org.eclipse.platform.doc.isv/guide/jface.htm"
+	target="_blank">Eclipse Platform Plug-in Developer Guide: JFace UI
+Framework</a><br>
+<a
+	href="http://www.eclipse.org/articles/article.php?file=Article-Understanding-Layouts/index.html"
+	target="_blank">Article: Understanding Layouts in SWT (Revised for
+2.0)</a></p>
+</div>
+</body>
+</html>
diff --git a/Article-JFaceWizards/info.xml b/Article-JFaceWizards/info.xml
new file mode 100644
index 0000000..8dc5ca6
--- /dev/null
+++ b/Article-JFaceWizards/info.xml
@@ -0,0 +1,10 @@
+<article>
+	<bug id="203343"/>
+	<project id="eclipse">
+		<release>2.0</release>
+		<release>3.0</release>
+		<release>3.1</release>
+		<release>3.2</release>
+		<release>3.3</release>
+	</project>
+</article>
\ No newline at end of file
diff --git a/Article-JFace Wizards/wizardArticle.html b/Article-JFaceWizards/wizardArticle.html
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizardArticle.html
rename to Article-JFaceWizards/wizardArticle.html
diff --git a/Article-JFace Wizards/wizards_files/Idea.jpg b/Article-JFaceWizards/wizards_files/Idea.jpg
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/Idea.jpg
rename to Article-JFaceWizards/wizards_files/Idea.jpg
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/car.gif b/Article-JFaceWizards/wizards_files/car.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/car.gif
rename to Article-JFaceWizards/wizards_files/car.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/error.gif b/Article-JFaceWizards/wizards_files/error.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/error.gif
rename to Article-JFaceWizards/wizards_files/error.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/linux_only.gif b/Article-JFaceWizards/wizards_files/linux_only.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/linux_only.gif
rename to Article-JFaceWizards/wizards_files/linux_only.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/mainPage.gif b/Article-JFaceWizards/wizards_files/mainPage.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/mainPage.gif
rename to Article-JFaceWizards/wizards_files/mainPage.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/newWizard.gif b/Article-JFaceWizards/wizards_files/newWizard.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/newWizard.gif
rename to Article-JFaceWizards/wizards_files/newWizard.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/plane.gif b/Article-JFaceWizards/wizards_files/plane.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/plane.gif
rename to Article-JFaceWizards/wizards_files/plane.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/popup.gif b/Article-JFaceWizards/wizards_files/popup.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/popup.gif
rename to Article-JFaceWizards/wizards_files/popup.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_1.gif b/Article-JFaceWizards/wizards_files/tag_1.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/tag_1.gif
rename to Article-JFaceWizards/wizards_files/tag_1.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_2.gif b/Article-JFaceWizards/wizards_files/tag_2.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/tag_2.gif
rename to Article-JFaceWizards/wizards_files/tag_2.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_3.gif b/Article-JFaceWizards/wizards_files/tag_3.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/tag_3.gif
rename to Article-JFaceWizards/wizards_files/tag_3.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_4.gif b/Article-JFaceWizards/wizards_files/tag_4.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/tag_4.gif
rename to Article-JFaceWizards/wizards_files/tag_4.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_5.gif b/Article-JFaceWizards/wizards_files/tag_5.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/tag_5.gif
rename to Article-JFaceWizards/wizards_files/tag_5.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_6.gif b/Article-JFaceWizards/wizards_files/tag_6.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/tag_6.gif
rename to Article-JFaceWizards/wizards_files/tag_6.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tag_7.gif b/Article-JFaceWizards/wizards_files/tag_7.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/tag_7.gif
rename to Article-JFaceWizards/wizards_files/tag_7.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tip.gif b/Article-JFaceWizards/wizards_files/tip.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/tip.gif
rename to Article-JFaceWizards/wizards_files/tip.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/tryit.gif b/Article-JFaceWizards/wizards_files/tryit.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/tryit.gif
rename to Article-JFaceWizards/wizards_files/tryit.gif
Binary files differ
diff --git a/Article-JFace Wizards/wizards_files/win_only.gif b/Article-JFaceWizards/wizards_files/win_only.gif
old mode 100644
new mode 100755
similarity index 100%
rename from Article-JFace Wizards/wizards_files/win_only.gif
rename to Article-JFaceWizards/wizards_files/win_only.gif
Binary files differ