/*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
*
* The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
* Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
*
* Contributor(s):
* Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
*
* If you didn't download this code from the following link, you should check
* if you aren't using an obsolete version: http://www.isqlviewer.com
*/
package org.isqlviewer.ui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.util.Collection;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;
import org.isqlviewer.swing.SwingUtilities;
import org.isqlviewer.swing.WizardPanel;
import org.isqlviewer.swing.action.SwingEventManager;
import org.isqlviewer.ui.wizards.Step;
import org.isqlviewer.ui.wizards.Wizard;
import org.isqlviewer.ui.wizards.WizardContext;
import org.isqlviewer.util.LocalMessages;
/**
* Runtime environment for running wizard sub-systems.
* <p>
* This dialog window follows the wizard interface for showing step by step processes.
*
* @author Mark A. Kobold <mkobold at isqlviewer dot com>
* @version 1.0
*/
public class WizardRunner extends JDialog implements ActionListener {
private static final long serialVersionUID = -1030110039402276194L;
private LocalMessages messages = new LocalMessages("org.isqlviewer.ui.ResourceBundle");
private static final GridBagConstraints UI_CONSTRAINT = new GridBagConstraints(0, 0, 0, 0, 0, 0, 0, 0, new Insets(
1, 1, 1, 1), 0, 0);
private DefaultListModel steplistModel = new DefaultListModel();
private JList stepList = new JList(steplistModel);
private JButton nextButton = new JButton();
private JButton previousButton = new JButton();
private JButton cancelButton = new JButton();
private JButton homeButton = new JButton();
private JLabel marqueeLabel = new JLabel();
private JLabel commentLabel = new JLabel();
private JLabel iconLabel = new JLabel();
private JPanel bannerPanel = new JPanel(new GridBagLayout());
private JPanel navigationPanel = new JPanel(new GridBagLayout());
private Wizard wizard = null;
private WizardContextImpl wizardContext = null;
private Step currentStep = null;
private JPanel stepContainer = new JPanel(new WizardPanel.Layout());
public WizardRunner(Frame owner, Wizard wizard, SwingEventManager eventManager) {
super(owner, true);
if (wizard == null) {
throw new NullPointerException(Wizard.class.getName());
}
wizardContext = new WizardContextImpl(eventManager, this);
this.wizard = wizard;
initUI();
}
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
int index = stepList.getSelectedIndex();
if (source == nextButton) {
boolean isValid = false;
try {
isValid = currentStep.isValid(wizardContext);
} catch (Throwable t) {
wizardContext.showErrorDialog(this, t, "");
}
if (isValid) {
Step next = currentStep.getNext();
if (next == null) {
wizard.finish(wizardContext);
dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
} else {
showStep(next);
stepList.setSelectedIndex(index + 1);
currentStep = next;
}
} else {
SwingUtilities.beep();
}
} else if (source == previousButton) {
Step previous = currentStep.getPrevious();
if (previous == null) {
wizard.finish(wizardContext);
} else {
stepList.setSelectedIndex(index - 1);
showStep(previous);
currentStep = previous;
}
} else if (source == homeButton) {
Step first = wizard.firstStep();
if (first == null) {
wizard.finish(wizardContext);
} else {
showStep(first);
currentStep = first;
}
} else if (source == cancelButton) {
wizard.finish(wizardContext);
dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
}
}
protected void setBanner(String text) {
marqueeLabel.setText(text);
}
protected void setComment(String text) {
commentLabel.setText(text);
}
protected void setIcon(Icon ico) {
iconLabel.setIcon(ico);
}
protected void startWizard() {
currentStep = wizard.firstStep();
setTitle(wizard.getTitle());
steplistModel.addElement(currentStep);
Step current = currentStep;
while ((current = current.getNext()) != null) {
steplistModel.addElement(current);
}
stepList.setSelectedIndex(0);
showStep(currentStep);
}
protected synchronized void showStep(Step step) {
if (step == null) {
return;
}
setBanner(step.getTitle());
setComment(step.getComment());
setIcon(step.getImage());
previousButton.setEnabled(!step.isFirst());
if (step.isLast()) {
nextButton.setText(messages.getMessage("wizardrunner.nav_finish.text"));
nextButton.setToolTipText(messages.getMessage("wizardrunner.nav_finish.tip"));
} else {
nextButton.setText(messages.getMessage("wizardrunner.nav_next.text"));
nextButton.setToolTipText(messages.getMessage("wizardrunner.nav_next.tip"));
}
stepContainer.removeAll();
try {
step.activate(wizardContext);
} catch (Exception error) {
error.printStackTrace();
}
stepContainer.add(step.getView());
validateTree();
if (!SwingUtilities.isFrameModified(this).booleanValue()) {
SwingUtilities.setFrameModified(this, Boolean.TRUE);
}
repaint();
}
protected void setNextStepEnabled(boolean f) {
nextButton.setEnabled(f);
}
protected void setPreviousStepEnabled(boolean f) {
previousButton.setEnabled(f);
}
protected void setHomeAllowable(boolean f) {
homeButton.setVisible(f);
homeButton.setEnabled(f);
}
@Override
protected void processWindowEvent(WindowEvent e) {
switch (e.getID()) {
case WindowEvent.WINDOW_OPENED :
startWizard();
break;
}
super.processWindowEvent(e);
}
private void initUI() {
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
JPanel rootContentPanel = (JPanel) getContentPane();
rootContentPanel.setLayout(new WizardPanel.Layout());
JPanel cp = new JPanel(new GridBagLayout());
rootContentPanel.add(cp);
configureToolbar();
configureBanner();
stepList.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
stepList.setEnabled(false);
stepList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
stepList.setCellRenderer(new StepListCellRenderer());
constrain(0, 0, 1, 3, 0.25, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
cp.add(stepList, UI_CONSTRAINT);
constrain(1, 0, 1, 3, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
cp.add(Box.createHorizontalStrut(5), UI_CONSTRAINT);
constrain(2, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
cp.add(bannerPanel, UI_CONSTRAINT);
constrain(2, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
cp.add(stepContainer, UI_CONSTRAINT);
constrain(2, 2, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
cp.add(navigationPanel, UI_CONSTRAINT);
wizard.init(wizardContext);
setSize(new Dimension(620, 360));
setPreferredSize(getSize());
}
private void configureToolbar() {
homeButton.addActionListener(this);
previousButton.addActionListener(this);
nextButton.addActionListener(this);
cancelButton.addActionListener(this);
homeButton.setText(messages.getMessage("wizardrunner.nav_home.text"));
homeButton.setToolTipText(messages.getMessage("wizardrunner.nav_home.tip"));
homeButton.setVisible(wizard.supportsHome());
previousButton.setToolTipText(messages.getMessage("wizardrunner.nav_previous.tip"));
previousButton.setText(messages.getMessage("wizardrunner.nav_previous.text"));
nextButton.setText(messages.getMessage("wizardrunner.nav_next.text"));
nextButton.setToolTipText(messages.getMessage("wizardrunner.nav_next.tip"));
cancelButton.setText(messages.getMessage("wizardrunner.nav_cancel.text"));
cancelButton.setToolTipText(messages.getMessage("wizardrunner.nav_cancel.tip"));
constrain(0, 0, 5, 1, 1.0d, 0.0d, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
navigationPanel.add(new JSeparator(SwingConstants.HORIZONTAL), UI_CONSTRAINT);
constrain(0, 1, 1, 1, 1.0d, 0.0d, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
navigationPanel.add(Box.createHorizontalGlue(), UI_CONSTRAINT);
constrain(1, 1, 1, 1, 0.0d, 0.0d, GridBagConstraints.EAST, GridBagConstraints.NONE);
navigationPanel.add(homeButton, UI_CONSTRAINT);
constrain(2, 1, 1, 1, 0.0d, 0.0d, GridBagConstraints.EAST, GridBagConstraints.NONE);
navigationPanel.add(previousButton, UI_CONSTRAINT);
constrain(3, 1, 1, 1, 0.0d, 0.0d, GridBagConstraints.EAST, GridBagConstraints.NONE);
navigationPanel.add(nextButton, UI_CONSTRAINT);
constrain(4, 1, 1, 1, 0.0d, 0.0d, GridBagConstraints.EAST, GridBagConstraints.NONE);
navigationPanel.add(cancelButton, UI_CONSTRAINT);
}
private void configureBanner() {
bannerPanel.setBorder(BorderFactory.createLineBorder(UIManager.getColor("TextArea.foreground"), 1));
bannerPanel.setBackground(UIManager.getColor("TextArea.background"));
bannerPanel.setForeground(UIManager.getColor("TextArea.foreground"));
marqueeLabel.setFont(marqueeLabel.getFont().deriveFont(Font.BOLD, 16f));
marqueeLabel.setForeground(bannerPanel.getForeground());
marqueeLabel.setBackground(bannerPanel.getBackground());
commentLabel.setFont(commentLabel.getFont().deriveFont(Font.ITALIC, 12f));
commentLabel.setForeground(bannerPanel.getForeground());
commentLabel.setBackground(bannerPanel.getBackground());
constrain(0, 0, 1, 2, 0.0d, 0.0d, GridBagConstraints.CENTER, GridBagConstraints.NONE);
bannerPanel.add(Box.createHorizontalStrut(12), UI_CONSTRAINT);
constrain(0, 0, 2, 1, 1.0d, 0.0d, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL);
bannerPanel.add(marqueeLabel, UI_CONSTRAINT);
constrain(1, 1, 1, 1, 1.0d, 0.0d, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL);
bannerPanel.add(commentLabel, UI_CONSTRAINT);
constrain(2, 0, 1, 2, 0.0d, 0.0d, GridBagConstraints.CENTER, GridBagConstraints.NONE);
bannerPanel.add(iconLabel, UI_CONSTRAINT);
constrain(3, 0, 1, 2, 0.0d, 0.0d, GridBagConstraints.CENTER, GridBagConstraints.NONE);
bannerPanel.add(Box.createHorizontalStrut(12), UI_CONSTRAINT);
}
protected static void constrain(int x, int y, int w, int h, double wx, double wy, int a, int f) {
UI_CONSTRAINT.gridx = x;
UI_CONSTRAINT.gridy = y;
UI_CONSTRAINT.gridwidth = w;
UI_CONSTRAINT.gridheight = h;
UI_CONSTRAINT.weightx = wx;
UI_CONSTRAINT.weighty = wy;
UI_CONSTRAINT.anchor = a;
UI_CONSTRAINT.fill = f;
}
private static class WizardContextImpl extends WizardContext {
WizardRunner reference = null;
WizardContextImpl(SwingEventManager eventManager, WizardRunner reference) {
super(eventManager);
this.reference = reference;
}
@Override
public void showErrorDialog(Throwable error, String message) {
super.showErrorDialog(reference, error, message);
}
@Override
public void showInformationDialog(String message) {
super.showInformationDialog(reference, message);
}
@Override
public void updateSteps(Collection<Step> newSteps) {
Step currentStep = reference.currentStep;
DefaultListModel listModel = reference.steplistModel;
int currentIndex = listModel.indexOf(currentStep);
try {
int fromIndex = currentIndex + 1;
int toIndex = listModel.getSize() - 1;
if (fromIndex <= toIndex) {
listModel.removeRange(fromIndex, toIndex);
}
} catch (ArrayIndexOutOfBoundsException ignored) {
debug("", ignored);
} catch (IllegalArgumentException ignored) {
debug("", ignored);
}
for (Step step : newSteps) {
listModel.addElement(step);
}
reference.pack();
}
@Override
public void invokeNext() {
reference.nextButton.doClick(0);
}
}
private static class StepListCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 1664986318928860084L;
static final Color selectedFocusedColor = Color.decode("#3D80DF");
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected,
boolean hasFocus) {
super.getListCellRendererComponent(list, value, index, selected, hasFocus);
if (selected) {
setBackground(selectedFocusedColor);
setForeground(Color.WHITE);
}
if (index < list.getSelectedIndex()) {
setIcon(SwingUtilities.loadIconResource("button_ok", 16));
} else {
setIcon(null);
}
Step step = (Step) value;
setText(step.getTitle());
setToolTipText(step.getComment());
setEnabled(true);
return this;
}
}
}
|