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 © 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>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 "Get price" 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("");
+ addPage(planePage);
+ carPage = new CarPage("");
+ 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
+ "yes" or "no" 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 "Get price" 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() >0) {
+ if (((HolidayWizard)getWizard()).model.discounted)
+ price *= discountRate;
+ MessageDialog.openInformation(this.getShell(),"", "Flight price "+ 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, "not_used", 0, "", 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, "not_used", 0,
+ "Departure and destination cannot be the same", 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() && !validDates())
+ status = new Status(IStatus.ERROR, "not_used", 0,
+ "Return date cannot be before the travel date", 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)&& isTextNonEmpty(toText) && (planeButton.getSelection()
+ || carButton.getSelection()) && 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() >=0)
+ priceText.setText("£"+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. </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. </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><extension id="com.xyz.article.wizards"
+ name="Holiday"
+ point="org.eclipse.ui.newWizards">
+ <category
+ name="Article Wizards"
+ id="com.xyz.article.wizards.category1">
+ </category>
+ <wizard
+ name="Holiday Document"
+ icon="icons/create.gif"
+ category="com.xyz.article.wizards.category1"
+<img border="0" src="wizards_files/tag_1.gif" alt=""> class="com.xyz.article.wizards.HolidayDocumentWizard"
+ id="com.xyz.article.wizards.wizard1">
+ <description>
+ Creates a holiday document
+ </description>
+ </wizard>
+</extension></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> <extension point="org.eclipse.ui.popupMenus">
+ <objectContribution
+<img border="0" src="wizards_files/tag_2.gif" alt=""> objectClass="org.eclipse.core.resources.IFolder"
+ id="com.xyz.article.wizards.popup1">
+ <action
+ label="Create holiday document"
+ icon="icons/create.gif"
+<img border="0" src="wizards_files/tag_3.gif" alt=""> class="com.xyz.article.wizards.CreateWizardAction"
+ id="com.xyz.article.wizards.action1">
+ </action>
+ </objectContribution>
+ </extension></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