/Users/richardallenbair/Documents/Source/Projects/swingx-work/jxerrorpane/swingx/src/java/org/jdesktop/swingx/JXErrorPane_API.java
/*
 * $Id: JXErrorPane_API.html 1530 2006-10-30 20:20:34Z rbair $
 *
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package org.jdesktop.swingx;

import java.awt.Component;
import java.lang.reflect.InvocationTargetException;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.SwingUtilities;
import org.jdesktop.swingx.error.ErrorReporter;
import org.jdesktop.swingx.error.ErrorInfo;
import org.jdesktop.swingx.plaf.ErrorPaneUI;
import org.jdesktop.swingx.plaf.JXErrorPaneAddon;
import org.jdesktop.swingx.plaf.LookAndFeelAddons;

/**
 * <p>JXErrorPane is a common error component suitable for displaying errors,
 * warnings, and exceptional application behavior to users.</p>
 * 
 * <p>User interaction with the <code>JXErrorPane</code> includes the ability to
 * view details associated with the error. This is the primary feature that differentiates
 * <code>JXErrorPane</code> from <code>JOptionPane</code>. In addition,
 * <code>JXErrorPane</code> specializes in handling unrecoverable errors. If you
 * need an error dialog that allows the user to take some action to recover
 * from an error (such as "Repair Disk", "Replace All", etc) then you should
 * use <code>JOptionPane</code>.</p>
 * 
 * <p>Data and application state associated with an error are encapsulated
 * in the {@link ErrorInfo} class. The <code>JXErrorPane</code> displays the
 * data contained in the <code>ErrorInfo</code>. In addition,
 * <code>ErrorInfo</code> is passed to the {@link ErrorReporter} if the user decides
 * to report the incident.</p>
 * 
 * <h2>Basic Usage</h2>
 * <p>Typically, the <code>JXErrorPane</code>
 * is not created and displayed directly. Instead, one of the static showXXX methods
 * are called that create and display the <code>JXErrorPane</code> in a 
 * <code>JDialog</code>, <code>JFrame</code>, or <code>JInternalFrame</code>.</p>
 * 
 * <p>These static showXXX methods all follow the same pattern, namely (
 * where XXX could be one of Dialog, Frame, or InternalFrame):
 * <ul>
 *  <li><b>showXXX(Throwable e)</b>: This usage allows you to show a default error
 *      window, detailing the error</li>
 *  <li><b>showXXX(Component owner, ErrorInfo info)</b>: This usage shows an
 *      error dialog based on the given <code>ErrorInfo</code>. The component
 *      argument is the component over which the dialog should be centered.</li>
 *  <li><b>showXXX(Component owner, JXErrorPane pane)</b>: This usage shows
 *      an error dialog using the given error pane. This allows you to completely
 *      modify the pane (perhaps installing a custom UI delegate, etc) to present
 *      to the user</li>
 *  <li><b>createXXX(Component owner, JXErrorPane pane)</b>: Creates and returns
 *      a dialog for presenting the given <code>JXErrorPane</code>, but does not
 *      show it. This allows the developer to modify properties of the dialog
 *      prior to display</li>
 * </ul></p>
 * 
 * <p>Following are some examples and further discussion regarding some of these
 * static methods. Example of the most basic usage:
 * <pre><code>
 *      try {
 *          //do stuff.... something throws an exception in here
 *      } catch (Exception e) {
 *          JXErrorPane.showDialog(e);
 *      }
 * </code></pre>. Alternatively there are <code>showFrame</code> and
 * <code>showInternalFrame</code> variants of each of the <code>showDialog</code>
 * methods described in this API.</p>
 *
 * <p>While this is the simplest usage, it is not the recommended approach for
 * most errors since it yields the most difficult messages for users to understand.
 * Instead it is recommended to provide a more useful message for users. For example:
 * <pre><code>
 *      URL url = null;
 *      try {
 *          url = new URL(userSuppliedUrl);
 *      } catch (MalformedURLException e) {
 *          String msg = "The web resource you entered is not formatted"
 *                      + " correctly.";
 *          String details = "&lt;html&gt;Web resources should begin with \"http://\""
 *                      + " and cannot contain any spaces. Below are a few"
 *                      + " more guidelines.&lt;ul&gt;"
 *                      + getURLGuidelines()
 *                      + "&lt;/ul&gt;&lt;/html&gt;";
 *          JXErrorPane.showDialog(myWindow, "Unknown Resource", msg, details, e);
 *          return false;
 *      }
 * </code></pre></p>
 * 
 * <p>Before showing the <code>JXErrorPane</code> in a frame or dialog, you may modify
 * the appearance and behavior of the <code>JXErrorPane</code> by setting one or more of its bean
 * properties. For example, to modify the icon shown with a particular
 * instance of a <code>JXErrorPane</code>, you might do the following:
 * <pre><code>
 *      JXErrorPane pane = new JXErrorPane();
 *      pane.setErrorIcon(myErrorIcon);
 *      pane.setErrorInfo(new ErrorInfo("Fatal Error", exception));
 *      JXErrorPane.showDialog(null, pane);
 * </code></pre></p>
 *
 * <p><code>JXErrorPane</code> may also be configured with a "Report" button which allows
 * the user to send a bug report, typically through email. This is done through
 * the pluggable {@link ErrorReporter} class. Simply instantiate
 * {@link EmailErrorReporter} or some custom
 * subclass of <code>ErrorReporter</code> and pass the instance into the
 * {@link #setErrorReporter} method.</p>
 *
 * <p><code>JXErrorPane</code> can also be used for displaying fatal error messages to
 * users. Fatal messages indicate a serious error in the application that cannot
 * be corrected and that must result in the termination of the application. 
 * After the close of a fatal error dialog, the application should
 * automatically exit. Fatal messages are identified by the <code>Level</code>
 * of the <code>ErrorInfo</code> being {@link ErrorLevel}<code>.FATAL</code>.</p>
 * 
 * <p>By default, when Fatal error dialogs are closed the application exits with
 * a code of "1". In other words, <code>System.exit(1)</code>. If you wish to implement
 * custom handling, you can replace the default fatal action in the <code>ActionMap</code>
 * of the <code>JXErrorPane</code> instance. If you specify a custom fatal 
 * action, then the default action of calling
 * System.exit will not occur. You are therefore responsible for shutting down
 * the application.</p>
 * 
 * <h2>UI Default Keys</h2>
 * <p>TODO</p>
 * JXErrorPane.errorIcon
 *      or, if not specified, JOptionPane.errorIcon
 * JXErrorPane.warningIcon
 *      or, if not specified, JOptionPane.warningIcon
 * JXErrorPane.details_contract_text (ignored on Mac OS X)
 * JXErrorPane.details_expand_text (ignored on Mac OS X)
 * JXErrorPane.mac.details_contract_text
 * JXErrorPane.mac.details_expand_text
 * Tree.expandedIcon (on Mac OS X)
 * Tree.collapsedIcon (on Mac OS X)
 * 
 * <h2>Customizing the Look and Feel</h2>
 * <p>TODO</p>
 * 
 * @author Richard Bair
 * @author Alexander Zuev
 * @author Shai Almog
 */
public class JXErrorPane extends JComponent {
    //---------------------------------------------------- static properties
    /**
     * Name of the Action used for reporting errors
     */
    public static final String REPORT_ACTION = "report-action";
    /**
     * Name of the Action used for fatal errors
     */
    public static final String FATAL_ACTION = "fatal-action";
    
    //--------------------------------------------------------- constructors

    /**
     * Create a new <code>JXErrorPane</code>.
     */
    public JXErrorPane();
    
    //-------------------------------------------- public methods/properties
    
    /**
     * Sets the ErrorInfo for this dialog
     *
     * @param info ErrorInfo that incorporates all the details about the error
     */
    public void setErrorInfo(ErrorInfo info);
    
    /**
     * Gets the <code>JXErrorPane</code>'s <code>ErrorInfo</code>
     *
     * @return <code>ErrorInfo</code> assigned to this dialog
     */
    public ErrorInfo getErrorInfo();
    
    /**
     * Specifies the icon to use
     *
     * @param icon the Icon to use. May be null.
     */
    public void setIcon(Icon icon);
    
    /**
     * Returns the Icon used
     *
     * @return the Icon
     */
    public Icon getIcon();
    
    /**
     * Sets the {@link ErrorReporter} delegate to use. This delegate is called
     * automatically when the report action is fired.
     * 
     * @param reporter the ErrorReporter to use. If null, the report button will
     *        not be shown in the error dialog.
     */
    public void setErrorReporter(ErrorReporter reporter);
    
    /**
     * Gets the {@link ErrorReporter} delegate in use.
     * 
     * @return the ErrorReporter. May be null.
     */
    public ErrorReporter getErrorReporter();
    
    //------------------------------------------------------- static methods
    
    /**
     * <p>Constructs and shows the error dialog for the given exception.  The 
     * exceptions message will be the errorMessage, and the stacktrace will form 
     * the details for the error dialog.</p>
     * 
     * <p>This method may be called from any thread. It will actually show the error
     * dialog on the AWT event dispatch thread. This method blocks. If called
     * on the EDT, the dialog shown will be modal. Otherwise, this thread will
     * block until the error dialog has been shown and hidden on the EDT.</p>
     * 
     * @param e Exception that contains information about the error cause and stack trace
     */
    public static void showDialog(Throwable e);
    
    /**
     * <p>Constructs and shows the error dialog, using the given
     * <code>ErrorInfo</code> to initialize the view.</p>
     * 
     * <p>This method may be called from any thread. It will actually show the error
     * dialog on the AWT event dispatch thread. This method blocks. If called
     * on the EDT, the dialog shown will be modal. Otherwise, this thread will
     * block until the error dialog has been shown and hidden on the EDT.</p>
     * 
     * @param owner Owner of this error dialog. Determines the Window in which the dialog
     *          is displayed; if the <code>owner</code> has
     *          no <code>Window</code>, a default <code>Frame</code> is used
     * @param info <code>ErrorInfo</code> that incorporates all the information about the error
     */
    public static void showDialog(Component owner, ErrorInfo info);
    
    /**
     * <p>Constructs and shows the error dialog, using the given
     * <code>JXErrorPane</code> for the view portion of the dialog.</p>
     * 
     * <p>This method may be called from any thread. It will actually show the error
     * dialog on the AWT event dispatch thread. This method blocks. If called
     * on the EDT, the dialog shown will be modal. Otherwise, this thread will
     * block until the error dialog has been shown and hidden on the EDT.</p>
     * 
     * @param owner Owner of this error dialog. Determines the Window in which the dialog
     *          is displayed; if the <code>owner</code> has
     *          no <code>Window</code>, a default <code>Frame</code> is used
     * @param pane <code>JXErrorPane</code> which will form the content area
     *        of the dialog.
     */
    public static void showDialog(final Component owner, final JXErrorPane pane);
    
    /**
     * <p>Constructs and returns an error dialog, using the given
     * <code>JXErrorPane</code> for the view portion of the dialog.</p>
     * 
     * <p>This method may be called from any thread. It does not block. The
     * caller is responsible for ensuring that the dialog is shown and manipulated
     * on the AWT event dispatch thread. A common way to do this is to use
     * <code>SwingUtilities.invokeAndWait</code> or 
     * <code>SwingUtilities.invokeLater()</code>.</p>
     * 
     * @param owner Owner of this error dialog. Determines the Window in which the dialog
     *          is displayed; if the <code>owner</code> has
     *          no <code>Window</code>, a default <code>Frame</code> is used
     * @param pane <code>JXErrorPane</code> which will form the content area
     *        of the dialog.
     * @return a <code>JDialog</code> configured to display the error.
     */
    public static JDialog createDialog(Component owner, JXErrorPane pane);
    
    /**
     * <p>Constructs and shows the error frame for the given exception.  The 
     * exceptions message will be the errorMessage, and the stacktrace will form 
     * the details for the error dialog.</p>
     * 
     * <p>This method may be called from any thread. It will actually show the error
     * dialog on the AWT event dispatch thread. This method blocks. If called
     * on the EDT, the frame shown will be modal. Otherwise, this thread will
     * block until the error frame has been shown and hidden on the EDT.</p>
     * 
     * @param e Exception that contains information about the error cause and stack trace
     */
    public static void showFrame(Throwable e);
    
    /**
     * <p>Constructs and shows the error frame, using the given
     * <code>ErrorInfo</code> to initialize the view.</p>
     * 
     * <p>This method may be called from any thread. It will actually show the error
     * dialog on the AWT event dispatch thread. This method blocks. If called
     * on the EDT, the frame shown will be modal. Otherwise, this thread will
     * block until the error frame has been shown and hidden on the EDT.</p>
     * 
     * @param owner Owner of this error frame. Determines the Window in which the frame
     *          is displayed; if the <code>owner</code> has
     *          no <code>Window</code>, a default <code>Frame</code> is used
     * @param info <code>ErrorInfo</code> that incorporates all the information about the error
     */
    public static void showFrame(Component owner, ErrorInfo info);
    
    /**
     * <p>Constructs and shows the error frame, using the given
     * <code>JXErrorPane</code> for the view portion of the frame.</p>
     * 
     * <p>This method may be called from any thread. It will actually show the error
     * dialog on the AWT event dispatch thread. This method blocks. If called
     * on the EDT, the frame shown will be modal. Otherwise, this thread will
     * block until the error frame has been shown and hidden on the EDT.</p>
     * 
     * @param owner Owner of this error frame. Determines the Window in which the dialog
     *          is displayed; if the <code>owner</code> has
     *          no <code>Window</code>, a default <code>Frame</code> is used
     * @param pane <code>JXErrorPane</code> which will form the content area
     *        of the frame.
     */
    public static void showFrame(final Component owner, final JXErrorPane pane);
    
    /**
     * <p>Constructs and returns an error frame, using the given
     * <code>JXErrorPane</code> for the view portion of the frame.</p>
     * 
     * <p>This method may be called from any thread. It does not block. The
     * caller is responsible for ensuring that the frame is shown and manipulated
     * on the AWT event dispatch thread. A common way to do this is to use
     * <code>SwingUtilities.invokeAndWait</code> or 
     * <code>SwingUtilities.invokeLater()</code>.</p>
     * 
     * @param owner Owner of this error frame. Determines the Window in which the frame
     *          is displayed; if the <code>owner</code> has
     *          no <code>Window</code>, a default <code>Frame</code> is used
     * @param pane <code>JXErrorPane</code> which will form the content area
     *        of the frame.
     * @return a <code>JFrame</code> configured to display the error.
     */
    public static JFrame createFrame(Component owner, JXErrorPane pane);
    
    /**
     * <p>Constructs and shows the error frame for the given exception.  The 
     * exceptions message will be the errorMessage, and the stacktrace will form 
     * the details for the error dialog.</p>
     * 
     * <p>This method may be called from any thread. It will actually show the error
     * dialog on the AWT event dispatch thread. This method blocks. If called
     * on the EDT, the frame shown will be modal. Otherwise, this thread will
     * block until the error frame has been shown and hidden on the EDT.</p>
     * 
     * @param e Exception that contains information about the error cause and stack trace
     */
    public static void showInternalFrame(Throwable e);
    
    /**
     * <p>Constructs and shows the error frame, using the given
     * <code>ErrorInfo</code> to initialize the view.</p>
     * 
     * <p>This method may be called from any thread. It will actually show the error
     * dialog on the AWT event dispatch thread. This method blocks. If called
     * on the EDT, the frame shown will be modal. Otherwise, this thread will
     * block until the error frame has been shown and hidden on the EDT.</p>
     * 
     * @param owner Owner of this error frame. Determines the Window in which the frame
     *          is displayed; if the <code>owner</code> has
     *          no <code>Window</code>, a default <code>Frame</code> is used
     * @param info <code>ErrorInfo</code> that incorporates all the information about the error
     */
    public static void showInternalFrame(Component owner, ErrorInfo info);
    
    /**
     * <p>Constructs and shows the error frame, using the given
     * <code>JXErrorPane</code> for the view portion of the frame.</p>
     * 
     * <p>This method may be called from any thread. It will actually show the error
     * dialog on the AWT event dispatch thread. This method blocks. If called
     * on the EDT, the frame shown will be modal. Otherwise, this thread will
     * block until the error frame has been shown and hidden on the EDT.</p>
     * 
     * @param owner Owner of this error frame. Determines the Window in which the dialog
     *          is displayed; if the <code>owner</code> has
     *          no <code>Window</code>, a default <code>Frame</code> is used
     * @param pane <code>JXErrorPane</code> which will form the content area
     *        of the frame.
     */
    public static void showInternalFrame(final Component owner, final JXErrorPane pane);
    
    /**
     * <p>Constructs and returns an error frame, using the given
     * <code>JXErrorPane</code> for the view portion of the frame.</p>
     * 
     * <p>This method may be called from any thread. It does not block. The
     * caller is responsible for ensuring that the frame is shown and manipulated
     * on the AWT event dispatch thread. A common way to do this is to use
     * <code>SwingUtilities.invokeAndWait</code> or 
     * <code>SwingUtilities.invokeLater()</code>.</p>
     * 
     * @param owner Owner of this error frame. Determines the Window in which the frame
     *          is displayed; if the <code>owner</code> has
     *          no <code>Window</code>, a default <code>Frame</code> is used
     * @param pane <code>JXErrorPane</code> which will form the content area
     *        of the frame.
     * @return a <code>JInternalFrame</code> configured to display the error.
     */
    public static JInternalFrame createInternalFrame(Component owner, JXErrorPane pane);
}