001/* Plotter application that is capable of reading pxgraph files.
002
003 @Author: Edward A. Lee and Christopher Hylands
004
005 @Version: $Id$
006
007 @Copyright (c) 1997-2014 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.compat;
033
034import java.awt.Point;
035import java.io.FileNotFoundException;
036import java.io.IOException;
037import java.io.InputStream;
038import java.net.URL;
039import java.util.StringTokenizer;
040
041import javax.swing.JOptionPane;
042import javax.swing.SwingUtilities;
043
044import ptolemy.plot.CmdLineArgException;
045import ptolemy.plot.Plot;
046import ptolemy.plot.PlotApplication;
047import ptolemy.plot.PlotBox;
048import ptolemy.util.StringUtilities;
049
050///////////////////////////////////////////////////////////////////
051//// PxgraphApplication
052
053/**
054 An application that can plot data in pxgraph format.
055 To compile and run this application, do the following:
056 <pre>
057 javac -classpath ../../.. PxgraphApplication.java
058 java -classpath ../../.. ptolemy.plot.compat.PxgraphApplication
059 </pre>
060 <p>
061 This class uses the helper class PxgraphParser to parse command-line
062 arguments and binary files.  See that class for documentation on
063 the formats.
064
065 @author Edward A. Lee
066 @version $Id$
067 @since Ptolemy II 0.4
068 @Pt.ProposedRating red (eal)
069 @Pt.AcceptedRating red (cxh)
070 @see PxgraphParser
071 @see Plot
072 */
073@SuppressWarnings("serial")
074public class PxgraphApplication extends PlotApplication {
075    /** Construct a plot with no command-line arguments.
076     *  It initially displays a sample plot.
077     *  @exception Exception If command line arguments have problems.
078     */
079    public PxgraphApplication() throws Exception {
080        this(null);
081    }
082
083    /** Construct a plot with the specified command-line arguments.
084     *  @param args The command-line arguments.
085     *  @exception Exception If command line arguments have problems.
086     */
087    public PxgraphApplication(String[] args) throws Exception {
088        this(new Plot(), args);
089    }
090
091    /** Construct a plot with the specified command-line arguments
092     *  and instance of Plot.
093     *  @param plot The instance of Plot.
094     *  @param args The command-line arguments.
095     *  @exception Exception If command line arguments have problems.
096     */
097    public PxgraphApplication(Plot plot, String[] args) throws Exception {
098        super(plot, args);
099    }
100
101    ///////////////////////////////////////////////////////////////////
102    ////                         public methods                    ////
103
104    /** Create a new plot window and map it to the screen.
105     *  @param args The command line arguments.  To see what command
106     *  line arguments are available, run with "-help" as the first element.
107     */
108    public static void main(final String[] args) {
109        try {
110            // Run this in the Swing Event Thread.
111            Runnable doActions = new Runnable() {
112                @Override
113                public void run() {
114                    try {
115                        new PxgraphApplication(new Plot(), args);
116                    } catch (Exception ex) {
117                        System.err.println(ex.toString());
118                        ex.printStackTrace();
119                    }
120                }
121            };
122
123            SwingUtilities.invokeAndWait(doActions);
124        } catch (Exception ex) {
125            ex.printStackTrace();
126        }
127
128        // If the -test arg was set, then exit after 2 seconds.
129        if (_test) {
130            try {
131                Thread.sleep(2000);
132            } catch (InterruptedException e) {
133            }
134
135            StringUtilities.exit(0);
136        }
137    }
138
139    ///////////////////////////////////////////////////////////////////
140    ////                         protected methods                 ////
141
142    /** Display basic information about the application.
143     */
144    @Override
145    protected void _about() {
146        JOptionPane.showMessageDialog(this, "               pxgraph\n"
147                + "        A Java Plotting Tool\n\n" + "By: Edward A. Lee and\n"
148                + "    Christopher Brooks\n" + "Version "
149                + PlotBox.PTPLOT_RELEASE + ", Build: $Id$\n\n"
150                + "For help, type 'pxgraph -help', or see \n"
151                + "the class documentation in the plot.compat package.\n"
152                + "For more information, see\n"
153                + "http://ptolemy.eecs.berkeley.edu/java/ptplot\n",
154                "About pxgraph", JOptionPane.INFORMATION_MESSAGE);
155    }
156
157    /** Parse those command-line arguments that are relevant to the
158     *  application only, and refer other arguments to the PxgraphParser
159     *  helper class.
160     *  @param args  The command line arguments to parse.
161     *  @return The number of arguments read.
162     *  @exception CmdLineArgException If a command line argument cannot
163     *   be parsed.
164     *  @exception FileNotFoundException If an input file cannot be found.
165     *  @exception IOException If there is a problem reading an input.
166     */
167    @Override
168    protected int _parseArgs(String[] args)
169            throws CmdLineArgException, FileNotFoundException, IOException {
170        int i = 0;
171        int argumentsRead;
172        String arg;
173        String title = "Ptolemy plot, pxgraph version";
174
175        int width = 400; // Default width of the graph
176        int height = 300; // Default height of the graph
177
178        // Although most of the arguments are handled by the Plot class,
179        // a few are dealt with here.
180        while (args != null && i < args.length) {
181            arg = args[i++];
182
183            if (arg.equals("-help")) {
184                // -help is not in the original X11 pxgraph.
185                System.out.println(_usage());
186                StringUtilities.exit(0);
187                continue;
188            } else if (arg.equals("-test")) {
189                // -test is not in the original X11 pxgraph.
190                _test = true;
191                continue;
192            } else if (arg.equals("-t")) {
193                // -t <title> TitleText "An X Graph"
194                title = args[i++];
195                continue;
196            } else if (arg.equals("-v") || arg.equals("-version")) {
197                // -version is not in the original X11 pxgraph.
198                System.out.println(
199                        "Version " + PlotBox.PTPLOT_RELEASE + ", Build $Id$");
200                StringUtilities.exit(0);
201                continue;
202            } else if (arg.startsWith("=")) {
203                // Process =WxH+X+Y
204                int xscreen = 1;
205
206                // Process =WxH+X+Y
207                int yscreen = 1;
208                boolean screenlocationgiven = false;
209                StringTokenizer stoken = new StringTokenizer(
210                        arg.substring(1, arg.length()), "=x-+");
211
212                if (stoken.hasMoreTokens()) {
213                    width = Integer.parseInt(stoken.nextToken());
214                }
215
216                if (stoken.hasMoreTokens()) {
217                    height = Integer.parseInt(stoken.nextToken());
218                }
219
220                if (stoken.hasMoreTokens()) {
221                    xscreen = Integer.parseInt(stoken.nextToken());
222                    screenlocationgiven = true;
223                }
224
225                if (stoken.hasMoreTokens()) {
226                    yscreen = Integer.parseInt(stoken.nextToken());
227                    screenlocationgiven = true;
228                }
229
230                if (screenlocationgiven) {
231                    // Note: we add one so that =800x200+0+0 will show up
232                    // in the proper location.
233                    setLocation(new Point(xscreen + 1, yscreen + 1));
234                }
235
236                continue;
237            }
238        }
239
240        setSize(width, height);
241        setTitle(title);
242
243        argumentsRead = i++;
244
245        if (_parser == null) {
246            _parser = new PxgraphParser((Plot) plot);
247        }
248
249        _parser.parseArgs(args);
250        return argumentsRead;
251    }
252
253    /** Read the specified stream.  This method assumes the stream
254     *  contains pxgraph-compatible binary or ascii data.  If it is
255     *  binary, then the -binary flag must have been specified on
256     *  the command line.
257     *  @param base The base for relative file references, or null if
258     *   there are not relative file references.
259     *  @param in The input stream.
260     *  @exception IOException If the stream cannot be read.
261     */
262    @Override
263    protected void _read(URL base, InputStream in) throws IOException {
264        _parser.read(in);
265    }
266
267    /** Return a string summarizing the command-line arguments.
268     *  @return A usage string.
269     */
270    @Override
271    protected String _usage() {
272        // We use a table here to keep things neat.
273        // If we have:
274        //  {"-bd",  "<color>", "Border",  "White", "(Unsupported)"},
275        // -bd       - The argument
276        // <color>   - The description of the value of the argument
277        // Border    - The Xgraph file directive (not supported at this time).
278        // White     - The default (not supported at this time)
279        // "(Unsupported)" - The string that is printed to indicate if
280        //                   a option is unsupported.
281        String[][] commandOptions = {
282                { "-bd", "<color>", "Border", "White", "(Unsupported)" },
283                { "-bg", "<color>", "BackGround", "White", "" },
284                { "-brb", "<base>", "BarBase", "0", "(Unsupported)" },
285                { "-brw", "<width>", "BarWidth", "1", "" },
286                { "-bw", "<size>", "BorderSize", "1", "(Unsupported)" },
287                { "-fg", "<color>", "Foreground", "Black", "" },
288                { "-gw", "<pixels>", "GridStyle", "1", "(Unsupported)" },
289                { "-lf", "<fontname>", "LabelFont", "helvetica-12", "" },
290                { "-lw", "<width>", "LineWidth", "0", "(Unsupported)" },
291                { "-lx", "<xl,xh>", "XLowLimit, XHighLimit", "0", "" },
292                { "-ly", "<yl,yh>", "YLowLimit, YHighLimit", "0", "" },
293                // -o is not in the original X11 pxgraph.
294                { "-o", "<output filename>", "", "/tmp/t.ps", "" },
295                { "-t", "<title>", "TitleText", "An X Graph", "" },
296                { "-tf", "<fontname>", "TitleFont", "helvetica-b-14", "" },
297                { "-x", "<unitName>", "XUnitText", "X", "" },
298                { "-y", "<unitName>", "YUnitText", "Y", "" },
299                { "-zg", "<color>", "ZeroColor", "Black", "(Unsupported)" },
300                { "-zw", "<width>", "ZeroWidth", "0", "(Unsupported)" }, };
301
302        String[][] commandFlags = {
303                // - is not in the original xgraph.
304                { "-", "", "(read from standard in)" },
305                { "-bar", "BarGraph", "" }, { "-bb", "BoundBox", "(Ignored)" },
306                { "-bigendian", "", "" }, { "-littleendian", "", "" },
307                { "-binary", "Binary", "" },
308                // -impulses is not in the original X11 pxgraph.
309                { "-impulses", "Impulses", "" }, { "-help", "", "" },
310                { "-lnx", "XLog", "" }, { "-lny", "YLog", "" },
311                { "-m", "Markers", "" }, { "-M", "StyleMarkers", "" },
312                { "-nl", "NoLines", "" }, { "-p", "PixelMarkers", "" },
313                { "-P", "LargePixel", "" }, { "-rv", "ReverseVideo", "" },
314                // -test is not in the original X11 pxgraph.  We use it for testing
315                { "-test", "Test", "" }, { "-tk", "Ticks", "" },
316                // -v is not in the original X11 pxgraph.
317                { "-v", "Version", "" }, { "-version", "Version", "" }, };
318        StringBuffer result = new StringBuffer(
319                "Usage: ptplot [ options ] [=WxH+X+Y] [file ...]\n\n"
320                        + " options that take values as second args:\n");
321
322        int i;
323
324        for (i = 0; i < commandOptions.length; i++) {
325            result.append(" " + commandOptions[i][0] + " "
326                    + commandOptions[i][1] + " " + commandOptions[i][4] + "\n");
327        }
328
329        result.append("\nBoolean flags:\n");
330
331        for (i = 0; i < commandFlags.length; i++) {
332            result.append(
333                    " " + commandFlags[i][0] + " " + commandFlags[i][2] + "\n");
334        }
335
336        result.append("\nThe following pxgraph features are not supported:\n"
337                + " * Directives in pxgraph input files\n" + " * Xresources\n");
338        return result.toString();
339    }
340
341    ///////////////////////////////////////////////////////////////////
342    ////                         private members                   ////
343    // Parser.
344    private PxgraphParser _parser;
345}