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 2008 Sun Microsystems, Inc.
025 *      Portions Copyright 2013-2014 ForgeRock AS.
026 */
027
028package org.opends.quicksetup.ui;
029
030import org.forgerock.i18n.LocalizableMessage;
031import static org.opends.messages.QuickSetupMessages.*;
032
033import java.awt.Dimension;
034import java.awt.GridBagConstraints;
035import java.awt.GridBagLayout;
036import java.awt.event.ActionEvent;
037import java.awt.event.ActionListener;
038
039import javax.swing.Box;
040import javax.swing.JButton;
041import javax.swing.JDialog;
042import javax.swing.JEditorPane;
043import javax.swing.JFrame;
044import javax.swing.JLabel;
045import javax.swing.JPanel;
046import javax.swing.JProgressBar;
047import javax.swing.JScrollPane;
048import javax.swing.event.HyperlinkEvent;
049import javax.swing.event.HyperlinkListener;
050
051import org.opends.quicksetup.event.MinimumSizeComponentListener;
052import org.opends.quicksetup.util.HtmlProgressMessageFormatter;
053import org.opends.quicksetup.util.ProgressMessageFormatter;
054
055/**
056 * This panel is used to show the progress of the start/stop/restart operations.
057 *
058 */
059public class ProgressDialog extends JDialog
060{
061  private static final long serialVersionUID = 8635080171100378470L;
062
063  private JEditorPane progressBarLabel;
064
065  private JProgressBar progressBar;
066
067  private JEditorPane detailsTextArea;
068
069  private LocalizableMessage lastText;
070
071  private JFrame parent;
072
073  private JButton closeButton;
074
075  private LocalizableMessage panelTitle = INFO_PROGRESS_TITLE.get();
076
077  private ProgressMessageFormatter formatter =
078    new HtmlProgressMessageFormatter();
079
080  /**
081   * ProgressDialog constructor.
082   * @param frame the parent frame for this dialog.
083   */
084  public ProgressDialog(JFrame frame)
085  {
086    super(frame);
087    this.parent = frame;
088    setTitle(INFO_PROGRESS_DIALOG_TITLE.get().toString());
089    createLayout();
090  }
091
092  /**
093   * Prepares size for this dialog.
094   *
095   */
096  public void pack()
097  {
098    /*
099     * TODO: find a way to calculate this dynamically.
100     */
101    setPreferredSize(new Dimension(500, 300));
102    addComponentListener(new MinimumSizeComponentListener(this, 500, 300));
103    super.pack();
104    closeButton.requestFocusInWindow();
105    getRootPane().setDefaultButton(closeButton);
106  }
107
108  /**
109   * Returns the parent for this dialog.
110   * @return the parent for this dialog.
111   */
112  public JFrame getFrame()
113  {
114    return parent;
115  }
116
117  /**
118   * Returns the title of the panel.
119   * @return the title of the panel
120   */
121  public LocalizableMessage getPanelTitle()
122  {
123    return panelTitle;
124  }
125
126  /**
127   * Sets the enable state of the close button.
128   * @param enable whether to enable or disable the button.
129   */
130  public void setCloseButtonEnabled(boolean enable)
131  {
132    closeButton.setEnabled(enable);
133  }
134
135  /**
136   * Sets the text in the summary label.  The text can be in HTML format.
137   * @param text the text to be set.
138   */
139  public void setSummary(LocalizableMessage text)
140  {
141    if (text != null) {
142      progressBarLabel.setText(text.toString());
143    } else {
144      progressBarLabel.setText(null);
145    }
146  }
147
148  /**
149   * Sets the text in the details text pane.  The text can be in HTML format.
150   * @param text the text to be set.
151   */
152  public void setDetails(LocalizableMessage text)
153  {
154    if (text != null) {
155      detailsTextArea.setText(text.toString());
156    } else {
157      detailsTextArea.setText(null);
158    }
159  }
160
161  /**
162   * Returns the formatter that will be used to display the messages in this
163   * panel.
164   * @return the formatter that will be used to display the messages in this
165   * panel.
166   */
167  private ProgressMessageFormatter getFormatter()
168  {
169    if (formatter == null)
170    {
171      formatter = new HtmlProgressMessageFormatter();
172    }
173    return formatter;
174  }
175
176  /**
177   * Creates the layout of the dialog panel.
178   *
179   */
180  private void createLayout()
181  {
182    /* Create title panel */
183    JPanel titlePanel = new JPanel(new GridBagLayout());
184    titlePanel.setOpaque(false);
185    GridBagConstraints gbc = new GridBagConstraints();
186    gbc.anchor = GridBagConstraints.NORTHWEST;
187    gbc.fill = GridBagConstraints.HORIZONTAL;
188    gbc.weightx = 0.0;
189    gbc.gridwidth = GridBagConstraints.RELATIVE;
190
191    LocalizableMessage title = getPanelTitle();
192
193    JLabel l =
194        UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, title,
195            UIFactory.TextStyle.TITLE);
196    l.setOpaque(false);
197    titlePanel.add(l, gbc);
198
199    gbc.weightx = 1.0;
200    gbc.gridwidth = GridBagConstraints.REMAINDER;
201    titlePanel.add(Box.createHorizontalGlue(), gbc);
202
203    /* Create input panel. */
204    JPanel mainPanel = new JPanel(new GridBagLayout());
205    mainPanel.setOpaque(false);
206    gbc.insets = UIFactory.getEmptyInsets();
207    gbc.anchor = GridBagConstraints.NORTHWEST;
208    gbc.gridwidth = GridBagConstraints.REMAINDER;
209    gbc.weightx = 1.0;
210    gbc.fill = GridBagConstraints.HORIZONTAL;
211    mainPanel.add(titlePanel, gbc);
212
213    gbc.insets.top = UIFactory.TOP_INSET_INSTRUCTIONS_SUBPANEL;
214    progressBarLabel =
215        UIFactory.makeHtmlPane(INFO_PROGRESSBAR_INITIAL_LABEL.get(),
216            UIFactory.PROGRESS_FONT);
217    progressBarLabel.setOpaque(false);
218    progressBarLabel.setEditable(false);
219    mainPanel.add(progressBarLabel, gbc);
220
221    gbc.insets.top = UIFactory.TOP_INSET_PROGRESS_BAR;
222    gbc.insets.bottom = UIFactory.BOTTOM_INSET_PROGRESS_BAR;
223    mainPanel.add(createProgressBarPanel(), gbc);
224    progressBar.setToolTipText(INFO_PROGRESSBAR_TOOLTIP.get().toString());
225
226    l =
227        UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
228            INFO_PROGRESS_DETAILS_LABEL.get(),
229            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
230
231    gbc.insets = UIFactory.getEmptyInsets();
232    mainPanel.add(l, gbc);
233
234    JScrollPane scroll = new JScrollPane();
235    detailsTextArea = UIFactory.makeProgressPane(scroll);
236    detailsTextArea.setBackground(
237        UIFactory.CURRENT_STEP_PANEL_BACKGROUND);
238    detailsTextArea.addHyperlinkListener(new HyperlinkListener()
239    {
240      public void hyperlinkUpdate(HyperlinkEvent e)
241      {
242        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
243        {
244          String url = e.getURL().toString();
245          lastText = getFormatter().getFormattedAfterUrlClick(url,
246              lastText);
247          setDetails(lastText);
248        }
249      }
250    });
251    detailsTextArea.setAutoscrolls(true);
252    scroll.setViewportView(detailsTextArea);
253
254    scroll.setBorder(UIFactory.TEXT_AREA_BORDER);
255    scroll.setWheelScrollingEnabled(true);
256    l.setLabelFor(detailsTextArea);
257    gbc.insets.top = UIFactory.TOP_INSET_PROGRESS_TEXTAREA;
258    gbc.fill = GridBagConstraints.BOTH;
259    gbc.weighty = 1.0;
260    mainPanel.add(scroll, gbc);
261
262    /* Create buttons panel */
263    JPanel buttonsPanel = new JPanel(new GridBagLayout());
264    buttonsPanel.setBackground(UIFactory.DEFAULT_BACKGROUND);
265    gbc.fill = GridBagConstraints.HORIZONTAL;
266    gbc.weightx = 1.0;
267    gbc.insets = UIFactory.getEmptyInsets();
268    gbc.gridwidth = GridBagConstraints.RELATIVE;
269    buttonsPanel.add(Box.createHorizontalGlue(), gbc);
270    closeButton =
271        UIFactory.makeJButton(INFO_CLOSE_BUTTON_LABEL.get(),
272            INFO_CLOSE_PROGRESS_BUTTON_TOOLTIP.get());
273    gbc.fill = GridBagConstraints.NONE;
274    gbc.weightx = 0.0;
275    gbc.gridwidth = GridBagConstraints.REMAINDER;
276    buttonsPanel.add(closeButton, gbc);
277    closeButton.addActionListener(new ActionListener()
278    {
279      public void actionPerformed(ActionEvent ev)
280      {
281        dispose();
282      }
283    });
284
285    JPanel p = new JPanel(new GridBagLayout());
286    p.setBackground(UIFactory.DEFAULT_BACKGROUND);
287    gbc.insets = UIFactory.getEmptyInsets();
288    gbc.fill = GridBagConstraints.BOTH;
289    gbc.gridwidth = GridBagConstraints.REMAINDER;
290    gbc.weightx = 1.0;
291    gbc.weighty = 1.0;
292    gbc.insets = UIFactory.getEmptyInsets();
293    JPanel p1 = new JPanel(new GridBagLayout());
294    p1.setBackground(UIFactory.CURRENT_STEP_PANEL_BACKGROUND);
295    p1.setBorder(UIFactory.DIALOG_PANEL_BORDER);
296    gbc.insets = UIFactory.getCurrentStepPanelInsets();
297    p1.add(mainPanel, gbc);
298    gbc.insets = UIFactory.getEmptyInsets();
299    p.add(p1, gbc);
300    gbc.weighty = 0.0;
301    gbc.insets = UIFactory.getButtonsPanelInsets();
302    p.add(buttonsPanel, gbc);
303
304    getContentPane().add(p);
305  }
306
307  /**
308   * Creates the progress bar panel.
309   * @return the created panel.
310   */
311  private JPanel createProgressBarPanel()
312  {
313    JPanel panel = new JPanel(new GridBagLayout());
314    panel.setOpaque(false);
315    GridBagConstraints gbc = new GridBagConstraints();
316    gbc.insets = UIFactory.getEmptyInsets();
317    gbc.fill = GridBagConstraints.HORIZONTAL;
318
319    progressBar = new JProgressBar();
320    progressBar.setIndeterminate(true);
321    // The ProgressDescriptor provides the ratio in %
322    progressBar.setMaximum(100);
323
324    gbc.gridwidth = GridBagConstraints.RELATIVE;
325    gbc.weightx = 0.0;
326    panel.add(Box.createHorizontalStrut(UIFactory.PROGRESS_BAR_SIZE), gbc);
327    gbc.gridwidth = GridBagConstraints.REMAINDER;
328    gbc.weightx = 1.0;
329    panel.add(Box.createHorizontalGlue(), gbc);
330
331    gbc.gridwidth = GridBagConstraints.RELATIVE;
332    gbc.weightx = 0.0;
333    //panel.add(progressBar, gbc);
334    gbc.gridwidth = GridBagConstraints.REMAINDER;
335    gbc.weightx = 1.0;
336    panel.add(Box.createHorizontalGlue(), gbc);
337
338    return panel;
339  }
340
341  /**
342   * Method written for testing purposes.
343   * @param args the arguments to be passed to the test program.
344   */
345  public static void main(String[] args)
346  {
347    try
348    {
349      ProgressDialog dlg = new ProgressDialog(new JFrame());
350      dlg.pack();
351      dlg.setVisible(true);
352    } catch (Exception ex)
353    {
354      ex.printStackTrace();
355    }
356  }
357}