001/* A tableau representing a token in a text editor. 002 003 Copyright (c) 2000-2014 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 */ 027package ptolemy.actor.gui; 028 029import java.util.Iterator; 030import java.util.List; 031 032import ptolemy.data.Token; 033import ptolemy.kernel.util.IllegalActionException; 034import ptolemy.kernel.util.NameDuplicationException; 035import ptolemy.kernel.util.NamedObj; 036 037/////////////////////////////////////////////////////////////////// 038//// TokenTableau 039 040/** 041 A tableau representing one or more tokens in a top-level window with 042 a text editor. Subclasses can be created to represent specific token 043 types in more specialized ways. 044 045 @author Edward A. Lee 046 @version $Id$ 047 @since Ptolemy II 2.1 048 @Pt.ProposedRating Yellow (eal) 049 @Pt.AcceptedRating Red (cxh) 050 @see TokenEffigy 051 */ 052public class TokenTableau extends Tableau { 053 /** Construct a new tableau for the model represented by the given effigy. 054 * This constructor creates a default editor frame, which is an instance 055 * of TextEditor. 056 * @param container The container. 057 * @param name The name. 058 * @exception IllegalActionException If the container does not accept 059 * this entity (this should not occur). 060 * @exception NameDuplicationException If the name coincides with an 061 * attribute already in the container. 062 */ 063 public TokenTableau(Effigy container, String name) 064 throws IllegalActionException, NameDuplicationException { 065 super(container, name); 066 createFrame(null); 067 } 068 069 /** Construct a new tableau for the model represented by the given effigy, 070 * using the specified frame. 071 * @param container The container. 072 * @param name The name. 073 * @param frame The frame to use. 074 * @exception IllegalActionException If the container does not accept 075 * this entity (this should not occur). 076 * @exception NameDuplicationException If the name coincides with an 077 * attribute already in the container. 078 */ 079 public TokenTableau(Effigy container, String name, TableauFrame frame) 080 throws IllegalActionException, NameDuplicationException { 081 super(container, name); 082 createFrame(frame); 083 } 084 085 /////////////////////////////////////////////////////////////////// 086 //// public methods //// 087 088 /** Append the specified token to the display. 089 * If the display is not a TextEditor, do nothing. 090 * Subclasses should override this with display-specific actions. 091 * @param token The token to append. 092 * @exception IllegalActionException If the token is not 093 * acceptable (not thrown in this base class). 094 */ 095 public void append(Token token) throws IllegalActionException { 096 if (_editor != null) { 097 _editor.text.append(token.toString()); 098 } 099 } 100 101 /** Append the specified tokens to the display. 102 * @param list A list of tokens. 103 * @exception IllegalActionException If the tokens are not 104 * acceptable (not thrown in this base class). 105 */ 106 public void append(List list) throws IllegalActionException { 107 if (_editor != null) { 108 Iterator tokens = list.iterator(); 109 110 while (tokens.hasNext()) { 111 _editor.text.append(tokens.next().toString()); 112 } 113 } 114 } 115 116 /** Return true if this tableau can display the specified token. 117 * @param token A candidate token to display. 118 * @return True, since this tableau can display any token. 119 */ 120 public static boolean canDisplay(Token token) { 121 return true; 122 } 123 124 /** Clear the display. 125 */ 126 public void clear() { 127 if (_editor != null) { 128 _editor.text.setText(""); 129 } 130 } 131 132 /** Create a text editor frame to view the data. This can be overridden 133 * in derived classes to create more specialized viewers/editors. 134 * If the specified frame is not an instance of TextEditor, then 135 * it is replaced with a text editor. 136 * This is called in the constructor. 137 * @param frame The frame to use, or null if none is specified. 138 * @exception IllegalActionException If the frame cannot be created. 139 */ 140 public void createFrame(TableauFrame frame) throws IllegalActionException { 141 TokenEffigy effigy = (TokenEffigy) getContainer(); 142 143 if (!(frame instanceof TextEditor)) { 144 frame = new TextEditor("Token display"); 145 } 146 147 setFrame(frame); 148 frame.setTableau(this); 149 ((TextEditor) frame).text.setEditable(false); 150 151 // Display current data. 152 Iterator tokens = effigy.getTokens().iterator(); 153 154 while (tokens.hasNext()) { 155 ((TextEditor) frame).text.append(tokens.next().toString()); 156 ((TextEditor) frame).text.append("\n"); 157 } 158 159 _editor = (TextEditor) frame; 160 } 161 162 /////////////////////////////////////////////////////////////////// 163 //// private members //// 164 // The frame as a text editor. 165 private TextEditor _editor; 166 167 /////////////////////////////////////////////////////////////////// 168 //// inner classes //// 169 170 /** A factory that creates a token tableau. 171 */ 172 public static class Factory extends TableauFactory { 173 /** Create a factory with the given name and container. 174 * @param container The container. 175 * @param name The name. 176 * @exception IllegalActionException If the container is incompatible 177 * with this attribute. 178 * @exception NameDuplicationException If the name coincides with 179 * an attribute already in the container. 180 */ 181 public Factory(NamedObj container, String name) 182 throws IllegalActionException, NameDuplicationException { 183 super(container, name); 184 } 185 186 /////////////////////////////////////////////////////////////////// 187 //// public methods //// 188 189 /** If the specified effigy already contains a tableau named 190 * "tokenTableau", then return that tableau; otherwise, create 191 * a new instance of TokenTableau in the specified 192 * effigy, and name it "tokenTableau". If the specified 193 * effigy is not an instance of TokenEffigy, then do not 194 * create a tableau and return null. It is the 195 * responsibility of callers of this method to check the 196 * return value and call show(). 197 * 198 * @param effigy The effigy, which is expected to be a TokenEffigy. 199 * @return An instance of TokenTableau, or null if one cannot be 200 * found or created. 201 * @exception Exception If the factory should be able to create a 202 * tableau for the effigy, but something goes wrong. 203 */ 204 @Override 205 public Tableau createTableau(Effigy effigy) throws Exception { 206 if (effigy instanceof TokenEffigy) { 207 // First see whether the effigy already contains an 208 // TokenTableau. 209 TokenTableau tableau = (TokenTableau) effigy 210 .getEntity("tokenTableau"); 211 212 if (tableau != null) { 213 return tableau; 214 } 215 216 // NOTE: Normally need to check effigy tokens for 217 // compatibility here, but they are always compatible, 218 // so we don't bother. 219 return new TokenTableau(effigy, "tokenTableau"); 220 } 221 222 return null; 223 } 224 } 225}