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-2016 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 */
039public class ButtonsPanel extends QuickSetupPanel
040{
041  private static final long serialVersionUID = -8460400337486357976L;
042
043  private HashSet<ButtonActionListener> buttonListeners = new HashSet<>();
044
045  private JButton nextButton;
046  private JButton previousButton;
047  private JButton quitButton;
048  private JButton closeButton;
049  private JButton finishButton;
050
051  /**
052   * Default constructor.
053   * @param application Application running in QuickSetup
054   */
055  public ButtonsPanel(GuiApplication application)
056  {
057    super(application);
058    createButtons();
059    layoutButtons();
060  }
061
062  /**
063   * Adds a button listener.  All the button listeners will be notified when
064   * the buttons are clicked (by the user or programatically).
065   * @param l the ButtonActionListener to be added.
066   */
067  public void addButtonActionListener(ButtonActionListener l)
068  {
069    buttonListeners.add(l);
070  }
071
072  /**
073   * Removes a button listener.
074   * @param l the ButtonActionListener to be removed.
075   */
076  public void removeButtonActionListener(ButtonActionListener l)
077  {
078    buttonListeners.remove(l);
079  }
080
081  /**
082   * Updates the layout of the panel so that it corresponds to the Step passed
083   * as parameter.
084   *
085   * @param step the step in the wizard.
086   */
087  public void updateButtons(WizardStep step)
088  {
089    GuiApplication application = getApplication();
090    previousButton.setVisible(application.canGoBack(step));
091    if (application.canFinish(step)) {
092      finishButton.setVisible(true);
093      nextButton.setVisible(false);
094    } else {
095      finishButton.setVisible(false);
096      nextButton.setVisible(application.canGoForward(step));
097    }
098
099    // The quit button appears on all the panels leading up
100    // to the progress panel
101    quitButton.setVisible(!step.isProgressStep() && !step.isFinishedStep());
102
103    // The close button is only used on the progress panel and
104    // is only enabled once progress has finished or cancelled.
105    closeButton.setVisible(step.isProgressStep() || step.isFinishedStep());
106    closeButton.setEnabled(application.getCurrentProgressStep().isLast());
107
108    // The next button is always enabled in all steps except the license step.
109    // In that step, the next button will be enabled only if the user has
110    // approved the license
111    nextButton.setEnabled(!step.isLicenseStep() || LicenseFile.getApproval());
112  }
113
114  /**
115   * Returns the button corresponding to the buttonName.
116   * @param buttonName the ButtonName for which we want to get the button.
117   * @return the button corresponding to the buttonName.
118   */
119  public JButton getButton(ButtonName buttonName)
120  {
121    JButton b = null;
122    if (buttonName != null) {
123      switch (buttonName) {
124        case NEXT:
125          b = nextButton;
126          break;
127
128        case PREVIOUS:
129          b = previousButton;
130          break;
131
132        case QUIT:
133          b = quitButton;
134          break;
135
136        case CLOSE:
137          b = closeButton;
138          break;
139
140        case FINISH:
141          b = finishButton;
142          break;
143
144        default:
145          throw new IllegalArgumentException("Unknown button name: " +
146                  buttonName);
147      }
148    }
149
150    return b;
151  }
152
153  private void createButtons()
154  {
155    GuiApplication application = getApplication();
156    nextButton = createButton(
157            INFO_NEXT_BUTTON_LABEL.get(),
158            INFO_NEXT_BUTTON_TOOLTIP.get(),
159            ButtonName.NEXT);
160
161    previousButton = createButton(
162            INFO_PREVIOUS_BUTTON_LABEL.get(),
163            INFO_PREVIOUS_BUTTON_TOOLTIP.get(),
164            ButtonName.PREVIOUS);
165
166    quitButton = createButton(
167            INFO_QUIT_BUTTON_LABEL.get(),
168            application.getQuitButtonToolTip(),
169            ButtonName.QUIT);
170
171    closeButton = createButton(
172            INFO_CLOSE_BUTTON_LABEL.get(),
173            application.getCloseButtonToolTip(),
174            ButtonName.CLOSE);
175
176    finishButton = createButton(
177            application.getFinishButtonLabel(),
178            application.getFinishButtonToolTip(),
179            ButtonName.FINISH);
180
181  }
182
183  /** Do the layout of the panel. */
184  private void layoutButtons()
185  {
186    setLayout(new GridBagLayout());
187    GridBagConstraints gbc = new GridBagConstraints();
188
189    GridBagConstraints gbcAux = new GridBagConstraints();
190    gbcAux.gridwidth = GridBagConstraints.REMAINDER;
191    gbcAux.fill = GridBagConstraints.HORIZONTAL;
192    JPanel previousPanel = new JPanel(new GridBagLayout());
193    // Set as opaque to inherit the background color of ButtonsPanel
194    previousPanel.setOpaque(false);
195    previousPanel.add(previousButton, gbcAux);
196    int width = (int) previousButton.getPreferredSize().getWidth();
197    previousPanel.add(Box.createHorizontalStrut(width), gbcAux);
198
199    gbc.gridwidth = 5;
200    gbc.weightx = 0.0;
201    gbc.weighty = 0.0;
202    gbc.insets.bottom = 0;
203    gbc.insets.right = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
204    gbc.anchor = GridBagConstraints.WEST;
205    gbc.fill = GridBagConstraints.NONE;
206    add(previousPanel, gbc);
207    gbc.gridwidth--;
208
209    JPanel nextFinishPanel = new JPanel(new GridBagLayout());
210    // Set as opaque to inherit the background color of ButtonsPanel
211    nextFinishPanel.setOpaque(false);
212    nextFinishPanel.add(nextButton, gbcAux);
213
214    if (getApplication().finishOnLeft()) {
215      nextFinishPanel.add(finishButton, gbcAux);
216    }
217    width =
218        (int) Math.max(nextButton.getPreferredSize().getWidth(), finishButton
219            .getPreferredSize().getWidth());
220    nextFinishPanel.add(Box.createHorizontalStrut(width), gbcAux);
221    add(nextFinishPanel, gbc);
222
223    gbc.gridwidth--;
224    gbc.weightx = 1.0;
225    gbc.fill = GridBagConstraints.HORIZONTAL;
226    gbc.insets.right = 0;
227    add(Box.createHorizontalGlue(), gbc);
228
229    gbc.gridwidth = GridBagConstraints.RELATIVE;
230    gbc.weightx = 0.0;
231    gbc.fill = GridBagConstraints.NONE;
232    gbc.insets.left = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
233
234    if (!getApplication().finishOnLeft()) {
235      gbc.insets.right = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
236      add(finishButton, gbc);
237      gbc.insets.right = 0;
238    }
239
240    gbc.gridwidth = GridBagConstraints.REMAINDER;
241    gbc.weightx = 0.0;
242    gbc.fill = GridBagConstraints.NONE;
243    gbc.insets.left = 0;
244    JPanel quitClosePanel = new JPanel(new GridBagLayout());
245    // Set as opaque to inherit the background color of ButtonsPanel
246    quitClosePanel.setOpaque(false);
247    quitClosePanel.add(
248        Box.createHorizontalStrut(UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS),
249        gbcAux);
250    quitClosePanel.add(quitButton, gbcAux);
251    quitClosePanel.add(closeButton, gbcAux);
252    width =
253        (int) Math.max(quitButton.getPreferredSize().getWidth(), closeButton
254            .getPreferredSize().getWidth());
255    quitClosePanel.add(Box.createHorizontalStrut(width), gbcAux);
256    add(quitClosePanel, gbc);
257  }
258
259  /**
260   * Create a button.
261   * @param label the label of the button.
262   * @param tooltip the tooltip of the button.
263   * @param buttonName the ButtonName.
264   * @return a new button with the specified parameters.
265   */
266  private JButton createButton(LocalizableMessage label, LocalizableMessage tooltip,
267      ButtonName buttonName)
268  {
269    JButton b = UIFactory.makeJButton(label, tooltip);
270
271    final ButtonName fButtonName = buttonName;
272
273    ActionListener actionListener = new ActionListener()
274    {
275      @Override
276      public void actionPerformed(ActionEvent ev)
277      {
278        ButtonEvent be = new ButtonEvent(ev.getSource(), fButtonName);
279        for (ButtonActionListener li : buttonListeners)
280        {
281          li.buttonActionPerformed(be);
282        }
283      }
284    };
285
286    b.addActionListener(actionListener);
287
288    return b;
289  }
290}