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