Frames | No Frames |
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.5 2005/11/16 15:58:41 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: 52: import javax.swing.BorderFactory; 53: import javax.swing.JButton; 54: import javax.swing.JDialog; 55: import javax.swing.JFrame; 56: import javax.swing.JPanel; 57: 58: /** 59: * A dialog that presents the user with a sequence of steps for completing a task. The dialog 60: * contains "Next" and "Previous" buttons, allowing the user to navigate through the task. 61: * <P> 62: * When the user backs up by one or more steps, the dialog keeps the completed steps so that 63: * they can be reused if the user doesn't change anything - this handles the cases where the user 64: * backs up a few steps just to review what has been completed. 65: * <p> 66: * But if the user changes some options in an earlier step, then the dialog may have to discard 67: * the later steps and have them repeated. 68: * <P> 69: * THIS CLASS IS NOT WORKING CORRECTLY YET. 70: * 71: * 72: * @author David Gilbert 73: */ 74: public class WizardDialog extends JDialog implements ActionListener { 75: 76: /** The end result of the wizard sequence. */ 77: private Object result; 78: 79: /** The current step in the wizard process (starting at step zero). */ 80: private int step; 81: 82: /** A reference to the current panel. */ 83: private WizardPanel currentPanel; 84: 85: /** A list of references to the panels the user has already seen - used for navigating through 86: the steps that have already been completed. */ 87: private java.util.List panels; 88: 89: /** A handy reference to the "previous" button. */ 90: private JButton previousButton; 91: 92: /** A handy reference to the "next" button. */ 93: private JButton nextButton; 94: 95: /** A handy reference to the "finish" button. */ 96: private JButton finishButton; 97: 98: /** A handy reference to the "help" button. */ 99: private JButton helpButton; 100: 101: /** 102: * Standard constructor - builds and returns a new WizardDialog. 103: * 104: * @param owner the owner. 105: * @param modal modal? 106: * @param title the title. 107: * @param firstPanel the first panel. 108: */ 109: public WizardDialog(final JDialog owner, final boolean modal, 110: final String title, final WizardPanel firstPanel) { 111: 112: super(owner, title + " : step 1", modal); 113: this.result = null; 114: this.currentPanel = firstPanel; 115: this.step = 0; 116: this.panels = new ArrayList(); 117: this.panels.add(firstPanel); 118: setContentPane(createContent()); 119: 120: } 121: 122: /** 123: * Standard constructor - builds a new WizardDialog owned by the specified JFrame. 124: * 125: * @param owner the owner. 126: * @param modal modal? 127: * @param title the title. 128: * @param firstPanel the first panel. 129: */ 130: public WizardDialog(final JFrame owner, final boolean modal, 131: final String title, final WizardPanel firstPanel) { 132: 133: super(owner, title + " : step 1", modal); 134: this.result = null; 135: this.currentPanel = firstPanel; 136: this.step = 0; 137: this.panels = new ArrayList(); 138: this.panels.add(firstPanel); 139: setContentPane(createContent()); 140: } 141: 142: /** 143: * Returns the result of the wizard sequence. 144: * 145: * @return the result. 146: */ 147: public Object getResult() { 148: return this.result; 149: } 150: 151: /** 152: * Returns the total number of steps in the wizard sequence, if this number is known. Otherwise 153: * this method returns zero. Subclasses should override this method unless the number of steps 154: * is not known. 155: * 156: * @return the number of steps. 157: */ 158: public int getStepCount() { 159: return 0; 160: } 161: 162: /** 163: * Returns true if it is possible to back up to the previous panel, and false otherwise. 164: * 165: * @return boolean. 166: */ 167: public boolean canDoPreviousPanel() { 168: return (this.step > 0); 169: } 170: 171: /** 172: * Returns true if there is a 'next' panel, and false otherwise. 173: * 174: * @return boolean. 175: */ 176: public boolean canDoNextPanel() { 177: return this.currentPanel.hasNextPanel(); 178: } 179: 180: /** 181: * Returns true if it is possible to finish the sequence at this point (possibly with defaults 182: * for the remaining entries). 183: * 184: * @return boolean. 185: */ 186: public boolean canFinish() { 187: return this.currentPanel.canFinish(); 188: } 189: 190: /** 191: * Returns the panel for the specified step (steps are numbered from zero). 192: * 193: * @param step the current step. 194: * 195: * @return the panel. 196: */ 197: public WizardPanel getWizardPanel(final int step) { 198: if (step < this.panels.size()) { 199: return (WizardPanel) this.panels.get(step); 200: } 201: else { 202: return null; 203: } 204: } 205: 206: /** 207: * Handles events. 208: * 209: * @param event the event. 210: */ 211: public void actionPerformed(final ActionEvent event) { 212: final String command = event.getActionCommand(); 213: if (command.equals("nextButton")) { 214: next(); 215: } 216: else if (command.equals("previousButton")) { 217: previous(); 218: } 219: else if (command.equals("finishButton")) { 220: finish(); 221: } 222: } 223: 224: /** 225: * Handles a click on the "previous" button, by displaying the previous panel in the sequence. 226: */ 227: public void previous() { 228: if (this.step > 0) { 229: final WizardPanel previousPanel = getWizardPanel(this.step - 1); 230: // tell the panel that we are returning 231: previousPanel.returnFromLaterStep(); 232: final Container content = getContentPane(); 233: content.remove(this.currentPanel); 234: content.add(previousPanel); 235: this.step = this.step - 1; 236: this.currentPanel = previousPanel; 237: setTitle("Step " + (this.step + 1)); 238: enableButtons(); 239: pack(); 240: } 241: } 242: 243: /** 244: * Displays the next step in the wizard sequence. 245: */ 246: public void next() { 247: 248: WizardPanel nextPanel = getWizardPanel(this.step + 1); 249: if (nextPanel != null) { 250: if (!this.currentPanel.canRedisplayNextPanel()) { 251: nextPanel = this.currentPanel.getNextPanel(); 252: } 253: } 254: else { 255: nextPanel = this.currentPanel.getNextPanel(); 256: } 257: 258: this.step = this.step + 1; 259: if (this.step < this.panels.size()) { 260: this.panels.set(this.step, nextPanel); 261: } 262: else { 263: this.panels.add(nextPanel); 264: } 265: 266: final Container content = getContentPane(); 267: content.remove(this.currentPanel); 268: content.add(nextPanel); 269: 270: this.currentPanel = nextPanel; 271: setTitle("Step " + (this.step + 1)); 272: enableButtons(); 273: pack(); 274: 275: } 276: 277: /** 278: * Finishes the wizard. 279: */ 280: public void finish() { 281: this.result = this.currentPanel.getResult(); 282: setVisible(false); 283: } 284: 285: /** 286: * Enables/disables the buttons according to the current step. A good idea would be to ask the 287: * panels to return the status... 288: */ 289: private void enableButtons() { 290: this.previousButton.setEnabled(this.step > 0); 291: this.nextButton.setEnabled(canDoNextPanel()); 292: this.finishButton.setEnabled(canFinish()); 293: this.helpButton.setEnabled(false); 294: } 295: 296: /** 297: * Checks, whether the user cancelled the dialog. 298: * 299: * @return false. 300: */ 301: public boolean isCancelled() { 302: return false; 303: } 304: 305: /** 306: * Creates a panel containing the user interface for the dialog. 307: * 308: * @return the panel. 309: */ 310: public JPanel createContent() { 311: 312: final JPanel content = new JPanel(new BorderLayout()); 313: content.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); 314: content.add((JPanel) this.panels.get(0)); 315: final L1R3ButtonPanel buttons = new L1R3ButtonPanel("Help", "Previous", "Next", "Finish"); 316: 317: this.helpButton = buttons.getLeftButton(); 318: this.helpButton.setEnabled(false); 319: 320: this.previousButton = buttons.getRightButton1(); 321: this.previousButton.setActionCommand("previousButton"); 322: this.previousButton.addActionListener(this); 323: this.previousButton.setEnabled(false); 324: 325: this.nextButton = buttons.getRightButton2(); 326: this.nextButton.setActionCommand("nextButton"); 327: this.nextButton.addActionListener(this); 328: this.nextButton.setEnabled(true); 329: 330: this.finishButton = buttons.getRightButton3(); 331: this.finishButton.setActionCommand("finishButton"); 332: this.finishButton.addActionListener(this); 333: this.finishButton.setEnabled(false); 334: 335: buttons.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0)); 336: content.add(buttons, BorderLayout.SOUTH); 337: 338: return content; 339: } 340: 341: }