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.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: }