001/* This parameter, when inserted into a port, causes the port to display its unconsumed inputs. 002 003 @Copyright (c) 2007-2014 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.vergil.actor.lib; 029 030import java.util.Collection; 031import java.util.List; 032 033import ptolemy.actor.IOPort; 034import ptolemy.actor.Receiver; 035import ptolemy.data.Token; 036import ptolemy.kernel.util.IllegalActionException; 037import ptolemy.kernel.util.Location; 038import ptolemy.kernel.util.NameDuplicationException; 039import ptolemy.kernel.util.NamedObj; 040import ptolemy.kernel.util.Settable; 041import ptolemy.kernel.util.SingletonAttribute; 042import ptolemy.kernel.util.ValueListener; 043import ptolemy.vergil.icon.EditorIcon; 044import ptolemy.vergil.kernel.attributes.RectangleAttribute; 045import ptolemy.vergil.kernel.attributes.TextAttribute; 046 047/////////////////////////////////////////////////////////////////// 048//// MonitorReceiverAttribute 049 050/** 051 This parameter, when inserted into a port, causes the port to display data 052 available for the actor to read. 053 It assumes that the port is an input port. 054 Otherwise, it returns an empty string. It is a singleton, and it's 055 name is always _showInfo, regardless of what name argument is specified to the constructor. 056 Note that the display is not automatically updated. Use an instance of RepaintController 057 in your model to cause the display to be updated, or use MonitorReceiverContents. 058 059 @author Edward A. Lee 060 @version $Id$ 061 @since Ptolemy II 8.0 062 @Pt.ProposedRating Yellow (eal) 063 @Pt.AcceptedRating Red (cxh) 064 @see MonitorReceiverContents 065 */ 066public class MonitorReceiverAttribute extends SingletonAttribute 067 implements Settable { 068 069 /** Construct an actor with the specified container and name. 070 * @param container The container. 071 * @param name The name of this actor. 072 * @exception IllegalActionException If the entity 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 MonitorReceiverAttribute(NamedObj container, String name) 078 throws IllegalActionException, NameDuplicationException { 079 super(container, "_showInfo"); 080 081 // The icon. 082 EditorIcon _icon = new EditorIcon(this, "_icon"); 083 RectangleAttribute rectangle = new RectangleAttribute(_icon, 084 "rectangle"); 085 rectangle.width.setExpression("175.0"); 086 rectangle.height.setExpression("20.0"); 087 rectangle.fillColor.setExpression("{1.0, 0.7, 0.7, 1.0}"); 088 089 Location _location = new Location(rectangle, "_location"); 090 _location.setExpression("-5.0, -15.0"); 091 092 TextAttribute text = new TextAttribute(_icon, "text"); 093 text.text.setExpression("MonitorReceiverAttribute"); 094 } 095 096 /////////////////////////////////////////////////////////////////// 097 //// public methods //// 098 099 /** Add a listener to be notified when the value of this settable 100 * object changes. An implementation of this method should ignore 101 * the call if the specified listener is already on the list of 102 * listeners. In other words, it should not be possible for the 103 * same listener to be notified twice of a value update. 104 * @param listener The listener to add. 105 * @see #removeValueListener(ValueListener) 106 */ 107 @Override 108 public void addValueListener(ValueListener listener) { 109 // FIXME: Ignore for now 110 } 111 112 /** Return the default value of this attribute, if there is 113 * one, or null if there is none. 114 * @return The default value of this attribute, or null 115 * if there is none. 116 */ 117 @Override 118 public String getDefaultExpression() { 119 return "Queue monitor"; 120 } 121 122 /** Return a name to present to the user. 123 * @return A name to present to the user. 124 */ 125 @Override 126 public String getDisplayName() { 127 return "MonitorReceiverAttribute"; 128 } 129 130 /** Get the expression currently used by this variable. The expression 131 * is either the value set by setExpression(), or a string representation 132 * of the value set by setToken(), or an empty string if no value 133 * has been set. 134 * @return The expression used by this variable. 135 * @see #setExpression(String) 136 */ 137 @Override 138 public String getExpression() { 139 try { 140 NamedObj container = getContainer(); 141 if (!(container instanceof IOPort)) { 142 return "Not an IOPort"; 143 } 144 Receiver[][] receivers = ((IOPort) container).getReceivers(); 145 if (receivers == null || receivers.length == 0) { 146 return ""; 147 } 148 StringBuffer result = new StringBuffer(); 149 if (((IOPort) container).isMultiport()) { 150 result.append("{"); 151 } 152 for (int i = 0; i < receivers.length; i++) { 153 if (i > 0) { 154 result.append("}, {"); 155 } 156 for (int j = 0; j < receivers[i].length; j++) { 157 // Normally there will only be one j with value 0. 158 // Just in case, put in a separator. 159 if (j > 0) { 160 result.append(" AND "); 161 } 162 Receiver receiver = receivers[i][j]; 163 if (receiver != null) { 164 List<Token> list = receiver.elementList(); 165 if (list != null) { 166 result.append(list); 167 } else { 168 result.append("NULL"); 169 } 170 } else { 171 result.append("No Receiver"); 172 } 173 } 174 } 175 if (((IOPort) container).isMultiport()) { 176 result.append("}"); 177 } 178 return result.toString(); 179 } catch (Exception e) { 180 return "ERROR: " + e; 181 } 182 } 183 184 /** Get the value of the attribute, which is the evaluated expression. 185 * @return The value. 186 * @see #getExpression() 187 */ 188 @Override 189 public String getValueAsString() { 190 return getExpression(); 191 } 192 193 /** Get the visibility of this Settable, as set by setVisibility(). 194 * If setVisibility() has not been called, then implementations of 195 * this interface should return some default, not null, indicating 196 * user-level visibility. The returned value is one of the static 197 * instances of the Visibility inner class. 198 * @return The visibility of this Settable. 199 * @see #setVisibility(Settable.Visibility) 200 */ 201 @Override 202 public Settable.Visibility getVisibility() { 203 return Settable.NOT_EDITABLE; 204 } 205 206 /** Remove a listener from the list of listeners that are 207 * notified when the value of this variable changes. If no such listener 208 * exists, do nothing. 209 * @param listener The listener to remove. 210 * @see #addValueListener(ValueListener) 211 */ 212 @Override 213 public void removeValueListener(ValueListener listener) { 214 // FIXME: Ignore for now. 215 } 216 217 /** Set the value of the attribute by giving some expression. 218 * In some implementations, the listeners and the container will 219 * be notified immediately. However, some implementations may 220 * defer notification until validate() is called. 221 * @param expression The value of the attribute. 222 * @exception IllegalActionException If the expression is invalid. 223 * @see #getExpression() 224 */ 225 @Override 226 public void setExpression(String expression) throws IllegalActionException { 227 // Ignore. 228 // Do not throw an exception here, as it prevents undo from working. 229 } 230 231 /** Set the visibility of this Settable. The argument should be one 232 * of the static public instances of the inner class Visibility. 233 * This is enforced by making it impossible to construct instances 234 * of this inner class outside this interface definition. 235 * If this method is not called, then implementations of 236 * this interface should return some default, not null. 237 * @param visibility The visibility of this Settable. 238 * @see #getVisibility() 239 */ 240 @Override 241 public void setVisibility(Settable.Visibility visibility) { 242 // Ignore. 243 } 244 245 /** Check the validity of the expression set in setExpression(). 246 * Implementations of this method should notify the container 247 * by calling attributeChanged(), unless the container has already 248 * been notified in setExpression(). They should also notify any 249 * registered value listeners if they have not already been notified. 250 * If any other instances of Settable are validated as a side effect, 251 * then an implementation should return a Collection containing those 252 * instances. This can be used by the caller to avoid validating those 253 * again. The list may contain this instance of Settable. 254 * @return A collection of settables that are also validated as a 255 * side effect, or null if there are none. 256 * @exception IllegalActionException If the expression is not valid, or 257 * its value is not acceptable to the container or the listeners. 258 */ 259 @Override 260 public Collection validate() throws IllegalActionException { 261 // Ignore. 262 return null; 263 } 264}