001/* A standalone plot application. 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 */ 027package ptolemy.plot; 028 029import java.awt.event.WindowAdapter; 030import java.awt.event.WindowEvent; 031import java.io.File; 032import java.io.FileInputStream; 033import java.io.FileNotFoundException; 034import java.io.IOException; 035import java.io.InputStream; 036import java.net.MalformedURLException; 037import java.net.URL; 038 039import javax.swing.JOptionPane; 040import javax.swing.SwingUtilities; 041 042import ptolemy.util.StringUtilities; 043 044/////////////////////////////////////////////////////////////////// 045//// PlotApplication 046 047/** 048 PlotApplication is a versatile two-dimensional data plotter application. 049 <p>It can read files compatible with the Ptolemy plot 050 file format (currently only ASCII). For a description of the file 051 format, see the Plot and PlotBox classes. 052 Command-line options include:</p> 053 054 <dl> 055 056 <dt><code>-help</code></dt> 057 <dd>Print the usage, including all command-line options 058 that exist for backward compatibility and then exit. 059 The help menu choice will display the same information.</dd> 060 061 <dt><code>-test</code></dt> 062 <dd>Display the plot, then exit after 2 seconds.</dd> 063 064 <dt><code>-version</code></dt> 065 <dd>Print the program version and then exit. 066 While ptplot is running, 067 the version menu choice will display the same information.</dd> 068 069 <dt><code>-</code></dt> 070 <dd>Read the plot data from standard in.</dd> 071 072 </dl> 073 074 <p> 075 For compatibility with historical applications, this application has 076 a limited ability to read pxgraph files. The command line arguments 077 must be used, and the options that are understood are exactly those 078 of the pxgraph application, plus some more to allow for cross-platform 079 reading. It is not possible to read pxgraph files 080 using the "Open" menu command (because of the cross-platform problems). 081 The additional command-line arguments are:</p> 082 083 <dl> 084 085 <dt><code>-bigendian</code></dt> 086 <dd>Data files are in big-endian, or network binary format. 087 If you are on a little-endian machine, such as a machine 088 with an Intel x86 chip, and you would like to read a binary 089 format file created on a big-endian machine, such as a Sun SPARC, 090 use the <code>-bigendian</code> flag.</dd> 091 092 <dt><code>-littleendian</code></dt> 093 <dd>Data files are in little-endian, or x86 binary format. 094 If you are on a big-endian machine, such as a Sun Sparc, 095 and you would like to read a binary 096 format file created on a little-endian machine, such as Intel x86 097 machine, then use the <code>-littleendian</code> flag.</dd> 098 </dl> 099 100 <p> 101 To compile and run this application, do the following:</p> 102 <pre> 103 javac -classpath ../.. PlotApplication.java 104 java -classpath ../.. ptolemy.plot.PlotApplication 105 </pre> 106 <p> 107 This assumes a particular directory structure. If this is not what you 108 have, then alter the above accordingly.</p> 109 110 @see Plot 111 @see PlotBox 112 @author Christopher Brooks and Edward A. Lee 113 @version $Id$ 114 @since Ptolemy II 0.2 115 @Pt.ProposedRating Yellow (cxh) 116 @Pt.AcceptedRating Yellow (cxh) 117 */ 118@SuppressWarnings("serial") 119public class PlotApplication extends PlotFrame { 120 /** Construct a plot with no command-line arguments. 121 * It initially displays a sample plot. 122 * @exception Exception Not thrown in this base class. 123 */ 124 public PlotApplication() throws Exception { 125 this(new String[0]); 126 } 127 128 /** Construct a plot with the specified command-line arguments. 129 * @param args The command-line arguments. 130 * @exception Exception If command line arguments have problems. 131 */ 132 public PlotApplication(String[] args) throws Exception { 133 this(new Plot(), args); 134 } 135 136 /** Construct a plot with the specified command-line arguments 137 * and instance of plot. If there are no command-line arguments, 138 * then display a sample plot. 139 * @param plot The instance of Plot to use. 140 * @param args The command-line arguments. 141 * @exception Exception If command line arguments have problems. 142 */ 143 public PlotApplication(PlotBox plot, String[] args) throws Exception { 144 // invoke the base class constructor and pass in the argument a Plot 145 // object. This makes sure that the plot field is an instance of 146 // Plot class. 147 super("PlotApplication", plot); 148 149 // Handle window closing by exiting the application. 150 addWindowListener(new WindowClosingAdapter()); 151 152 _parseArgs(args); 153 154 if (args == null || args.length == 0) { 155 samplePlot(); 156 } 157 158 setVisible(true); 159 160 if (_printPDF) { 161 _printPDF(); 162 } 163 } 164 165 /** Display the given plot. Unlike the two argument constructor, 166 * this does not take command-line arguments, and does not fill 167 * the plot with a sample plot. 168 * @param plot The instance of Plot to display. 169 */ 170 public PlotApplication(PlotBox plot) { 171 // Invoke the base class constructor and pass in the argument a Plot 172 // object. This makes sure that the plot field is an instance of 173 // Plot class. 174 super("PlotApplication", plot); 175 176 // Handle window closing by exiting the application. 177 addWindowListener(new WindowClosingAdapter()); 178 179 setVisible(true); 180 } 181 182 /////////////////////////////////////////////////////////////////// 183 //// public methods //// 184 185 /** Create a new plot window and map it to the screen. 186 * @param args The command line arguments. See the class comment 187 * for details. 188 */ 189 public static void main(final String[] args) { 190 try { 191 // Run this in the Swing Event Thread. 192 Runnable doActions = new Runnable() { 193 @Override 194 public void run() { 195 try { 196 new PlotApplication(new Plot(), args); 197 } catch (Exception ex) { 198 System.err.println(ex.toString()); 199 ex.printStackTrace(); 200 } 201 } 202 }; 203 204 SwingUtilities.invokeAndWait(doActions); 205 } catch (Throwable throwable) { 206 throwable.printStackTrace(); 207 } 208 209 // If the -test arg was set, then exit after 2 seconds. 210 if (_test) { 211 try { 212 Thread.sleep(2000); 213 } catch (InterruptedException e) { 214 } 215 216 StringUtilities.exit(0); 217 } 218 } 219 220 /////////////////////////////////////////////////////////////////// 221 //// protected methods //// 222 @Override 223 protected void _about() { 224 JOptionPane.showMessageDialog(this, 225 "PlotApplication class\n" + "By: Edward A. Lee " 226 + "and Christopher Brooks\n" + "Version " 227 + PlotBox.PTPLOT_RELEASE + ", Build: $Id$\n\n" 228 + "For more information, see\n" 229 + "http://ptolemy.eecs.berkeley.edu/java/ptplot\n\n" 230 + "Copyright (c) 1997-2014, " 231 + "The Regents of the University of California.", 232 "About Ptolemy Plot", JOptionPane.INFORMATION_MESSAGE); 233 } 234 235 /** Exit the application. 236 */ 237 @Override 238 protected void _close() { 239 StringUtilities.exit(0); 240 } 241 242 /** Display more detailed information than given by _about(). 243 */ 244 @Override 245 protected void _help() { 246 JOptionPane.showMessageDialog(this, 247 "PlotApplication is a standalone plot " + " application.\n" 248 + " File formats understood: Ptplot ASCII.\n" 249 + " Left mouse button: Zooming.\n\n" + _usage(), 250 "About Ptolemy Plot", JOptionPane.INFORMATION_MESSAGE); 251 } 252 253 /** Parse the command-line 254 * arguments and make calls to the Plot class accordingly. 255 * @param args The command line arguments. See the class comment 256 * for details. 257 * @return The number of arguments read. 258 * @exception CmdLineArgException If a command line argument cannot 259 * be parsed. 260 * @exception FileNotFoundException If an input file cannot be found. 261 * @exception IOException If there is a problem reading an input. 262 */ 263 protected int _parseArgs(String[] args) 264 throws CmdLineArgException, FileNotFoundException, IOException { 265 int i = 0; 266 int argumentsRead; 267 String arg; 268 String title = "Ptolemy plot"; 269 270 int width = 500; // Default width of the graph 271 int height = 300; // Default height of the graph 272 273 while (args != null && i < args.length) { 274 arg = args[i++]; 275 276 if (arg.equals("-height")) { 277 if (i > args.length - 1) { 278 throw new CmdLineArgException(_usage()); 279 } 280 281 height = Integer.parseInt(args[i++]); 282 continue; 283 } else if (arg.equals("-help")) { 284 System.out.println(_usage()); 285 StringUtilities.exit(0); 286 continue; 287 } else if (arg.equals("-printPDF")) { 288 _printPDF = true; 289 continue; 290 } else if (arg.equals("-test")) { 291 _test = true; 292 continue; 293 } else if (arg.equals("-version")) { 294 System.out.println( 295 "Version " + PlotBox.PTPLOT_RELEASE + ", Build $Id$"); 296 StringUtilities.exit(0); 297 continue; 298 } else if (arg.equals("-width")) { 299 if (i > args.length - 1) { 300 throw new CmdLineArgException( 301 "-width requires an integer argument"); 302 } 303 304 width = Integer.parseInt(args[i++]); 305 continue; 306 } else if (arg.equals("")) { 307 // Ignore blank argument. 308 } else if (arg.equals("-")) { 309 // read from standard input 310 URL base = new URL("file", null, "standard input"); 311 _read(base, System.in); 312 } else if (!arg.startsWith("-")) { 313 // Have a filename. First attempt to open it as a URL. 314 InputStream instream; 315 URL base; 316 317 try { 318 // First argument is null because we are only 319 // processing absolute URLs this way. Relative 320 // URLs are opened as ordinary files. 321 URL inurl = new URL(null, arg); 322 base = inurl; 323 instream = inurl.openStream(); 324 } catch (MalformedURLException ex) { 325 File file = new File(arg); 326 instream = new FileInputStream(file); 327 _file = new File(file.getAbsolutePath()); 328 title = _file.getName(); 329 _directory = _file.getParentFile(); 330 base = new URL("file", null, _directory.getAbsolutePath()); 331 } 332 333 _read(base, instream); 334 } else { 335 // Unrecognized option. 336 throw new CmdLineArgException("Unrecognized option: " + arg); 337 } 338 } 339 340 setSize(width, height); 341 setTitle(title); 342 343 argumentsRead = i; 344 345 return argumentsRead; 346 } 347 348 /** Return a string summarizing the command-line arguments. 349 * @return A usage string. 350 */ 351 protected String _usage() { 352 // We use a table here to keep things neat. 353 // If we have: 354 // {"-bd", "<color>", "Border", "White", "(Unsupported)"}, 355 // -bd - The argument 356 // <color> - The description of the value of the argument 357 // Border - The Xgraph file directive (not supported at this time). 358 // White - The default (not supported at this time) 359 // "(Unsupported)" - The string that is printed to indicate if 360 // a option is unsupported. 361 String[][] commandOptions = { { "-height", "<pixels>" }, 362 { "-width", "<pixels>" }, }; 363 364 String[] commandFlags = { "-help", "-printPDF", "-test", "-version", 365 "-", }; 366 StringBuffer result = new StringBuffer( 367 "Usage: ptplot [ options ] [file ...]\n\n" 368 + "Options that take values:\n"); 369 370 int i; 371 372 for (i = 0; i < commandOptions.length; i++) { 373 result.append(" " + commandOptions[i][0] + " " 374 + commandOptions[i][1] + "\n"); 375 } 376 377 result.append("\nBoolean flags:\n"); 378 379 for (i = 0; i < commandFlags.length; i++) { 380 result.append(" " + commandFlags[i]); 381 } 382 383 return result.toString(); 384 } 385 386 /////////////////////////////////////////////////////////////////// 387 //// protected variables //// 388 389 /** If true, then print to PDF. */ 390 protected static boolean _printPDF = false; 391 392 /** If true, then auto exit after a few seconds. */ 393 protected static boolean _test = false; 394 395 private static class WindowClosingAdapter extends WindowAdapter { 396 @Override 397 public void windowClosing(WindowEvent e) { 398 // Strangely, calling _close() here sends javac into 399 // an infinite loop (in jdk 1.1.4). 400 // _close(); 401 StringUtilities.exit(0); 402 } 403 } 404}