001/* Editable plotter application that is capable of reading PlotML files.
002
003 @Author: Edward A. Lee
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.plotml;
033
034import java.awt.Event;
035import java.awt.event.ActionEvent;
036import java.awt.event.ActionListener;
037import java.awt.event.KeyEvent;
038
039import javax.swing.JComponent;
040import javax.swing.JMenuItem;
041import javax.swing.JOptionPane;
042import javax.swing.KeyStroke;
043import javax.swing.SwingUtilities;
044
045import ptolemy.gui.ComponentDialog;
046import ptolemy.gui.Query;
047import ptolemy.plot.EditablePlot;
048import ptolemy.plot.PlotBox;
049import ptolemy.util.StringUtilities;
050
051///////////////////////////////////////////////////////////////////
052//// EditablePlotMLApplication
053
054/**
055 An application that can plot data in PlotML format from a URL or
056 from files specified on the command line, and can then permit the
057 user to edit the plot.
058 To compile and run this application, do the following:
059 <pre>
060 javac -classpath ../../.. EditablePlotMLApplication.java
061 java -classpath ../../.. ptolemy.plot.plotml.EditablePlotMLApplication
062 </pre>
063 Initially, none of the data sets is editable. Use the Edit menu's
064 Edit Dataset item to make a data set editable.
065
066 @author Edward A. Lee
067 @version $Id$
068 @since Ptolemy II 0.4
069 @Pt.ProposedRating red (eal)
070 @Pt.AcceptedRating red (cxh)
071 @see ptolemy.plot.PlotBox
072 @see ptolemy.plot.Plot
073 */
074@SuppressWarnings("serial")
075public class EditablePlotMLApplication extends PlotMLApplication {
076    /** Construct a plot with no command-line arguments.
077     *  It initially displays a sample plot.
078     *  @exception Exception If command line arguments have problems.
079     */
080    public EditablePlotMLApplication() throws Exception {
081        this(null);
082    }
083
084    /** Construct a plot with the specified command-line arguments.
085     *  @param args The command-line arguments.
086     *  @exception Exception If command line arguments have problems.
087     */
088    public EditablePlotMLApplication(String[] args) throws Exception {
089        this(new EditablePlot(), args);
090    }
091
092    /** Construct a plot with the specified command-line arguments
093     *  and instance of plot.
094     *  @param plot The instance of EditablePlot to use.
095     *  @param args The command-line arguments.
096     *  @exception Exception If command line arguments have problems.
097     */
098    public EditablePlotMLApplication(EditablePlot plot, String[] args)
099            throws Exception {
100        super(plot, args);
101
102        // The default is that no set is editable.
103        plot.setEditable(-1);
104
105        // Edit menu
106        JMenuItem select = new JMenuItem("Edit Dataset", KeyEvent.VK_E);
107        SelectListener selectListener = new SelectListener();
108        select.addActionListener(selectListener);
109
110        // Note that under Windows, the setLookAndFeel() in
111        // PlotApplication causes problems here with this new
112        // JMenuItem: the font and background color may be wrong.
113        // Setting the background works here because the parent
114        // class has called setVisible() already.
115        // Unfortunately, setting the background helps, but the
116        // result does not have the etch border
117        //select.setBorderPainted(true);
118        //select.setBorder(javax.swing.BorderFactory.createMatteBorder(0,1,0,0,java.awt.Color.white));
119        //select.setBackground(_editMenu.getBackground());
120        // Under Java 1.3.1_06, at least the font is right, but not
121        // under 1.4.1_02
122        //select.setFont(_editMenu.getFont());
123        // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4736093
124        // suggests this, which does not seem to help
125        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
126                KeyStroke.getKeyStroke(KeyEvent.VK_ALT, Event.ALT_MASK, false),
127                "repaint");
128
129        _editMenu.add(select);
130
131        // http://java.sun.com/docs/books/tutorial/uiswing/misc/plaf.html
132        // suggests calling updateComponentTreeUI(), but if we do,
133        // that forces the menu back to a white background.
134        //SwingUtilities.updateComponentTreeUI(select);
135    }
136
137    ///////////////////////////////////////////////////////////////////
138    ////                         public methods                    ////
139
140    /** Create a new plot window and map it to the screen.
141     *  The command to run would be:
142     *  <pre>
143     *  java -classpath $PTII ptolemy.plot.plotml.EditablePlotMLApplication
144     *  </pre>
145     *  @param args Arguments suitable for the
146     *  {@link ptolemy.plot.EditablePlot} class.
147     */
148    public static void main(final String[] args) {
149        try {
150            Runnable doActions = new Runnable() {
151                @Override
152                public void run() {
153                    try {
154                        new EditablePlotMLApplication(new EditablePlot(), args);
155                    } catch (Exception ex) {
156                        System.err.println(ex.toString());
157                        ex.printStackTrace();
158                    }
159                }
160            };
161
162            // NOTE: Using invokeAndWait() here risks causing
163            // deadlock.  However, the Sun Tutorial recommends calling
164            // invokeAndWait so that the work finishes before returning.
165            // if we call invokeLater() then demo/PlotFourierSeries.java
166            // has problems.
167            SwingUtilities.invokeAndWait(doActions);
168        } catch (Exception ex) {
169            System.err.println(ex.toString());
170            ex.printStackTrace();
171        }
172
173        // If the -test arg was set, then exit after 2 seconds.
174        if (_test) {
175            try {
176                Thread.sleep(2000);
177            } catch (InterruptedException e) {
178            }
179
180            StringUtilities.exit(0);
181        }
182    }
183
184    ///////////////////////////////////////////////////////////////////
185    ////                         protected methods                 ////
186
187    /** Display basic information about the application.
188     */
189    @Override
190    protected void _about() {
191        JOptionPane.showMessageDialog(this,
192                "EditablePlotMLApplication class\n" + "By: Edward A. Lee "
193                        + "and Christopher Hylands\n" + "Version "
194                        + PlotBox.PTPLOT_RELEASE + ", Build: $Id$\n\n"
195                        + "For more information, see\n"
196                        + "http://ptolemy.eecs.berkeley.edu/java/ptplot\n\n"
197                        + "Copyright (c) 1997-2014, "
198                        + "The Regents of the University of California.",
199                "About Ptolemy Plot", JOptionPane.INFORMATION_MESSAGE);
200    }
201
202    /** Display more detailed information than given by _about().
203     */
204    @Override
205    protected void _help() {
206        JOptionPane.showMessageDialog(this,
207                "EditablePlotMLApplication is a standalone plot "
208                        + " application.\n"
209                        + "  File formats understood: PlotML and Ptplot ASCII.\n"
210                        + "  Left mouse button: Zooming.\n"
211                        + "  Right mouse button: Editing data (use edit menu to select "
212                        + "a dataset).\n\n" + _usage(),
213                "About Ptolemy Plot", JOptionPane.INFORMATION_MESSAGE);
214    }
215
216    /** Open a dialog to select a dataset to edit.
217     */
218    protected void _selectDataset() {
219        Query query = new Query();
220        int numSets = ((EditablePlot) plot).getNumDataSets();
221        String[] choices = new String[numSets + 1];
222
223        for (int i = 0; i < numSets; i++) {
224            choices[i + 1] = plot.getLegend(i);
225
226            if (choices[i + 1] == null) {
227                choices[i + 1] = "" + i;
228            }
229        }
230
231        choices[0] = "none";
232        query.setTextWidth(20);
233        query.addChoice("choice",
234                "Choose a data set, then drag the right mouse button", choices,
235                choices[0]);
236
237        ComponentDialog dialog = new ComponentDialog(this, "Select dataset",
238                query);
239        String buttonPressed = dialog.buttonPressed();
240
241        if (buttonPressed.equals("OK")) {
242            int result = query.getIntValue("choice");
243
244            if (result > 0) {
245                ((EditablePlot) plot).setEditable(result - 1);
246            } else {
247                // none...
248                ((EditablePlot) plot).setEditable(-1);
249            }
250        }
251    }
252
253    ///////////////////////////////////////////////////////////////////
254    ////                         inner classes                     ////
255    class SelectListener implements ActionListener {
256        @Override
257        public void actionPerformed(ActionEvent e) {
258            _selectDataset();
259        }
260    }
261}