001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2006-2008 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2015 ForgeRock AS.
016 */
017package org.opends.quicksetup.ui;
018
019import org.forgerock.i18n.LocalizableMessage;
020import static org.opends.messages.QuickSetupMessages.*;
021
022import org.opends.quicksetup.ButtonName;
023import org.opends.quicksetup.WizardStep;
024import org.opends.quicksetup.LicenseFile;
025import org.opends.quicksetup.event.ButtonActionListener;
026import org.opends.quicksetup.event.ButtonEvent;
027
028import javax.swing.*;
029import java.awt.*;
030import java.awt.event.ActionEvent;
031import java.awt.event.ActionListener;
032import java.util.HashSet;
033
034/**
035 * This class contains the buttons in the bottom of the Install/Uninstall
036 * dialog.  There is only one of this instances for the QuickSetupDialog.
037 * The layout is updated calling setCurrentStep method.
038 *
039 */
040public class ButtonsPanel extends QuickSetupPanel
041{
042  private static final long serialVersionUID = -8460400337486357976L;
043
044  private HashSet<ButtonActionListener> buttonListeners = new HashSet<>();
045
046  private JButton nextButton;
047  private JButton previousButton;
048  private JButton quitButton;
049  private JButton closeButton;
050  private JButton finishButton;
051
052  /**
053   * Default constructor.
054   * @param application Application running in QuickSetup
055   */
056  public ButtonsPanel(GuiApplication application)
057  {
058    super(application);
059    createButtons();
060    layoutButtons();
061  }
062
063  /**
064   * Adds a button listener.  All the button listeners will be notified when
065   * the buttons are clicked (by the user or programatically).
066   * @param l the ButtonActionListener to be added.
067   */
068  public void addButtonActionListener(ButtonActionListener l)
069  {
070    buttonListeners.add(l);
071  }
072
073  /**
074   * Removes a button listener.
075   * @param l the ButtonActionListener to be removed.
076   */
077  public void removeButtonActionListener(ButtonActionListener l)
078  {
079    buttonListeners.remove(l);
080  }
081
082  /**
083   * Updates the layout of the panel so that it corresponds to the Step passed
084   * as parameter.
085   *
086   * @param step the step in the wizard.
087   */
088  public void updateButtons(WizardStep step)
089  {
090    GuiApplication application = getApplication();
091    previousButton.setVisible(application.canGoBack(step));
092    if (application.canFinish(step)) {
093      finishButton.setVisible(true);
094      nextButton.setVisible(false);
095    } else {
096      finishButton.setVisible(false);
097      nextButton.setVisible(application.canGoForward(step));
098    }
099
100    // The quit button appears on all the panels leading up
101    // to the progress panel
102    quitButton.setVisible(!step.isProgressStep() && !step.isFinishedStep());
103
104    // The close button is only used on the progress panel and
105    // is only enabled once progress has finished or cancelled.
106    closeButton.setVisible(step.isProgressStep() || step.isFinishedStep());
107    closeButton.setEnabled(application.getCurrentProgressStep().isLast());
108
109    // The next button is always enabled in all steps except the license step.
110    // In that step, the next button will be enabled only if the user has
111    // approved the license
112    nextButton.setEnabled(!step.isLicenseStep() || LicenseFile.getApproval());
113  }
114
115  /**
116   * Returns the button corresponding to the buttonName.
117   * @param buttonName the ButtonName for which we want to get the button.
118   * @return the button corresponding to the buttonName.
119   */
120  public JButton getButton(ButtonName buttonName)
121  {
122    JButton b = null;
123    if (buttonName != null) {
124      switch (buttonName) {
125        case NEXT:
126          b = nextButton;
127          break;
128
129        case PREVIOUS:
130          b = previousButton;
131          break;
132
133        case QUIT:
134          b = quitButton;
135          break;
136
137        case CLOSE:
138          b = closeButton;
139          break;
140
141        case FINISH:
142          b = finishButton;
143          break;
144
145        default:
146          throw new IllegalArgumentException("Unknown button name: " +
147                  buttonName);
148      }
149    }
150
151    return b;
152  }
153
154  private void createButtons()
155  {
156    GuiApplication application = getApplication();
157    nextButton = createButton(
158            INFO_NEXT_BUTTON_LABEL.get(),
159            INFO_NEXT_BUTTON_TOOLTIP.get(),
160            ButtonName.NEXT);
161
162    previousButton = createButton(
163            INFO_PREVIOUS_BUTTON_LABEL.get(),
164            INFO_PREVIOUS_BUTTON_TOOLTIP.get(),
165            ButtonName.PREVIOUS);
166
167    quitButton = createButton(
168            INFO_QUIT_BUTTON_LABEL.get(),
169            application.getQuitButtonToolTip(),
170            ButtonName.QUIT);
171
172    closeButton = createButton(
173            INFO_CLOSE_BUTTON_LABEL.get(),
174            application.getCloseButtonToolTip(),
175            ButtonName.CLOSE);
176
177    finishButton = createButton(
178            application.getFinishButtonLabel(),
179            application.getFinishButtonToolTip(),
180            ButtonName.FINISH);
181
182  }
183
184  /**
185   * Do the layout of the panel.
186   *
187   */
188  private void layoutButtons()
189  {
190    setLayout(new GridBagLayout());
191    GridBagConstraints gbc = new GridBagConstraints();
192
193    GridBagConstraints gbcAux = new GridBagConstraints();
194    gbcAux.gridwidth = GridBagConstraints.REMAINDER;
195    gbcAux.fill = GridBagConstraints.HORIZONTAL;
196    JPanel previousPanel = new JPanel(new GridBagLayout());
197    // Set as opaque to inherit the background color of ButtonsPanel
198    previousPanel.setOpaque(false);
199    previousPanel.add(previousButton, gbcAux);
200    int width = (int) previousButton.getPreferredSize().getWidth();
201    previousPanel.add(Box.createHorizontalStrut(width), gbcAux);
202
203    gbc.gridwidth = 5;
204    gbc.weightx = 0.0;
205    gbc.weighty = 0.0;
206    gbc.insets.bottom = 0;
207    gbc.insets.right = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
208    gbc.anchor = GridBagConstraints.WEST;
209    gbc.fill = GridBagConstraints.NONE;
210    add(previousPanel, gbc);
211    gbc.gridwidth--;
212
213    JPanel nextFinishPanel = new JPanel(new GridBagLayout());
214    // Set as opaque to inherit the background color of ButtonsPanel
215    nextFinishPanel.setOpaque(false);
216    nextFinishPanel.add(nextButton, gbcAux);
217
218    if (getApplication().finishOnLeft()) {
219      nextFinishPanel.add(finishButton, gbcAux);
220    }
221    width =
222        (int) Math.max(nextButton.getPreferredSize().getWidth(), finishButton
223            .getPreferredSize().getWidth());
224    nextFinishPanel.add(Box.createHorizontalStrut(width), gbcAux);
225    add(nextFinishPanel, gbc);
226
227    gbc.gridwidth--;
228    gbc.weightx = 1.0;
229    gbc.fill = GridBagConstraints.HORIZONTAL;
230    gbc.insets.right = 0;
231    add(Box.createHorizontalGlue(), gbc);
232
233    gbc.gridwidth = GridBagConstraints.RELATIVE;
234    gbc.weightx = 0.0;
235    gbc.fill = GridBagConstraints.NONE;
236    gbc.insets.left = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
237
238    if (!getApplication().finishOnLeft()) {
239      gbc.insets.right = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
240      add(finishButton, gbc);
241      gbc.insets.right = 0;
242    }
243
244    gbc.gridwidth = GridBagConstraints.REMAINDER;
245    gbc.weightx = 0.0;
246    gbc.fill = GridBagConstraints.NONE;
247    gbc.insets.left = 0;
248    JPanel quitClosePanel = new JPanel(new GridBagLayout());
249    // Set as opaque to inherit the background color of ButtonsPanel
250    quitClosePanel.setOpaque(false);
251    quitClosePanel.add(
252        Box.createHorizontalStrut(UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS),
253        gbcAux);
254    quitClosePanel.add(quitButton, gbcAux);
255    quitClosePanel.add(closeButton, gbcAux);
256    width =
257        (int) Math.max(quitButton.getPreferredSize().getWidth(), closeButton
258            .getPreferredSize().getWidth());
259    quitClosePanel.add(Box.createHorizontalStrut(width), gbcAux);
260    add(quitClosePanel, gbc);
261  }
262
263  /**
264   * Create a button.
265   * @param label the label of the button.
266   * @param tooltip the tooltip of the button.
267   * @param buttonName the ButtonName.
268   * @return a new button with the specified parameters.
269   */
270  private JButton createButton(LocalizableMessage label, LocalizableMessage tooltip,
271      ButtonName buttonName)
272  {
273    JButton b = UIFactory.makeJButton(label, tooltip);
274
275    final ButtonName fButtonName = buttonName;
276
277    ActionListener actionListener = new ActionListener()
278    {
279      public void actionPerformed(ActionEvent ev)
280      {
281        ButtonEvent be = new ButtonEvent(ev.getSource(), fButtonName);
282        for (ButtonActionListener li : buttonListeners)
283        {
284          li.buttonActionPerformed(be);
285        }
286      }
287    };
288
289    b.addActionListener(actionListener);
290
291    return b;
292  }
293}