001/* An icon that renders the value of all attributes of the container. 002 003 Copyright (c) 2003-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.Color; 031import java.awt.Font; 032import java.awt.geom.Rectangle2D; 033import java.util.Iterator; 034 035import javax.swing.SwingConstants; 036 037import diva.canvas.CompositeFigure; 038import diva.canvas.Figure; 039import diva.canvas.toolbox.BasicRectangle; 040import diva.canvas.toolbox.LabelFigure; 041import ptolemy.data.IntToken; 042import ptolemy.data.expr.Parameter; 043import ptolemy.data.type.BaseType; 044import ptolemy.kernel.util.IllegalActionException; 045import ptolemy.kernel.util.NameDuplicationException; 046import ptolemy.kernel.util.NamedObj; 047import ptolemy.kernel.util.Settable; 048 049/////////////////////////////////////////////////////////////////// 050//// BoxedValuesIcon 051 052/** 053 This icon displays the value of all visible attributes of class Settable 054 contained by the container of this icon. Visible attributes are those 055 whose visibility is Settable.FULL. The names and values of the attributes 056 are displayed in a box that resizes as necessary. If any line is longer 057 than <i>displayWidth</i> (in characters), then it is truncated. 058 059 @author Edward A. Lee 060 @version $Id$ 061 @since Ptolemy II 4.0 062 @Pt.ProposedRating Yellow (eal) 063 @Pt.AcceptedRating Red (johnr) 064 */ 065public class BoxedValuesIcon extends XMLIcon { 066 /** Create a new icon with the given name in the given container. 067 * The container is required to implement Settable, or an exception 068 * will be thrown. 069 * @param container The container for this attribute. 070 * @param name The name of this attribute. 071 * @exception IllegalActionException If thrown by the parent 072 * class or while setting an attribute. 073 * @exception NameDuplicationException If the name coincides with 074 * an attribute already in the container. 075 */ 076 public BoxedValuesIcon(NamedObj container, String name) 077 throws NameDuplicationException, IllegalActionException { 078 super(container, name); 079 080 displayWidth = new Parameter(this, "displayWidth"); 081 displayWidth.setExpression("80"); 082 displayWidth.setTypeEquals(BaseType.INT); 083 084 setPersistent(false); 085 } 086 087 /////////////////////////////////////////////////////////////////// 088 //// parameters //// 089 090 /** The number of characters to display. This is an integer, with 091 * default value 80. 092 */ 093 public Parameter displayWidth; 094 095 /////////////////////////////////////////////////////////////////// 096 //// public methods //// 097 098 /** Create a new background figure. This overrides the base class 099 * to draw a box around the value display, where the width of the 100 * box depends on the value. 101 * @return A new figure. 102 */ 103 @Override 104 public Figure createBackgroundFigure() { 105 String displayString = _displayString(); 106 double width = 60; 107 double heigth = 30; 108 109 if (displayString != null) { 110 // Measure width of the text. Unfortunately, this 111 // requires generating a label figure that we will not use. 112 LabelFigure label = new LabelFigure(displayString, _labelFont, 1.0, 113 SwingConstants.CENTER); 114 Rectangle2D stringBounds = label.getBounds(); 115 116 // NOTE: Padding of 20. 117 width = stringBounds.getWidth() + 20; 118 heigth = stringBounds.getHeight() + 10; 119 } 120 121 BasicRectangle result = new BasicRectangle(0, 0, width, heigth, 122 Color.white, 1); 123 124 // FIXME: Doesn't do the right thing. 125 // result.setCentered(false); 126 return result; 127 } 128 129 /** Create a new Diva figure that visually represents this icon. 130 * The figure will be an instance of LabelFigure that renders the 131 * values of the attributes of the container. 132 * @return A new CompositeFigure consisting of the label. 133 */ 134 @Override 135 public Figure createFigure() { 136 CompositeFigure result = (CompositeFigure) super.createFigure(); 137 String truncated = _displayString(); 138 139 // If there is no string to display now, then create a string 140 // with a single blank. 141 if (truncated == null) { 142 truncated = " "; 143 } 144 145 // NOTE: This violates the Diva MVC architecture! 146 // This attribute is part of the model, and should not have 147 // a reference to this figure. By doing so, it precludes the 148 // possibility of having multiple views on this model. 149 LabelFigure label = new LabelFigure(truncated, _labelFont, 1.0, 150 SwingConstants.CENTER); 151 Rectangle2D backBounds = result.getBackgroundFigure().getBounds(); 152 label.translateTo(backBounds.getCenterX(), backBounds.getCenterY()); 153 result.add(label); 154 155 _addLiveFigure(label); 156 return result; 157 } 158 159 /////////////////////////////////////////////////////////////////// 160 //// protected methods //// 161 162 /** Get the string to render in the icon. This string is the 163 * expression giving the value of the attribute of the container 164 * having the name <i>attributeName</i>, truncated so that it is 165 * no longer than <i>displayWidth</i> characters. If it is truncated, 166 * then the string has a trailing "...". If the string is empty, 167 * then return a string with one space (diva fails on empty strings). 168 * @return The string to display, or null if none is found. 169 */ 170 protected String _displayString() { 171 NamedObj container = getContainer(); 172 173 if (container != null) { 174 StringBuffer buffer = new StringBuffer(); 175 Iterator settables = container.attributeList(Settable.class) 176 .iterator(); 177 178 while (settables.hasNext()) { 179 Settable settable = (Settable) settables.next(); 180 181 if (settable.getVisibility() != Settable.FULL 182 && settable.getVisibility() != Settable.NOT_EDITABLE) { 183 continue; 184 } 185 186 String name = settable.getDisplayName(); 187 String value = settable.getExpression(); 188 String line = name + ": " + value; 189 String truncated = line; 190 191 try { 192 int width = ((IntToken) displayWidth.getToken()).intValue(); 193 194 if (line.length() > width) { 195 truncated = line.substring(0, width) + "..."; 196 } 197 } catch (IllegalActionException ex) { 198 // Ignore... use whole string. 199 } 200 201 buffer.append(truncated); 202 203 if (settables.hasNext()) { 204 buffer.append("\n"); 205 } 206 } 207 208 return buffer.toString(); 209 } 210 211 return null; 212 } 213 214 /////////////////////////////////////////////////////////////////// 215 //// protected members //// 216 217 /** The font used. */ 218 protected static final Font _labelFont = new Font("Dialog", Font.PLAIN, 12); 219}