/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program 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. * This program 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 this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.snap.ui; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.CardLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Vector; /** * @author Norman Fomferra * @version $Revision$ $Date$ */ public class SequentialDialog { public static final int ID_BACK = 0x0001; public static final int ID_NEXT = 0x0002; public static final int ID_FINISH = 0x0004; public static final int ID_CANCEL = 0x0008; public static final int ID_HELP = 0x0010; private JFrame frame; private JDialog dialog; private int buttonID = ID_CANCEL; private Vector names = new Vector(); private int cardIndex = -1; private String titleBase; private JButton backButton = new JButton(); private JButton nextButton = new JButton(); private JButton finishButton = new JButton(); private JButton cancelButton = new JButton(); private JButton helpButton = new JButton(); private CardLayout cardLayout = new CardLayout(6, 6); private JPanel cardPanel = new JPanel(cardLayout); public SequentialDialog(JFrame frame, String titleBase) { this(frame, titleBase, null, false); } public SequentialDialog(JFrame frame, String titleBase, Icon image, boolean hasHelp) { this.frame = frame; this.cardIndex = -1; this.dialog = new JDialog(frame, titleBase, true); this.titleBase = titleBase; // Panel for buttons JPanel buttonRow = new JPanel(); buttonRow.setLayout(new BoxLayout(buttonRow, BoxLayout.X_AXIS)); buttonRow.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6)); JPanel panel1 = new JPanel(new BorderLayout()); panel1.add(BorderLayout.NORTH, new HorizontalLine(4, 4)); panel1.add(BorderLayout.SOUTH, buttonRow); if (image != null) { dialog.getContentPane().add(BorderLayout.WEST, new JLabel(image)); } dialog.getContentPane().add(BorderLayout.CENTER, cardPanel); dialog.getContentPane().add(BorderLayout.SOUTH, panel1); backButton.setText("< Back"); backButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { buttonID = ID_BACK; onBack(); } }); nextButton.setText("Next >"); nextButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { buttonID = ID_NEXT; onNext(); } }); finishButton.setText("Finish"); finishButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { buttonID = ID_FINISH; onFinish(); } }); cancelButton.setText("Cancel"); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { buttonID = ID_CANCEL; onCancel(); } }); helpButton.setText("Help"); helpButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { buttonID = ID_HELP; onHelp(); } }); Dimension hgap = new Dimension(6, 0); buttonRow.add(Box.createHorizontalGlue()); buttonRow.add(backButton); buttonRow.add(Box.createRigidArea(hgap)); buttonRow.add(nextButton); buttonRow.add(Box.createRigidArea(hgap)); buttonRow.add(finishButton); buttonRow.add(Box.createRigidArea(hgap)); buttonRow.add(cancelButton); if (hasHelp) { buttonRow.add(Box.createRigidArea(hgap)); buttonRow.add(helpButton); } dialog.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { buttonID = ID_CANCEL; onCancel(); } }); } public JFrame getFrame() { return frame; } public JDialog getDialog() { return dialog; } public int getButtonID() { return buttonID; } public int getCardCount() { return cardPanel.getComponentCount(); } public Component getCard(int index) { return cardPanel.getComponent(index); } public Component getCurrentCard() { return cardIndex < 0 ? null : getCard(cardIndex); } public String getCardName(int index) { return (String) names.elementAt(index); } public void addCard(String name, Component card) { cardPanel.add(card, name); names.addElement(name); } public int show() { if (getCardCount() > 0) { showCard(0); } dialog.pack(); center(); dialog.setVisible(true); return getButtonID(); } public void hide() { dialog.setVisible(false); } public void center() { UIUtils.centerComponent(dialog, frame); } protected void onBack() { showCard(getPreviousCardIndex()); } protected void onNext() { if (verifyUserInput()) { showCard(getNextCardIndex()); } } protected void onFinish() { if (verifyUserInput()) { hide(); } } protected void onCancel() { hide(); } protected void onHelp() { } protected int getCurrentCardIndex() { return cardIndex; } protected int getPreviousCardIndex() { int cardIndexMin = 0; return (cardIndex > cardIndexMin) ? (cardIndex - 1) : cardIndexMin; } protected int getNextCardIndex() { int cardIndexMax = getCardCount() - 1; return (cardIndex < cardIndexMax) ? (cardIndex + 1) : cardIndexMax; } protected void showCard(int index) { cardIndex = index; cardLayout.show(cardPanel, getCardName(index)); dialog.setTitle(titleBase + " - Step " + (cardIndex + 1) + " of " + getCardCount()); updateButtonStates(); } protected void updateButtonStates() { backButton.setEnabled(isBackPossible()); nextButton.setEnabled(isNextPossible()); finishButton.setEnabled(isFinishPossible()); } protected boolean isBackPossible() { return getCurrentCardIndex() > 0; } protected boolean isNextPossible() { return getCurrentCardIndex() < getCardCount() - 1; } protected boolean isFinishPossible() { return getCurrentCardIndex() == getCardCount() - 1; } protected boolean verifyUserInput() { return true; } static class HorizontalLine extends Canvas { Dimension prefSize; HorizontalLine(int w, int h) { prefSize = new Dimension(w, h); } @Override public Dimension getMinimumSize() { return prefSize; } @Override public Dimension getPreferredSize() { return prefSize; } @Override public void paint(Graphics g) { Dimension size = this.getSize(); int x1 = 0; int x2 = size.width - 1; int y1 = size.height / 2; int y2 = y1 + 1; g.setColor(this.getBackground().brighter()); g.drawLine(x1, y1, x2, y1); g.setColor(this.getBackground().darker()); g.drawLine(x1, y2, x2, y2); } } }