001/* Base class for swing applets.
002
003 Copyright (c) 1998-2014 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.gui;
029
030import java.awt.Color;
031import java.io.ByteArrayOutputStream;
032import java.io.PrintWriter;
033
034import javax.swing.JApplet;
035
036import ptolemy.util.MessageHandler;
037
038///////////////////////////////////////////////////////////////////
039//// BasicJApplet
040
041/**
042 Base class for swing applets.  This class provides basic management
043 for background colors, a standardized mechanism for reporting errors
044 and exceptions, and a minimal amount of information about the
045 applet.
046 <p>
047 The applet parameter is:
048 <ul>
049 <li>
050 <i>background</i>: The background color, typically given as a hex
051 number of the form "#<i>rrggbb</i>" where <i>rr</i> gives the red
052 component, <i>gg</i> gives the green component, and <i>bb</i> gives
053 the blue component.
054 </ul>
055
056 @author  Edward A. Lee
057 @version $Id$
058 @since Ptolemy II 0.4
059 @Pt.ProposedRating Red (eal)
060 @Pt.AcceptedRating Red (eal)
061 */
062@SuppressWarnings("serial")
063public class BasicJApplet extends JApplet {
064    ///////////////////////////////////////////////////////////////////
065    ////                         public methods                    ////
066
067    /** Return generic applet information.
068     *  @return A string giving minimal information about Ptolemy II.
069     */
070    @Override
071    public String getAppletInfo() {
072        return "Ptolemy II swing-based applet.\n"
073                + "Ptolemy II comes from UC Berkeley, Department of EECS.\n"
074                + "See http://ptolemy.eecs.berkeley.edu/ptolemyII";
075    }
076
077    /** Describe the applet parameters. Derived classes should override
078     *  this and append their own parameters.  The protected method
079     *  _concatStringArrays() is provided to make this easy to do.
080     *  @return An array describing the applet parameters.
081     */
082    @Override
083    public String[][] getParameterInfo() {
084        String[][] pinfo = {
085                { "background", "#RRGGBB", "color of the background" }, };
086        return pinfo;
087    }
088
089    /** Initialize the applet. This method is called by the browser
090     *  or applet viewer to inform this applet that it has been
091     *  loaded into the system. It is always called before
092     *  the first time that the start() method is called.
093     *  In this base class, this method reads the background color parameter.
094     *  If the background color parameter has not been set, then the
095     *  background color is set to white.
096     */
097    @Override
098    public void init() {
099        UndeferredGraphicalMessageHandler.setContext(this);
100        MessageHandler.setMessageHandler(new GraphicalMessageHandler());
101
102        // Process the background parameter.
103        _background = null;
104
105        try {
106            String colorSpecification = getParameter("background");
107
108            if (colorSpecification != null) {
109                _background = Color.decode(colorSpecification);
110            }
111        } catch (Exception ex) {
112            report("Warning: background parameter failed: ", ex);
113        }
114
115        setBackground(_background);
116        getRootPane().setBackground(_background);
117        getContentPane().setBackground(_background);
118    }
119
120    /** Report an exception.  This prints a message to the standard error
121     *  stream, followed by the stack trace, but displays on the screen
122     *  only the error message associated with the exception.
123     *  @param throwable The throwable that triggered the error.
124     */
125    public void report(Throwable throwable) {
126        report(MessageHandler.shortDescription(throwable)
127                + " thrown by applet.", throwable);
128    }
129
130    /** Report a message to the user.
131     *  This shows the message on the browser's status bar.
132     *  @param message The message to report.
133     */
134    public void report(String message) {
135        try {
136            showStatus(message);
137        } catch (Throwable throwable) {
138            // Under JDK 1.4.2_04, we get NullPointerExceptions
139            System.err.println("showStatus() threw a NullPointerException\n"
140                    + "This can happen if the Applet has already exited\n "
141                    + "because of an error or exception.\n");
142            throwable.printStackTrace();
143        }
144    }
145
146    /** Report an exception with an additional message.
147     *  This prints a message to standard error, followed by the stack trace,
148     *  and pops up a window with the message and the message of the
149     *  exception.
150     *  @param message The message to report.
151     *  @param throwable The throwable that triggered the error.
152     */
153    public void report(String message, Throwable throwable) {
154        // In JDK1.3.1, we can't copy the contents of the window that the
155        // applet pops up, so be sure to print the stack trace to stderr.
156        throwable.printStackTrace();
157        MessageHandler.error(message, throwable);
158
159        try {
160            showStatus("exception occurred.");
161        } catch (Throwable throwable2) {
162            // Under JDK 1.4.2_04, we get NullPointerExceptions
163            System.err.println("showStatus() threw an exception\n"
164                    + _stackTraceToString(throwable2)
165                    + "This can happen if the Applet has already exited\n "
166                    + "because of an error or exception.\n"
167                    + "The original error or exception was:\n"
168                    + _stackTraceToString(throwable));
169        }
170    }
171
172    ///////////////////////////////////////////////////////////////////
173    ////                         protected methods                 ////
174
175    /** Concatenate two parameter info string arrays and return the result.
176     *  This is provided to make it easy for derived classes to override
177     *  the getParameterInfo() method. The returned array has length equal
178     *  to the sums of the lengths of the two arguments, and containing
179     *  the arrays contained by the arguments.
180     *
181     *  @param first The first string array.
182     *  @param second The second string array.
183     *  @return A concatenated string array.
184     */
185    protected String[][] _concatStringArrays(String[][] first,
186            String[][] second) {
187        String[][] newInfo = new String[first.length + second.length][];
188        System.arraycopy(first, 0, newInfo, 0, first.length);
189        System.arraycopy(second, 0, newInfo, first.length, second.length);
190        return newInfo;
191    }
192
193    /** Get the background color as set by the "background" applet parameter.
194     *  This is protected so that derived classes can find out what the
195     *  background color is. Derived classes may wish to know the
196     *  color so they can match it in some of their components.
197     *  @return The background color.
198     *  @deprecated Use the public method getBackground() instead.
199     */
200    @Deprecated
201    protected Color _getBackground() {
202        return _background;
203    }
204
205    /** Get the stack trace and return as a string.
206     *  @param throwable The exception for which we want the stack trace.
207     *  @return The stack trace.
208     */
209    protected String _stackTraceToString(Throwable throwable) {
210        // For a similar method, see
211        // ptolemy.kernel.util.KernelException.stackTraceToString()
212        // We do not use that method here because we do not want to
213        // make this class depend on the kernel.
214        ByteArrayOutputStream stream = new ByteArrayOutputStream();
215        PrintWriter printWriter = new PrintWriter(stream);
216        throwable.printStackTrace(printWriter);
217        printWriter.flush();
218        return stream.toString();
219    }
220
221    ///////////////////////////////////////////////////////////////////
222    ////                         protected variables               ////
223
224    /** The background color as set by the "background" applet parameter.
225     *  This is protected so that derived classes can find out what the
226     *  background color is. Derived classes may wish to know the
227     *  color so they can match it in some of their components.
228     */
229    protected Color _background;
230}