001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2013-2015 ForgeRock AS.
026 */
027package org.opends.quicksetup.ui;
028
029import java.awt.Component;
030import java.awt.GridBagConstraints;
031import java.awt.GridBagLayout;
032import java.awt.event.ActionEvent;
033import java.awt.event.ActionListener;
034import java.awt.event.FocusEvent;
035import java.awt.event.FocusListener;
036
037import javax.swing.*;
038import javax.swing.event.HyperlinkEvent;
039import javax.swing.event.HyperlinkListener;
040
041import org.opends.quicksetup.ButtonName;
042import org.opends.quicksetup.ProgressStep;
043import org.opends.quicksetup.event.ButtonEvent;
044import org.opends.quicksetup.ProgressDescriptor;
045import org.forgerock.i18n.LocalizableMessage;
046import static org.opends.messages.QuickSetupMessages.*;
047
048/**
049 * This panel is used to show the progress of the application.
050 *
051 */
052public class ProgressPanel extends QuickSetupStepPanel
053{
054  private static final long serialVersionUID = 8129425068163357170L;
055
056  private JEditorPane progressBarLabel;
057
058  private JProgressBar progressBar;
059
060  private JButton btnCancel;
061
062  private JEditorPane detailsTextArea;
063
064  private LocalizableMessage lastText;
065
066  private Component lastFocusComponent;
067
068  /**
069   * ProgressPanel constructor.
070   * @param application Application this panel represents
071   */
072  public ProgressPanel(GuiApplication application)
073  {
074    super(application);
075  }
076
077  /** {@inheritDoc} */
078  protected Component createInputPanel()
079  {
080    JPanel panel = new JPanel(new GridBagLayout());
081    panel.setOpaque(false);
082
083    GridBagConstraints gbc = new GridBagConstraints();
084
085    gbc.insets = UIFactory.getEmptyInsets();
086    gbc.anchor = GridBagConstraints.NORTHWEST;
087    gbc.gridwidth = GridBagConstraints.REMAINDER;
088    gbc.weightx = 1.0;
089    gbc.fill = GridBagConstraints.HORIZONTAL;
090
091    progressBarLabel = UIFactory.makeHtmlPane(
092            null,
093            UIFactory.PROGRESS_FONT);
094    progressBarLabel.setOpaque(false);
095    progressBarLabel.setEditable(false);
096    progressBarLabel.setFocusable(false);
097    progressBarLabel.setFocusCycleRoot(false);
098    CustomHTMLEditorKit htmlEditor = new CustomHTMLEditorKit();
099    htmlEditor.addActionListener(new ActionListener()
100    {
101      public void actionPerformed(ActionEvent ev)
102      {
103        // Assume is the authentication button.
104        ButtonEvent be = new ButtonEvent(ev.getSource(),
105            ButtonName.LAUNCH_STATUS_PANEL);
106        notifyButtonListeners(be);
107      }
108    });
109    progressBarLabel.setEditorKit(htmlEditor);
110    String summaryText = UIFactory.applyFontToHtml(
111        String.valueOf(INFO_PROGRESSBAR_INITIAL_LABEL.get()),
112        UIFactory.PROGRESS_FONT);
113    progressBarLabel.setText(summaryText);
114    progressBarLabel.addHyperlinkListener(this);
115    panel.add(progressBarLabel, gbc);
116
117    gbc.insets.top = UIFactory.TOP_INSET_PROGRESS_BAR;
118    gbc.insets.bottom = UIFactory.BOTTOM_INSET_PROGRESS_BAR;
119    panel.add(createProgressBarPanel(), gbc);
120    progressBar.setToolTipText(INFO_PROGRESSBAR_TOOLTIP.get().toString());
121
122    JLabel l =
123        UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
124            INFO_PROGRESS_DETAILS_LABEL.get(),
125            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
126
127    gbc.insets = UIFactory.getEmptyInsets();
128    panel.add(l, gbc);
129
130    JScrollPane scroll = new JScrollPane();
131    detailsTextArea = UIFactory.makeProgressPane(scroll);
132    detailsTextArea.setBackground(
133        UIFactory.CURRENT_STEP_PANEL_BACKGROUND);
134    detailsTextArea.addHyperlinkListener(new HyperlinkListener()
135    {
136      public void hyperlinkUpdate(HyperlinkEvent e)
137      {
138        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
139        {
140          String url = e.getURL().toString();
141          lastText = getFormatter().getFormattedAfterUrlClick(url,
142              lastText);
143          detailsTextArea.setText(lastText.toString());
144        }
145      }
146    });
147    detailsTextArea.setAutoscrolls(true);
148    scroll.setViewportView(detailsTextArea);
149
150    scroll.setBorder(UIFactory.TEXT_AREA_BORDER);
151    scroll.setWheelScrollingEnabled(true);
152    l.setLabelFor(detailsTextArea);
153    gbc.insets.top = UIFactory.TOP_INSET_PROGRESS_TEXTAREA;
154    gbc.fill = GridBagConstraints.BOTH;
155    gbc.weighty = 1.0;
156    panel.add(scroll, gbc);
157
158    addFocusListeners();
159
160    return panel;
161  }
162
163  /** {@inheritDoc} */
164  protected LocalizableMessage getInstructions()
165  {
166    return null;
167  }
168
169  /** {@inheritDoc} */
170  protected LocalizableMessage getTitle()
171  {
172    return INFO_PROGRESS_PANEL_TITLE.get();
173  }
174
175  /** {@inheritDoc} */
176  protected boolean requiresScroll()
177  {
178    return false;
179  }
180
181  /** {@inheritDoc} */
182  public void endDisplay()
183  {
184    if (lastFocusComponent != null)
185    {
186      lastFocusComponent.requestFocusInWindow();
187    }
188  }
189
190  /** {@inheritDoc} */
191  public void displayProgress(ProgressDescriptor descriptor)
192  {
193    ProgressStep status = descriptor.getProgressStep();
194    String summaryText = UIFactory.applyFontToHtml(
195            String.valueOf(descriptor.getProgressBarMsg()),
196            UIFactory.PROGRESS_FONT);
197
198    if (status.isLast()) {
199      progressBar.setVisible(false);
200      progressBarLabel.setFocusable(true);
201      btnCancel.setVisible(false);
202      if (!status.isError()) {
203        summaryText = "<form>"+summaryText+"</form>";
204      }
205    }
206
207    progressBarLabel.setText(summaryText);
208
209    Integer v = descriptor.getProgressBarRatio();
210    if (v != null && v > 0)
211    {
212      progressBar.setIndeterminate(false);
213      progressBar.setValue(v);
214    }
215    lastText = descriptor.getDetailsMsg();
216    detailsTextArea.setText(lastText.toString());
217  }
218
219  /**
220   * Creates the progress bar panel.
221   * @return the created panel.
222   */
223  private JPanel createProgressBarPanel()
224  {
225    JPanel panel = new JPanel(new GridBagLayout());
226    panel.setOpaque(false);
227    GridBagConstraints gbc = new GridBagConstraints();
228    gbc.insets = UIFactory.getEmptyInsets();
229    gbc.fill = GridBagConstraints.HORIZONTAL;
230
231    btnCancel = UIFactory.makeJButton(
232                    INFO_CANCEL_BUTTON_LABEL.get(),
233                    INFO_CANCEL_BUTTON_TOOLTIP.get());
234    btnCancel.addActionListener(new ActionListener() {
235      public void actionPerformed(ActionEvent e) {
236        GuiApplication app = getApplication();
237        QuickSetup qs = getQuickSetup();
238        if (app.confirmCancel(qs)) {
239          app.cancel();
240          btnCancel.setEnabled(false);
241        }
242      }
243    });
244
245    progressBar = new JProgressBar();
246    progressBar.setIndeterminate(true);
247    // The ProgressDescriptor provides the ratio in %
248    progressBar.setMaximum(100);
249
250    gbc.gridwidth = GridBagConstraints.RELATIVE;
251    gbc.weightx = 0.0;
252    panel.add(Box.createHorizontalStrut(UIFactory.PROGRESS_BAR_SIZE), gbc);
253    gbc.gridwidth = GridBagConstraints.REMAINDER;
254    gbc.weightx = 1.0;
255    panel.add(Box.createHorizontalGlue(), gbc);
256
257    gbc.gridwidth = GridBagConstraints.RELATIVE;
258    gbc.weightx = 0.0;
259    panel.add(progressBar, gbc);
260
261    if (getApplication().isCancellable()) {
262      gbc.insets.left = 15;
263      gbc.fill = GridBagConstraints.NONE;
264      gbc.anchor = GridBagConstraints.LINE_START;
265      gbc.gridwidth = 1;
266      panel.add(btnCancel, gbc);
267    }
268
269    gbc.gridwidth = GridBagConstraints.REMAINDER;
270    gbc.fill = GridBagConstraints.HORIZONTAL;
271    gbc.weightx = 1.0;
272    panel.add(Box.createHorizontalGlue(), gbc);
273
274
275
276    return panel;
277  }
278
279  /**
280   * Adds the required focus listeners to the fields.
281   */
282  private void addFocusListeners()
283  {
284    final FocusListener l = new FocusListener()
285    {
286      public void focusGained(FocusEvent e)
287      {
288        lastFocusComponent = e.getComponent();
289      }
290
291      public void focusLost(FocusEvent e)
292      {
293      }
294    };
295
296    JComponent[] comps =
297    {
298        progressBarLabel,
299        progressBar,
300        btnCancel,
301        detailsTextArea
302    };
303    for (JComponent comp : comps) {
304      comp.addFocusListener(l);
305    }
306
307    lastFocusComponent = detailsTextArea;
308  }
309}