/* This file is part of JFLICKS. JFLICKS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. JFLICKS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with JFLICKS. If not, see <http://www.gnu.org/licenses/>. */ package org.jflicks.wizard; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Map; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import org.jflicks.util.ColumnPanel; import org.jflicks.util.RowPanel; /** * A wizard performs based upon it's supplied WizardPanelProvider instance. * Users create (extend) the WizardPanelProvider to create the desired * panels and to then create the proper edited data in a Map instance. * * @author Doug Barnum * @version 1.0 */ public class Wizard extends JPanel implements ActionListener, Wizardable, WizardListener { private ArrayList<WizardListener> wizardList = new ArrayList<WizardListener>(); private WizardPanelProvider wizardPanelProvider; private JLabel[] stepLabels; private JButton previousButton; private JButton nextButton; private JButton finishButton; private JButton cancelButton; private int panelIndex; private int panelCount; private JPanel currentPanel; private Map map; /** * Create a wizard based upon the given WizardPanelProvider. * * @param wpp A given WizardPanelProvider instance. */ public Wizard(WizardPanelProvider wpp) { setPanelIndex(0); setPanelCount(0); if (wpp != null) { wpp.addWizardListener(this); setWizardPanelProvider(wpp); String[] descArray = wpp.getPanelDescriptions(); String[] idArray = wpp.getPanelIds(); if ((descArray != null) && (descArray.length > 0)) { setPanelCount(descArray.length); JLabel[] labels = new JLabel[descArray.length + 1]; for (int i = 0; i < descArray.length; i++) { labels[i] = new JLabel((i + 1) + ". " + descArray[i]); } labels[descArray.length] = new JLabel(""); setStepLabels(labels); ColumnPanel labelCP = new ColumnPanel("Steps", labels.length - 1, labels); setPreviousButton(new JButton("Prev")); getPreviousButton().addActionListener(this); setNextButton(new JButton("Next")); getNextButton().addActionListener(this); setFinishButton(new JButton("Finish")); getFinishButton().addActionListener(this); setCancelButton(new JButton("Cancel")); getCancelButton().addActionListener(this); RowPanel buttonRP = new RowPanel( getPreviousButton(), getNextButton(), getFinishButton(), getCancelButton()); JPanel first = wpp.createPanel(idArray[0]); ColumnPanel stepPanel = new ColumnPanel(descArray[0], 0, first); setCurrentPanel(stepPanel); setLayout(new BorderLayout(4, 4)); add(BorderLayout.WEST, labelCP); add(BorderLayout.CENTER, stepPanel); add(BorderLayout.SOUTH, buttonRP); makeState(); Dimension d = wpp.getPreferredSize(); if (d != null) { setPreferredSize(new Dimension(d)); } } } } /** * Convenience method to access the WizardPanelProvider title property. * * @return The WizardPanelProvider title property. */ public String getTitle() { String result = null; WizardPanelProvider wpp = getWizardPanelProvider(); if (wpp != null) { result = wpp.getTitle(); } return (result); } /** * {@inheritDoc} */ public void addWizardListener(WizardListener l) { wizardList.add(l); } /** * {@inheritDoc} */ public void removeWizardListener(WizardListener l) { wizardList.remove(l); } private void fireEvent(int type) { WizardEvent we = new WizardEvent(this, type); processWizardEvent(we); } protected synchronized void processWizardEvent(WizardEvent event) { for (int i = 0; i < wizardList.size(); i++) { WizardListener l = wizardList.get(i); l.stateChanged(event); } } private WizardPanelProvider getWizardPanelProvider() { return (wizardPanelProvider); } private void setWizardPanelProvider(WizardPanelProvider wpp) { wizardPanelProvider = wpp; } private JLabel[] getStepLabels() { return (stepLabels); } private void setStepLabels(JLabel[] array) { stepLabels = array; } private JButton getPreviousButton() { return (previousButton); } private void setPreviousButton(JButton b) { previousButton = b; } private JButton getNextButton() { return (nextButton); } private void setNextButton(JButton b) { nextButton = b; } private JButton getFinishButton() { return (finishButton); } private void setFinishButton(JButton b) { finishButton = b; } private JButton getCancelButton() { return (cancelButton); } private void setCancelButton(JButton b) { cancelButton = b; } /** * Get the map. * * @return a Map instance. */ public Map getMap() { return (map); } private void setMap(Map m) { map = m; } private JPanel getCurrentPanel() { return (currentPanel); } private void setCurrentPanel(JPanel p) { currentPanel = p; } private int getPanelCount() { return (panelCount); } private void setPanelCount(int i) { panelCount = i; } private int getPanelIndex() { return (panelIndex); } private void setPanelIndex(int i) { panelIndex = i; } private void incrPanelIndex() { setPanelIndex(getPanelIndex() + 1); if (getPanelIndex() == getPanelCount()) { setPanelIndex(getPanelCount() - 1); } } private void decrPanelIndex() { setPanelIndex(getPanelIndex() - 1); if (getPanelIndex() < 0) { setPanelIndex(0); } } /** * React to the button presses. * * @param e The given ActionEvent instance. */ public void actionPerformed(ActionEvent e) { if (e.getSource() == getPreviousButton()) { previousAction(); } else if (e.getSource() == getNextButton()) { WizardPanelProvider wpp = getWizardPanelProvider(); if (wpp != null) { if (!wpp.canPanelNext(getCurrentPanel())) { nextAction(); } } else { nextAction(); } } else if (e.getSource() == getFinishButton()) { finishAction(); } else if (e.getSource() == getCancelButton()) { cancelAction(); } } private void previousAction() { setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); decrPanelIndex(); displayPanel(); setCursor(Cursor.getDefaultCursor()); } private void nextAction() { setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); incrPanelIndex(); displayPanel(); setCursor(Cursor.getDefaultCursor()); } private void finishAction() { WizardPanelProvider wpp = getWizardPanelProvider(); if (wpp != null) { setMap(wpp.finish()); } fireEvent(WizardEvent.FINISH); } private void cancelAction() { fireEvent(WizardEvent.CANCEL); } private void displayPanel() { WizardPanelProvider wpp = getWizardPanelProvider(); if (wpp != null) { String[] idArray = wpp.getPanelIds(); String[] descArray = wpp.getPanelDescriptions(); if (idArray != null) { int pi = getPanelIndex(); if (pi < idArray.length) { JPanel p = wpp.createPanel(idArray[pi]); JPanel current = getCurrentPanel(); if ((p != null) && (current != null)) { ColumnPanel stepPanel = new ColumnPanel(descArray[pi], 0, p); remove(current); add(BorderLayout.CENTER, stepPanel); setCurrentPanel(stepPanel); validate(); } } } } makeState(); } private void makeState() { int index = getPanelIndex(); int count = getPanelCount(); JButton b = getPreviousButton(); if (b != null) { if (index > 0) { b.setEnabled(true); } else { b.setEnabled(false); } } b = getNextButton(); if (b != null) { if ((index + 1) == count) { b.setEnabled(false); } else { b.setEnabled(true); } } b = getFinishButton(); if (b != null) { if ((index + 1) == count) { b.setEnabled(true); } else { b.setEnabled(false); } } JLabel[] labels = getStepLabels(); if (labels != null) { for (int i = 0; i < labels.length; i++) { if (i == index) { labels[i].setForeground(Color.red); } else { labels[i].setForeground(Color.black); } } } } /** * {@inheritDoc} */ public void stateChanged(WizardEvent e) { if (e.getState() == WizardEvent.NEXT) { nextAction(); } } }