001/* Appletable Plotter 002 003 @Author: Edward A. Lee and Christopher Hylands 004 005 @Version: $Id$ 006 007 @Copyright (c) 1997-2018 The Regents of the University of California. 008 All rights reserved. 009 010 Permission is hereby granted, without written agreement and without 011 license or royalty fees, to use, copy, modify, and distribute this 012 software and its documentation for any purpose, provided that the 013 above copyright notice and the following two paragraphs appear in all 014 copies of this software. 015 016 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 017 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 018 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 019 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 020 SUCH DAMAGE. 021 022 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 023 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 024 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 025 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 026 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 027 ENHANCEMENTS, OR MODIFICATIONS. 028 029 PT_COPYRIGHT_VERSION_2 030 COPYRIGHTENDKEY 031 */ 032package ptolemy.plot; 033 034import java.awt.BorderLayout; 035import java.awt.Color; 036import java.io.FileNotFoundException; 037import java.io.IOException; 038import java.io.InputStream; 039import java.net.MalformedURLException; 040import java.net.URL; 041 042import javax.swing.JApplet; 043import javax.swing.SwingUtilities; 044 045/////////////////////////////////////////////////////////////////// 046//// PlotApplet 047 048/** 049 An Applet that can plot data from a URL. 050 The URL should be specified using the dataurl applet parameter. 051 The formatting commands are included in the file with the 052 the data. 053 If no URL is given, then a sample plot is generated. 054 055 @author Edward A. Lee, Christopher Hylands, Contributor: Roger Robins 056 @version $Id$ 057 @since Ptolemy II 0.2 058 @Pt.ProposedRating Yellow (cxh) 059 @Pt.AcceptedRating Yellow (cxh) 060 @see PlotBox 061 @see Plot 062 */ 063@SuppressWarnings("serial") 064public class PlotApplet extends JApplet { 065 // /** Construct a Plot applet */ 066 // public PlotApplet() { 067 // FIXME: having the mutex causes applets to hang. 068 // The mutex was introduced to Work around problem in Java 069 // 1.3.1_08 where if we create 6 instances of a Plot applet then 070 // navigate forward then back - IE and Navigator hang. 071 // However, since we are now operating inside the Swing Event 072 // thread, I think this code is unnecessary. 073 // if (_mutex == null) { 074 // _mutex = new Object(); 075 // } 076 // } 077 078 /** Cleanup after execution of the model. This method is called 079 * by the browser or appletviewer to inform this applet that 080 * it should clean up. 081 */ 082 @Override 083 public void destroy() { 084 try { 085 // See http://download.oracle.com/javase/tutorial/uiswing/components/applet.html 086 SwingUtilities.invokeAndWait(new Runnable() { 087 @Override 088 public void run() { 089 _plot.destroy(); 090 // Needed to get rid of the Mouse, MouseMotion and Key listeners 091 //getRootPane().getContentPane().removeAll(); 092 getContentPane().remove(_plot); 093 _plot = null; 094 } 095 }); 096 } catch (Throwable throwable) { 097 System.err.println("init() didn't successfully complete"); 098 throwable.printStackTrace(); 099 } 100 super.destroy(); 101 } 102 103 /** Return a string describing this applet. 104 * @return A string describing the applet. 105 */ 106 @Override 107 public String getAppletInfo() { 108 return "PlotApplet " + PlotBox.PTPLOT_RELEASE + ": A data plotter.\n" 109 + "By: Edward A. Lee and\n " + "Christopher Hylands\n" 110 + "($Id$)"; 111 } 112 113 /** Return information about parameters. 114 * @return A array of arrays giving parameter names, the type, 115 * and the default value or description. 116 */ 117 @Override 118 public String[][] getParameterInfo() { 119 String[][] pinfo = { 120 { "background", "hexcolor value", "background color" }, 121 { "foreground", "hexcolor value", "foreground color" }, 122 { "dataurl", "url", "the URL of the data to plot" }, 123 { "height", "integer", "100" }, 124 { "width", "integer", "100" }, }; 125 return pinfo; 126 } 127 128 /** Initialize the applet. Read the applet parameters. 129 130 * Subclasses that extend this method and call Swing UI methods 131 * should do so in the Swing Event thread by calling 132 * SwingUtilities.invokeAndWait(). 133 * Note that some Plot methods will automatically run in the 134 * Swing Event thread, some will not. 135 * For details about SwingUtilities.invokeAndWait(), see 136 * <a href="http://download.oracle.com/javase/tutorial/uiswing/components/applet.html#thread">The Sun Applet Tutorial</a> 137 */ 138 @Override 139 public void init() { 140 super.init(); 141 142 // FIXME: having the mutex causes applets to hang. 143 //synchronized (_mutex) { 144 Runnable doActions = new Runnable() { 145 @Override 146 public void run() { 147 if (_plot == null) { 148 _plot = newPlot(); 149 } 150 151 getContentPane().add(plot(), BorderLayout.NORTH); 152 153 // Process the width and height applet parameters 154 int width; 155 156 // Process the width and height applet parameters 157 int height; 158 String widthspec = getParameter("width"); 159 160 if (widthspec != null) { 161 width = Integer.parseInt(widthspec); 162 } else { 163 width = 400; 164 } 165 166 String heightspec = getParameter("height"); 167 168 if (heightspec != null) { 169 height = Integer.parseInt(heightspec); 170 } else { 171 height = 400; 172 } 173 174 _setPlotSize(width, height); 175 plot().setButtons(true); 176 177 // Process the background parameter. 178 Color background = Color.white; 179 String colorspec = getParameter("background"); 180 181 if (colorspec != null) { 182 background = PlotBox.getColorByName(colorspec); 183 } 184 185 setBackground(background); 186 plot().setBackground(background); 187 getContentPane().setBackground(background); 188 189 // Process the foreground parameter. 190 Color foreground = Color.black; 191 colorspec = getParameter("foreground"); 192 193 if (colorspec != null) { 194 foreground = PlotBox.getColorByName(colorspec); 195 } 196 197 setForeground(foreground); 198 plot().setForeground(foreground); 199 plot().setVisible(true); 200 201 // Process the dataurl parameter. 202 String dataurlspec = getParameter("dataurl"); 203 204 if (dataurlspec != null) { 205 try { 206 showStatus("Reading data"); 207 208 URL dataurl = new URL(getDocumentBase(), dataurlspec); 209 InputStream in = dataurl.openStream(); 210 _read(in); 211 showStatus("Done"); 212 } catch (MalformedURLException e) { 213 System.err.println(e.toString()); 214 } catch (FileNotFoundException e) { 215 System.err.println("PlotApplet: file not found: " + e); 216 } catch (IOException e) { 217 System.err.println( 218 "PlotApplet: error reading input file: " + e); 219 } 220 } 221 } 222 }; 223 224 try { 225 // NOTE: Using invokeAndWait() here risks causing 226 // deadlock. However, the Sun Tutorial recommends calling 227 // invokeAndWait so that the work finishes before returning. 228 // if we call invokeLater() then demo/PlotFourierSeries.java 229 // has problems. 230 SwingUtilities.invokeAndWait(doActions); 231 } catch (Throwable throwable) { 232 // Ignore InterruptedException. 233 // Other exceptions should not occur. 234 } 235 236 //} 237 } 238 239 /** Create a new Plot object for the applet. Derived classes can 240 * redefine this method to return a different type of plot object. 241 * @return A new instance of PlotBox. 242 */ 243 public PlotBox newPlot() { 244 return new Plot(); 245 } 246 247 /** Return the plot object to operate on. 248 * @return The plot object associated with this applet. 249 */ 250 public PlotBox plot() { 251 return _plot; 252 } 253 254 /** Set the plot object to operate on. 255 * @param plot The plot object to associate with this applet. 256 */ 257 public void setPlot(PlotBox plot) { 258 // FIXME: this method is necessary for PxgraphApplet to work 259 // properly. We could modify newPlot() to set _plot, but 260 // that would change the newPlot() contract, so we add another method. 261 _plot = plot; 262 } 263 264 /////////////////////////////////////////////////////////////////// 265 //// protected methods //// 266 267 /** Read the specified stream. Derived classes may override this 268 * to support other file formats. 269 * @param in The input stream. 270 * @exception IOException If the stream cannot be read. 271 */ 272 protected void _read(InputStream in) throws IOException { 273 plot().read(in); 274 } 275 276 /** Given the size of the applet, set the size of the plot. 277 * Derived classes may override this to allow room for other 278 * widgets below the plot. 279 * @param appletWidth The width of the applet. 280 * @param appletHeight The height of the applet. 281 */ 282 protected void _setPlotSize(int appletWidth, int appletHeight) { 283 plot().setSize(appletWidth, appletHeight); 284 } 285 286 /////////////////////////////////////////////////////////////////// 287 //// private variables //// 288 // Work around problem in Java 1.3.1_08 where if we create 289 // 6 instances of a Plot applet then navigate forward then 290 // back - IE and Navigator hang. (Roger Robins) 291 // FIXME: having the mutex causes applets to hang. 292 //private static Object _mutex = null; 293 // The Plot component we are running. 294 private transient PlotBox _plot; 295}