001/* Base class for plotters, except histograms. 002 003 @Copyright (c) 1998-2015 The Regents of the University of California. 004 All rights reserved. 005 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the 009 above copyright notice and the following two paragraphs appear in all 010 copies of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016 SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION 2 026 COPYRIGHTENDKEY 027 */ 028package ptolemy.actor.lib.gui; 029 030import ptolemy.data.BooleanToken; 031import ptolemy.data.IntToken; 032import ptolemy.data.expr.Parameter; 033import ptolemy.data.type.BaseType; 034import ptolemy.kernel.CompositeEntity; 035import ptolemy.kernel.util.Attribute; 036import ptolemy.kernel.util.IllegalActionException; 037import ptolemy.kernel.util.NameDuplicationException; 038import ptolemy.plot.PlotInterface; 039 040/////////////////////////////////////////////////////////////////// 041//// Plotter 042 043/** 044 Base class for plotters. This class contains an instance of the 045 Plot class from the Ptolemy plot package as a public member. 046 It provides a parameter that determines whether to fill the plot 047 when wrapup is invoked. It also has a <i>legend</i> parameter, 048 which gives a comma-separated list of labels to attach to 049 each dataset. Normally, the number of elements in this list 050 should equal the number of input channels, although this 051 is not enforced. 052 <p> 053 This actor also provides a parameter 054 <i>startingDataset</i>, which specifies the starting point 055 for the number of the dataset to use to create the plots. 056 This defaults to zero, but will typically be set to a positive 057 number when more than one instance of a plotter actor shares 058 the same plot object. 059 060 @see ptolemy.plot.PlotInterface 061 062 @author Edward A. Lee 063 @version $Id$ 064 @since Ptolemy II 1.0 065 @Pt.ProposedRating Green (eal) 066 @Pt.AcceptedRating Green (cxh) 067 */ 068public class Plotter extends PlotterBase { 069 /** Construct an actor with the given container and name. 070 * @param container The container. 071 * @param name The name of this actor. 072 * @exception IllegalActionException If the actor cannot be contained 073 * by the proposed container. 074 * @exception NameDuplicationException If the container already has an 075 * actor with this name. 076 */ 077 public Plotter(CompositeEntity container, String name) 078 throws IllegalActionException, NameDuplicationException { 079 super(container, name); 080 081 startingDataset = new Parameter(this, "startingDataset", 082 new IntToken(0)); 083 startingDataset.setTypeEquals(BaseType.INT); 084 } 085 086 /////////////////////////////////////////////////////////////////// 087 //// ports and parameters //// 088 089 /** The starting dataset number to which data is plotted. 090 * This parameter has type IntToken, with default value 0. 091 * Its value must be non-negative. 092 */ 093 public Parameter startingDataset; 094 095 /////////////////////////////////////////////////////////////////// 096 //// public methods //// 097 098 /** If the attribute is <i>startingDataset</i>, then check its validity. 099 * @param attribute The attribute that changed. 100 * @exception IllegalActionException If the specified attribute 101 * is <i>startingDataset</i> and its value is negative, or if the 102 * superclass throws it. 103 */ 104 @Override 105 public void attributeChanged(Attribute attribute) 106 throws IllegalActionException { 107 // NOTE: Do not react to changes in _windowProperties. 108 // Those properties are only used when originally opening a window. 109 if (attribute == startingDataset) { 110 IntToken dataset = (IntToken) startingDataset.getToken(); 111 if (dataset == null) { 112 throw new IllegalActionException(this, 113 "startingDataset null: please enter a nonnegative index value."); 114 } else if (dataset.intValue() < 0) { 115 throw new IllegalActionException(this, 116 "startingDataset: negative value is not allowed."); 117 } 118 } else { 119 super.attributeChanged(attribute); 120 } 121 } 122 123 /** If the plot has not already been created, create it. 124 * If configurations specified by a call to configure() have not yet 125 * been processed, process them. Clear the data sets that this 126 * actor is responsible for (starting with the one indexed 127 * by <i>startingDataset</i>, up to <i>startingDataset</i> + 128 * <i>width</i> - 1, where <i>width</i> is the width of the 129 * input port. 130 * @exception IllegalActionException If the parent class throws it. 131 */ 132 @Override 133 public void initialize() throws IllegalActionException { 134 super.initialize(); 135 136 if (plot == null) { 137 // Create a new plot. 138 plot = _newPlot(); 139 plot.setTitle(getName()); 140 plot.setButtons(true); 141 } 142 143 if (((BooleanToken) automaticRescale.getToken()).booleanValue()) { 144 plot.setAutomaticRescale(true); 145 } 146 147 if (_getImplementation().getFrame() == null 148 && _getImplementation().getPlatformContainer() == null) { 149 _getImplementation().initializeEffigy(); 150 _implementDeferredConfigurations(); 151 _getImplementation().updateSize(); 152 } else { 153 if (plot instanceof PlotInterface) { 154 // FIXME: super.preinitialize() calls PlotBoxInterface.clear(), which 155 // in Plot.java is likely to set the the number of datasets to 0. 156 // This, this code is likely to not actually clear the datasets as 157 // the clearing has already been done. 158 // Another issue is that this super.preinitialize() calls clear in 159 // the Swing event thread, but so the clear might not have happened 160 // when we read the value of the number of datasets. Thus, we could 161 // get the value, preinitialize() could clear it and then we call 162 // clear again below. 163 int width = ((PlotInterface) plot).getNumDataSets(); 164 int offset = ((IntToken) startingDataset.getToken()).intValue(); 165 for (int i = width - 1; i >= 0; i--) { 166 ((PlotInterface) plot).clear(i + offset); 167 } 168 169 plot.repaint(); 170 } else { 171 plot.clear(false); 172 plot.repaint(); 173 } 174 } 175 176 _getImplementation().bringToFront(); 177 } 178}