/* * SetupDialog.java * * Copyright (C) 2010 Leo Osvald <leo.osvald@gmail.com> * * This file is part of SGLJ. * * SGLJ is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SGLJ 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see <http://www.gnu.org/licenses/>. */ package org.sglj.swing.dialog; import java.awt.Frame; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JOptionPane; /** * Dialog which resembles some kind of a setup. * It consists of one or more steps (see {@link SetupStep}). * * @author Leo Osvald * @version 0.93 */ public abstract class SetupDialog extends DynamicContentDialog { // protected JPanel navigationPanel; // private JButton backButton; private SetupStep currStep; private final ActionPreviousStep actionBack = createPreviousStepAction(); private final ActionNextStep actionNext = createNextStepAction(); private final ActionFinish actionFinish = createFinishAction(); private final Object[] options = { new JButton(actionBack), new JButton(actionNext), new JButton(actionFinish) }; private static final long serialVersionUID = 1L; public SetupDialog(Frame parentFrame, String title) { super(parentFrame, title, false); //FIXME ne radi sa true setOptionPane(createOptionPane()); update(); // setSize(500,400); //pack(); } // private JPanel createNavigationPanel() { // backButton = new JButton(actionBack); // nextOrFinishButton = nextButton = new JButton(actionNext); // finishButton = new JButton(actionFinish); // // Dimension nextDim = nextButton.getPreferredSize(); // Dimension finDim = finishButton.getPreferredSize(); // Dimension maxDim = new Dimension(Math.max(nextDim.width, finDim.width), // Math.max(nextDim.height, finDim.height)); // backButton.setPreferredSize(maxDim); // nextButton.setPreferredSize(maxDim); // finishButton.setPreferredSize(maxDim); // System.out.println("Next button dim: " + nextDim); // System.out.println("Fin button dim: " + finDim); // // backButton.setVisible(false); // // navigationPanel = new JPanel(); // navigationPanel.setLayout(new BoxLayout(navigationPanel, BoxLayout.X_AXIS)); // navigationPanel.add(Box.createGlue()); // navigationPanel.add(backButton); // navigationPanel.add(nextOrFinishButton); // // return navigationPanel; // } /** * This method should be called to refresh the state of * Back/Next/Finish button.<br> * Before this method returns, method {@link #onUpdate()} * is called from inside this method. */ public void update() { //replace next with finish on last step // if(!hasNextStep()) { // if(nextOrFinishButton == nextButton) { // navigationPanel.remove(nextButton); // navigationPanel.add(finishButton); // } // nextOrFinishButton = finishButton; // } // else { // if(nextOrFinishButton == finishButton) { // navigationPanel.remove(finishButton); // navigationPanel.add(nextButton); // } // nextOrFinishButton = nextButton; // } // // System.out.println("Finish instead of next? " + (nextOrFinishButton == finishButton)); // navigationPanel.validate(); if(getCurrentStep() != null) { //disable previous step on first step actionBack.setEnabled(hasPreviousStep()); actionNext.setEnabled(hasNextStep() && getCurrentStep().validate()); actionFinish.setEnabled(canFinish()); } else { actionBack.setEnabled(false); actionNext.setEnabled(false); actionFinish.setEnabled(false); } //update action onUpdate(); } public SetupStep getCurrentStep() { return currStep; } // /** // * Postavlja jeli "back" gumb postoji. // */ // public void setBackVisible(boolean visible) { // backButton.setVisible(visible); // } /** * Proceeds to the next step of the setup. * This method is automatically called when the user clicks * on "Next" button. */ public abstract void nextStep(); /** * Goes back to the previous step of the setup. * This method is automatically called when the user clicks * on "Back" button. */ public abstract void previousStep(); /** * Checks whether there are more steps to advance to. * @return <code>true</code> if this is not the last step, * <code>false</code> if this is the last step. */ public abstract boolean hasNextStep(); /** * Checks whether there are previous steps, or this is the first one. * @return <code>true</code> if there are, <code>false</code> otherwise. */ public abstract boolean hasPreviousStep(); /** * Checks whether the setup can finish. * This has a direct impact on the state of the * "Finish" button. If the setup can finish, "Finish" * button will be enabled (otherwise it will be disabled). * @return <code>true</code> if setup can finish, * <code>false</code> otherwise. */ public abstract boolean canFinish(); /** * Finishes the setup. * This method is automatically called when the user clicks * on "Finish" button. */ public abstract void finish(); /** * This method is automatically called from inside the * {@link #update()} method. */ protected abstract void onUpdate(); /** * This method is called whenever an attempt to close the dialog * occurs or the user clicks "Cancel" button. * All actions and behavior should be done here, such as * asking for confirmation, saving state etc.. */ protected abstract void onClose(); /** * Sets the specified step as the current one, * after calling {@link SetupStep#leave()} on the previous one. * @param setupStep */ protected void setCurrentStep(SetupStep setupStep) { if(this.currStep == setupStep) return ; if(this.currStep != null) this.currStep.leave(); this.currStep = setupStep; setupStep.load(); setContent(setupStep.getPanel()); update(); } @Override protected JOptionPane createOptionPane() { return new JOptionPane( contentPane, JOptionPane.PLAIN_MESSAGE, JOptionPane.YES_NO_OPTION, null, options); } protected abstract ActionNextStep createNextStepAction(); protected abstract ActionPreviousStep createPreviousStepAction(); protected abstract ActionFinish createFinishAction(); protected class ActionNextStep extends AbstractAction { private static final long serialVersionUID = 1L; public ActionNextStep(String name, Icon icon, String shortDescription, int mnemonicKey) { super(name, icon); putValue(SHORT_DESCRIPTION, shortDescription); putValue(MNEMONIC_KEY, mnemonicKey); } @Override public void actionPerformed(ActionEvent e) { nextStep(); } } protected class ActionPreviousStep extends AbstractAction { private static final long serialVersionUID = 1L; public ActionPreviousStep(String name, Icon icon, String shortDescription, int mnemonicKey) { super(name, icon); putValue(SHORT_DESCRIPTION, shortDescription); putValue(MNEMONIC_KEY, mnemonicKey); } @Override public void actionPerformed(ActionEvent e) { previousStep(); } } protected class ActionFinish extends AbstractAction { private static final long serialVersionUID = 1L; public ActionFinish(String name, Icon icon, String shortDescription, int mnemonicKey) { super(name, icon); putValue(SHORT_DESCRIPTION, shortDescription); putValue(MNEMONIC_KEY, mnemonicKey); } @Override public void actionPerformed(ActionEvent e) { finish(); } } }