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