Source for org.jfree.ui.WizardDialog

   1: /* ========================================================================
   2:  * JCommon : a free general purpose class library for the Java(tm) platform
   3:  * ========================================================================
   4:  *
   5:  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
   6:  * 
   7:  * Project Info:  http://www.jfree.org/jcommon/index.html
   8:  *
   9:  * This library is free software; you can redistribute it and/or modify it 
  10:  * under the terms of the GNU Lesser General Public License as published by 
  11:  * the Free Software Foundation; either version 2.1 of the License, or 
  12:  * (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but 
  15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  16:  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
  17:  * License for more details.
  18:  *
  19:  * You should have received a copy of the GNU Lesser General Public
  20:  * License along with this library; if not, write to the Free Software
  21:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
  22:  * USA.  
  23:  *
  24:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
  25:  * in the United States and other countries.]
  26:  * 
  27:  * -----------------
  28:  * WizardDialog.java
  29:  * -----------------
  30:  * (C) Copyright 2000-2004, by Object Refinery Limited.
  31:  *
  32:  * Original Author:  David Gilbert (for Object Refinery Limited);
  33:  * Contributor(s):   -;
  34:  *
  35:  * $Id: WizardDialog.java,v 1.6 2007/11/02 17:50:36 taqua Exp $
  36:  *
  37:  * Changes (from 26-Oct-2001)
  38:  * --------------------------
  39:  * 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
  40:  * 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
  41:  *
  42:  */
  43: 
  44: package org.jfree.ui;
  45: 
  46: import java.awt.BorderLayout;
  47: import java.awt.Container;
  48: import java.awt.event.ActionEvent;
  49: import java.awt.event.ActionListener;
  50: import java.util.ArrayList;
  51: import javax.swing.BorderFactory;
  52: import javax.swing.JButton;
  53: import javax.swing.JDialog;
  54: import javax.swing.JFrame;
  55: import javax.swing.JPanel;
  56: 
  57: /**
  58:  * A dialog that presents the user with a sequence of steps for completing a task.  The dialog
  59:  * contains "Next" and "Previous" buttons, allowing the user to navigate through the task.
  60:  * <P>
  61:  * When the user backs up by one or more steps, the dialog keeps the completed steps so that
  62:  * they can be reused if the user doesn't change anything - this handles the cases where the user
  63:  * backs up a few steps just to review what has been completed.
  64:  * <p>
  65:  * But if the user changes some options in an earlier step, then the dialog may have to discard
  66:  * the later steps and have them repeated.
  67:  * <P>
  68:  * THIS CLASS IS NOT WORKING CORRECTLY YET.
  69:  *
  70:  *
  71:  * @author David Gilbert
  72:  */
  73: public class WizardDialog extends JDialog implements ActionListener {
  74: 
  75:     /** The end result of the wizard sequence. */
  76:     private Object result;
  77: 
  78:     /** The current step in the wizard process (starting at step zero). */
  79:     private int step;
  80: 
  81:     /** A reference to the current panel. */
  82:     private WizardPanel currentPanel;
  83: 
  84:     /** A list of references to the panels the user has already seen - used for navigating through
  85:         the steps that have already been completed. */
  86:     private java.util.List panels;
  87: 
  88:     /** A handy reference to the "previous" button. */
  89:     private JButton previousButton;
  90: 
  91:     /** A handy reference to the "next" button. */
  92:     private JButton nextButton;
  93: 
  94:     /** A handy reference to the "finish" button. */
  95:     private JButton finishButton;
  96: 
  97:     /** A handy reference to the "help" button. */
  98:     private JButton helpButton;
  99: 
 100:     /**
 101:      * Standard constructor - builds and returns a new WizardDialog.
 102:      *
 103:      * @param owner  the owner.
 104:      * @param modal  modal?
 105:      * @param title  the title.
 106:      * @param firstPanel  the first panel.
 107:      */
 108:     public WizardDialog(final JDialog owner, final boolean modal,
 109:                         final String title, final WizardPanel firstPanel) {
 110: 
 111:         super(owner, title + " : step 1", modal);
 112:         this.result = null;
 113:         this.currentPanel = firstPanel;
 114:         this.step = 0;
 115:         this.panels = new ArrayList();
 116:         this.panels.add(firstPanel);
 117:         setContentPane(createContent());
 118: 
 119:     }
 120: 
 121:     /**
 122:      * Standard constructor - builds a new WizardDialog owned by the specified JFrame.
 123:      *
 124:      * @param owner  the owner.
 125:      * @param modal  modal?
 126:      * @param title  the title.
 127:      * @param firstPanel  the first panel.
 128:      */
 129:     public WizardDialog(final JFrame owner, final boolean modal,
 130:                         final String title, final WizardPanel firstPanel) {
 131: 
 132:         super(owner, title + " : step 1", modal);
 133:         this.result = null;
 134:         this.currentPanel = firstPanel;
 135:         this.step = 0;
 136:         this.panels = new ArrayList();
 137:         this.panels.add(firstPanel);
 138:         setContentPane(createContent());
 139:     }
 140: 
 141:     /**
 142:      * Returns the result of the wizard sequence.
 143:      *
 144:      * @return the result.
 145:      */
 146:     public Object getResult() {
 147:         return this.result;
 148:     }
 149: 
 150:     /**
 151:      * Returns the total number of steps in the wizard sequence, if this number is known.  Otherwise
 152:      * this method returns zero.  Subclasses should override this method unless the number of steps
 153:      * is not known.
 154:      *
 155:      * @return the number of steps.
 156:      */
 157:     public int getStepCount() {
 158:         return 0;
 159:     }
 160: 
 161:     /**
 162:      * Returns true if it is possible to back up to the previous panel, and false otherwise.
 163:      *
 164:      * @return boolean.
 165:      */
 166:     public boolean canDoPreviousPanel() {
 167:         return (this.step > 0);
 168:     }
 169: 
 170:     /**
 171:      * Returns true if there is a 'next' panel, and false otherwise.
 172:      *
 173:      * @return boolean.
 174:      */
 175:     public boolean canDoNextPanel() {
 176:         return this.currentPanel.hasNextPanel();
 177:     }
 178: 
 179:     /**
 180:      * Returns true if it is possible to finish the sequence at this point (possibly with defaults
 181:      * for the remaining entries).
 182:      *
 183:      * @return boolean.
 184:      */
 185:     public boolean canFinish() {
 186:         return this.currentPanel.canFinish();
 187:     }
 188: 
 189:     /**
 190:      * Returns the panel for the specified step (steps are numbered from zero).
 191:      *
 192:      * @param step  the current step.
 193:      *
 194:      * @return the panel.
 195:      */
 196:     public WizardPanel getWizardPanel(final int step) {
 197:         if (step < this.panels.size()) {
 198:             return (WizardPanel) this.panels.get(step);
 199:         }
 200:         else {
 201:             return null;
 202:         }
 203:     }
 204: 
 205:     /**
 206:      * Handles events.
 207:      *
 208:      * @param event  the event.
 209:      */
 210:     public void actionPerformed(final ActionEvent event) {
 211:         final String command = event.getActionCommand();
 212:         if (command.equals("nextButton")) {
 213:             next();
 214:         }
 215:         else if (command.equals("previousButton")) {
 216:             previous();
 217:         }
 218:         else if (command.equals("finishButton")) {
 219:             finish();
 220:         }
 221:     }
 222: 
 223:     /**
 224:      * Handles a click on the "previous" button, by displaying the previous panel in the sequence.
 225:      */
 226:     public void previous() {
 227:         if (this.step > 0) {
 228:             final WizardPanel previousPanel = getWizardPanel(this.step - 1);
 229:             // tell the panel that we are returning
 230:             previousPanel.returnFromLaterStep();
 231:             final Container content = getContentPane();
 232:             content.remove(this.currentPanel);
 233:             content.add(previousPanel);
 234:             this.step = this.step - 1;
 235:             this.currentPanel = previousPanel;
 236:             setTitle("Step " + (this.step + 1));
 237:             enableButtons();
 238:             pack();
 239:         }
 240:     }
 241: 
 242:     /**
 243:      * Displays the next step in the wizard sequence.
 244:      */
 245:     public void next() {
 246: 
 247:         WizardPanel nextPanel = getWizardPanel(this.step + 1);
 248:         if (nextPanel != null) {
 249:             if (!this.currentPanel.canRedisplayNextPanel()) {
 250:                 nextPanel = this.currentPanel.getNextPanel();
 251:             }
 252:         }
 253:         else {
 254:             nextPanel = this.currentPanel.getNextPanel();
 255:         }
 256: 
 257:         this.step = this.step + 1;
 258:         if (this.step < this.panels.size()) {
 259:             this.panels.set(this.step, nextPanel);
 260:         }
 261:         else {
 262:             this.panels.add(nextPanel);
 263:         }
 264: 
 265:         final Container content = getContentPane();
 266:         content.remove(this.currentPanel);
 267:         content.add(nextPanel);
 268: 
 269:         this.currentPanel = nextPanel;
 270:         setTitle("Step " + (this.step + 1));
 271:         enableButtons();
 272:         pack();
 273: 
 274:     }
 275: 
 276:     /**
 277:      * Finishes the wizard.
 278:      */
 279:     public void finish() {
 280:         this.result = this.currentPanel.getResult();
 281:         setVisible(false);
 282:     }
 283: 
 284:     /**
 285:      * Enables/disables the buttons according to the current step.  A good idea would be to ask the
 286:      * panels to return the status...
 287:      */
 288:     private void enableButtons() {
 289:         this.previousButton.setEnabled(this.step > 0);
 290:         this.nextButton.setEnabled(canDoNextPanel());
 291:         this.finishButton.setEnabled(canFinish());
 292:         this.helpButton.setEnabled(false);
 293:     }
 294: 
 295:     /**
 296:      * Checks, whether the user cancelled the dialog.
 297:      *
 298:      * @return false.
 299:      */
 300:     public boolean isCancelled() {
 301:         return false;
 302:     }
 303: 
 304:     /**
 305:      * Creates a panel containing the user interface for the dialog.
 306:      *
 307:      * @return the panel.
 308:      */
 309:     public JPanel createContent() {
 310: 
 311:         final JPanel content = new JPanel(new BorderLayout());
 312:         content.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
 313:         content.add((JPanel) this.panels.get(0));
 314:         final L1R3ButtonPanel buttons = new L1R3ButtonPanel("Help", "Previous", "Next", "Finish");
 315: 
 316:         this.helpButton = buttons.getLeftButton();
 317:         this.helpButton.setEnabled(false);
 318: 
 319:         this.previousButton = buttons.getRightButton1();
 320:         this.previousButton.setActionCommand("previousButton");
 321:         this.previousButton.addActionListener(this);
 322:         this.previousButton.setEnabled(false);
 323: 
 324:         this.nextButton = buttons.getRightButton2();
 325:         this.nextButton.setActionCommand("nextButton");
 326:         this.nextButton.addActionListener(this);
 327:         this.nextButton.setEnabled(true);
 328: 
 329:         this.finishButton = buttons.getRightButton3();
 330:         this.finishButton.setActionCommand("finishButton");
 331:         this.finishButton.addActionListener(this);
 332:         this.finishButton.setEnabled(false);
 333: 
 334:         buttons.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
 335:         content.add(buttons, BorderLayout.SOUTH);
 336: 
 337:         return content;
 338:     }
 339: 
 340: }