001/* An icon that renders the value of an attribute of the container. 002 003 Copyright (c) 1999-2016 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 027 */ 028package ptolemy.vergil.icon; 029 030import java.awt.Font; 031import java.awt.geom.Rectangle2D; 032 033import javax.swing.SwingConstants; 034 035import diva.canvas.CompositeFigure; 036import diva.canvas.Figure; 037import diva.canvas.toolbox.LabelFigure; 038import ptolemy.data.IntToken; 039import ptolemy.data.expr.Parameter; 040import ptolemy.data.expr.StringParameter; 041import ptolemy.data.type.BaseType; 042import ptolemy.kernel.CompositeEntity; 043import ptolemy.kernel.util.Attribute; 044import ptolemy.kernel.util.IllegalActionException; 045import ptolemy.kernel.util.NameDuplicationException; 046import ptolemy.kernel.util.NamedObj; 047import ptolemy.kernel.util.Settable; 048import ptolemy.kernel.util.StringAttribute; 049import ptolemy.util.StringUtilities; 050 051/////////////////////////////////////////////////////////////////// 052//// AttributeValueIcon 053 054/** 055 An icon that displays the value of an attribute of the container 056 or of some other entity contained by the container. 057 The attribute is assumed to be an instance of Settable, and its name 058 is given by the parameter <i>attributeName</i>. The display is not 059 automatically updated when the attribute value is updated. 060 061 @author Edward A. Lee 062 @version $Id$ 063 @since Ptolemy II 2.0 064 @Pt.ProposedRating Yellow (eal) 065 @Pt.AcceptedRating Red (johnr) 066 */ 067public class AttributeValueIcon extends XMLIcon { 068 /** Create a new icon with the given name in the given container. 069 * The container is required to implement Settable, or an exception 070 * will be thrown. 071 * @param container The container for this attribute. 072 * @param name The name of this attribute. 073 * @exception IllegalActionException If thrown by the parent 074 * class or while setting an attribute 075 * @exception NameDuplicationException If the name coincides with 076 * an attribute already in the container. 077 */ 078 public AttributeValueIcon(NamedObj container, String name) 079 throws NameDuplicationException, IllegalActionException { 080 super(container, name); 081 082 attributeName = new StringAttribute(this, "attributeName"); 083 084 displayWidth = new Parameter(this, "displayWidth"); 085 displayWidth.setExpression("6"); 086 displayWidth.setTypeEquals(BaseType.INT); 087 088 displayHeight = new Parameter(this, "displayHeight"); 089 displayHeight.setExpression("1"); 090 displayHeight.setTypeEquals(BaseType.INT); 091 092 entityName = new StringParameter(this, "entityName"); 093 entityName.setExpression(""); 094 } 095 096 /////////////////////////////////////////////////////////////////// 097 //// parameters //// 098 099 /** The name of the attribute of the container whose value to display. 100 * This is a string that by default is empty. An empty string means 101 * that the attribute whose value to display is the container itself, 102 * rather than an attribute contained by the container. 103 */ 104 public StringAttribute attributeName; 105 106 /** The maximum number of lines to display. This is an integer, with 107 * default value 1. 108 */ 109 public Parameter displayHeight; 110 111 /** The number of characters to display. This is an integer, with 112 * default value 6. 113 */ 114 public Parameter displayWidth; 115 116 /** Name of the entity contained by the container whose attribute 117 * this icon will display. This is a string that defaults to the 118 * empty string, which means that the attribute is contained 119 * by the container of this attribute. 120 */ 121 public StringParameter entityName; 122 123 /////////////////////////////////////////////////////////////////// 124 //// public methods //// 125 126 /** Create a new Diva figure that visually represents this icon. 127 * The figure will be an instance of LabelFigure that renders the 128 * value of the specified attribute of the container. 129 * @return A new CompositeFigure consisting of the label. 130 */ 131 @Override 132 public Figure createFigure() { 133 CompositeFigure result = (CompositeFigure) super.createFigure(); 134 String truncated = _displayString(); 135 136 LabelFigure label = new LabelFigure(truncated, _labelFont, 1.0, 137 SwingConstants.CENTER); 138 Rectangle2D backBounds = result.getBackgroundFigure().getBounds(); 139 label.translateTo(backBounds.getCenterX(), backBounds.getCenterY()); 140 result.add(label); 141 142 _addLiveFigure(label); 143 return result; 144 } 145 146 /////////////////////////////////////////////////////////////////// 147 //// protected methods //// 148 149 /** Return the associated attribute. If an {@link #entityName} is given, 150 * then the associated attribute is attribute with name given by 151 * {@link #attributeName} contained by the specified entity. 152 * If no entityName is given, then the associated attribute is 153 * the one contained by the container of this object with the 154 * specified name. If no attributeName is given either, and the 155 * the container of this object is an Attribute, then the associated 156 * attribute is that container. Otherwise, throw an exception. 157 * @return The associated attribute. 158 * @exception IllegalActionException If no Settable associated attribute 159 * can be found. 160 */ 161 protected Settable _associatedAttribute() throws IllegalActionException { 162 NamedObj container = getContainer(); 163 if (entityName.stringValue().trim().equals("")) { 164 String name = attributeName.getExpression(); 165 if (!name.trim().equals("") && container != null) { 166 Attribute candidate = container.getAttribute(name); 167 if (candidate instanceof Settable) { 168 return (Settable) candidate; 169 } 170 } else { 171 // No attributeName is given. 172 // If the container is an Attribute, use it. 173 if (container instanceof Settable) { 174 return (Settable) container; 175 } 176 } 177 } else if (container instanceof CompositeEntity) { 178 NamedObj entity = ((CompositeEntity) container) 179 .getEntity(entityName.stringValue()); 180 if (entity != null) { 181 Attribute candidate = entity 182 .getAttribute(attributeName.getExpression()); 183 if (candidate instanceof Settable) { 184 return (Settable) candidate; 185 } 186 } 187 } 188 throw new IllegalActionException(this, "No associated attribute."); 189 } 190 191 /** Get the string value of the attribute to render in the icon. 192 * This string is the expression giving the value of the attribute of the 193 * container having the name <i>attributeName</i>. If the string is empty, 194 * then return a string with one space (diva fails on empty strings). This 195 * method will always return the full string value of the attribute and will 196 * not be truncated. 197 * @return The string value of the attribute to display, or a string with 198 * one space if none is found. 199 */ 200 protected String _attributeValueString() { 201 try { 202 String value = _associatedAttribute().getExpression(); 203 if (value == null || value.equals("")) { 204 value = " "; 205 } 206 return value; 207 } catch (IllegalActionException e) { 208 // Ignore and produce a default icon. 209 return " "; 210 } 211 } 212 213 /** Get the string to render in the icon. This string is the 214 * expression giving the value of the attribute of the container 215 * having the name <i>attributeName</i>, truncated so that it is 216 * no longer than <i>displayWidth</i> characters. If it is truncated, 217 * then the string has a trailing "...". If the string is empty, 218 * then return a string with one space (diva fails on empty strings). 219 * @return The string to display, or a string with one space if none is found. 220 */ 221 protected String _displayString() { 222 String truncated = _attributeValueString(); 223 224 try { 225 int width = ((IntToken) displayWidth.getToken()).intValue(); 226 int height = ((IntToken) displayHeight.getToken()).intValue(); 227 truncated = StringUtilities.truncateString(truncated, width, 228 height); 229 } catch (IllegalActionException ex) { 230 // Ignore... use whole string. 231 } 232 233 if (truncated.length() == 0) { 234 truncated = " "; 235 } 236 237 return truncated; 238 } 239 240 /////////////////////////////////////////////////////////////////// 241 //// protected members //// 242 243 /** The font used. */ 244 protected static final Font _labelFont = new Font("SansSerif", Font.PLAIN, 245 12); 246}