/* * org.openmicroscopy.shoola.util.ui.NotificationDialog * *------------------------------------------------------------------------------ * Copyright (C) 2006-2013 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.util.ui; //Java imports import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; //Third-party libraries import org.jdesktop.swingx.JXHeader; import org.jdesktop.swingx.JXHeader.IconPosition; import org.jdesktop.swingx.painter.RectanglePainter; //Application-internal dependencies /** * A general-purpose modal dialog to display a notification message. * An icon can be specified to display by the message and an <i>OK</i> * button is provided to close the dialog. The dialog is brought up by the * {@link #setVisible(boolean)} method and is automatically disposed after the * user closes it. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author <br>Andrea Falconi      * <a href="mailto:a.falconi@dundee.ac.uk">a.falconi@dundee.ac.uk</a> * @version 2.2 * @since OME2.2 */ public class NotificationDialog extends JDialog { /** Bound property indication to do something with the hyperlink.*/ public static final String HYPERLINK_OPEN_PROPERTY = "hyperlinkOpen"; /** Bound property indication to close the notification dialog.*/ public static final String CLOSE_NOTIFICATION_PROPERTY = "closeNotification"; /** Bound property indication to close the notification dialog.*/ public static final String CANCEL_NOTIFICATION_PROPERTY = "cancelNotification"; /** * The preferred size of the widget that displays the notification message. * Only the part of text that fits into this display area will be displayed. */ protected static final Dimension MSG_AREA_SIZE = new Dimension(300, 50); /** * The size of the invisible components used to separate widgets * horizontally. */ protected static final Dimension H_SPACER_SIZE = new Dimension(20, 1); /** * The size of the invisible components used to separate widgets * vertically. */ protected static final Dimension V_SPACER_SIZE = new Dimension(1, 20); /** * The outmost container. * All other widgets are added to this panel, which, in turn, is then * added to the dialog's content pane. */ protected JXHeader contentPanel; /** Contains the message and the message icon, if any. */ protected JPanel messagePanel; /** Contains the {@link #okButton}. */ protected JPanel controlsPanel; /** Hides and disposes of the dialog. */ protected JButton okButton; /** Cancel any action. */ protected JButton cancelButton; /** Component hosting the UI components. */ private JPanel mainPanel; /** The original message displayed.*/ protected String message; /** * Listener invoking the <code>close</code> method when the dialog * shuts down. */ protected WindowAdapter windowAdapter; /** Creates the various UI components that make up the dialog. */ private void createComponents() { mainPanel = new JPanel(); contentPanel = new JXHeader(); contentPanel.setBackgroundPainter( new RectanglePainter(getBackground(), null)); messagePanel = new JPanel(); messagePanel.setOpaque(true); controlsPanel = new JPanel(); okButton = new JButton("OK"); cancelButton = new JButton("Cancel"); cancelButton.setVisible(false); getRootPane().setDefaultButton(okButton); } /** * Binds the {@link #close() close} action to the exit event generated * either by the close icon or by the {@link #okButton}. */ private void attachListeners() { windowAdapter = new WindowAdapter() { public void windowClosing(WindowEvent we) { close(); } }; addWindowListener(windowAdapter); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { close(); } }); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { cancel(); } }); } /** Cancels any action. */ protected void cancel() { setVisible(false); dispose(); firePropertyChange(CANCEL_NOTIFICATION_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true)); } /** Hides and disposes of the dialog. */ protected void close() { setVisible(false); dispose(); firePropertyChange(CLOSE_NOTIFICATION_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true)); } /** * Builds and lays out the {@link #contentPanel}. * It will contain the notification message along with the message icon, * if any. * * @param msg The notification message. * @param icon The icon to display by the message. * @return See above. */ private JPanel buildCommentPanel(String msg, Icon icon) { contentPanel.setDescription(msg); contentPanel.setOpaque(false); if (icon != null) { contentPanel.setIcon(icon); contentPanel.setIconPosition(IconPosition.LEFT); } return contentPanel; } /** * Builds and lays out the {@link #controlsPanel}. * The {@link #okButton} will be added to this panel. * * @return See above. */ private JPanel buildControlPanel() { controlsPanel.setBorder(null); controlsPanel.add(cancelButton); controlsPanel.add(Box.createRigidArea(H_SPACER_SIZE)); controlsPanel.add(okButton); controlsPanel.add(Box.createRigidArea(H_SPACER_SIZE)); return UIUtilities.buildComponentPanelRight(controlsPanel); } /** * Formats the text as <code>HTML</code> text. * * @param message The message to display. * @return See above. */ private JEditorPane buildHTMLPane(String message) { JEditorPane htmlPane =UIUtilities.buildTextEditorPane(message); htmlPane.addHyperlinkListener(new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { if (HyperlinkEvent.EventType.ACTIVATED.equals( e.getEventType())) { String url; if (e.getURL() == null) url = e.getDescription(); else url = e.getURL().toString(); firePropertyChange(HYPERLINK_OPEN_PROPERTY, null, url); } } }); return htmlPane; } /** * Builds and lays out the {@link #contentPanel}, then adds it to the * content pane. * * @param message The notification message. * @param messageIcon The icon to display by the message. */ private void buildGUI(String message, Icon messageIcon, boolean html) { mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); mainPanel.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.gridwidth = GridBagConstraints.REMAINDER; //end row c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.anchor = GridBagConstraints.WEST; c.gridy = 0; if (html) mainPanel.add(buildHTMLPane(message), c); else mainPanel.add(buildCommentPanel(message, messageIcon), c); c.gridy++; mainPanel.add(Box.createVerticalStrut(5), c); c.gridy++; mainPanel.add(buildControlPanel(), c); getContentPane().add(mainPanel, BorderLayout.CENTER); } /** * Initializes the UI. * * @param message The message to display. * @param messageIcon The icon laid out next to the message. * @param html Indicates to use an pane displaying <code>HTML</code> * content if <code>true</code>, <code>false</code> otherwise. */ private void initiliaze(String message, Icon messageIcon, boolean html) { this.message = message; createComponents(); attachListeners(); setAlwaysOnTop(true); setModal(true); buildGUI(message, messageIcon, html); pack(); } /** * Creates a new dialog. * You have to call {@link #setVisible(boolean)} to actually display it * on screen. * * @param owner The parent window. * @param title The title to display on the title bar. * @param message The notification message. * @param messageIcon An optional icon to display by the message. */ public NotificationDialog(JFrame owner, String title, String message, Icon messageIcon) { super(owner, title); //setResizable(false); //Believe it or not the icon from owner won't be displayed if the //dialog is not resizable. initiliaze(message, messageIcon, false); } /** * Creates a new dialog. * You have to call {@link #setVisible(boolean)} to actually display it * on screen. * * @param owner The parent window. * @param title The title to display on the title bar. * @param message The notification message. * @param messageIcon An optional icon to display by the message. */ public NotificationDialog(JDialog owner, String title, String message, Icon messageIcon) { super(owner, title); initiliaze(message, messageIcon, false); } /** * Creates a new dialog. * You have to call {@link #setVisible(boolean)} to actually display it * on screen. * * @param title The title to display on the title bar. * @param message The notification message. * @param messageIcon An optional icon to display by the message. */ public NotificationDialog(String title, String message, Icon messageIcon) { setTitle(title); initiliaze(message, messageIcon, false); } /** * Creates a new dialog. * You have to call {@link #setVisible(boolean)} to actually display it * on screen. * * @param owner The parent window. * @param title The title to display on the title bar. * @param message The notification message. * @param html Indicates to use an pane displaying <code>HTML</code> * content if <code>true</code>, <code>false</code> otherwise. */ public NotificationDialog(JDialog owner, String title, String message, boolean html) { super(owner, title); //setResizable(false); //Believe it or not the icon from owner won't be displayed if the //dialog is not resizable. initiliaze(message, null, html); } /** * Creates a new dialog. * You have to call {@link #setVisible(boolean)} to actually display it * on screen. * * @param owner The parent window. * @param title The title to display on the title bar. * @param message The notification message. * @param html Indicates to use an pane displaying <code>HTML</code> * content if <code>true</code>, <code>false</code> otherwise. */ public NotificationDialog(JFrame owner, String title, String message, boolean html) { super(owner, title); //setResizable(false); //Believe it or not the icon from owner won't be displayed if the //dialog is not resizable. initiliaze(message, null, html); } }