001/* An object that can create a tableau for a model. 002 003 Copyright (c) 1997-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 027 028 */ 029package ptolemy.actor.gui; 030 031import java.net.URL; 032import java.util.Iterator; 033 034import javax.swing.SwingUtilities; 035 036import ptolemy.kernel.util.Attribute; 037import ptolemy.kernel.util.Configurable; 038import ptolemy.kernel.util.IllegalActionException; 039import ptolemy.kernel.util.NameDuplicationException; 040import ptolemy.kernel.util.NamedObj; 041import ptolemy.moml.MoMLChangeRequest; 042 043/////////////////////////////////////////////////////////////////// 044//// TableauFactory 045 046/** 047 This class is an attribute that creates a tableau to view a specified effigy. 048 When a model is opened, if the top-level of that model contains this 049 attribute or a subclass, then that attribute handles constructing a tableau. 050 Otherwise, the configuration specifies which tableau is used. 051 A configuration contains an instance of this class, and uses it to create 052 a tableau for a model represented by an effigy. This base class assumes 053 that it contains other tableau factories. Its createTableau() method defers 054 to each contained factory, in the order in which they were added, 055 until one is capable of creating a tableau for the specified effigy. 056 Subclasses of this class will usually be inner classes of a Tableau, 057 and will create the Tableau, or might themselves be aggregates of 058 instances of TextEditorTableauFactory. 059 <p> 060 When there are multiple distinct TableauFactory classes that are capable 061 of providing views on the same effigy, then instances of these 062 factories should be aggregated into a single factory contained herein. 063 Those instances can be presented as alternative views of the data when 064 any single view is opened. 065 <p> 066 There is a significant subtlety with respect to how Ptolemy II classes 067 are dealt with. Normally, when one looks inside an instance of a class, 068 what is opened is the class definition, not the instance. However, 069 if the instance contains an instance of TableauFactory, then what 070 is opened is the instance, not the class definition. This is used, 071 for example, when the look inside behavior is customized on a per 072 instance basis. 073 074 @author Steve Neuendorffer and Edward A. Lee 075 @version $Id$ 076 @since Ptolemy II 1.0 077 @Pt.ProposedRating Green (eal) 078 @Pt.AcceptedRating Yellow (celaine) 079 @see Configuration 080 @see Effigy 081 @see Tableau 082 */ 083public class TableauFactory extends Attribute implements Configurable { 084 /** Create a factory with the given name and container. 085 * @param container The container. 086 * @param name The name. 087 * @exception IllegalActionException If the container is incompatible 088 * with this attribute. 089 * @exception NameDuplicationException If the name coincides with 090 * an attribute already in the container. 091 */ 092 public TableauFactory(NamedObj container, String name) 093 throws IllegalActionException, NameDuplicationException { 094 super(container, name); 095 } 096 097 /////////////////////////////////////////////////////////////////// 098 //// public methods //// 099 100 /** Create a tableau for the specified effigy. The tableau will be 101 * created with a new unique name with the specified effigy as its 102 * container. If this factory cannot create a tableau 103 * for the given effigy (perhaps because the effigy is not of the 104 * appropriate subclass), then return null. This base class assumes 105 * that it contains other tableau factories. This method defers 106 * to each contained factory in order until one is capable of creating a 107 * tableau for the specified effigy. As with all attributes, the order 108 * is simply the order of creation. Subclasses of this class will 109 * usually be inner classes of a Tableau, and will create the Tableau. 110 * A subclass that actually creates a tableau is responsible for setting 111 * the container of the tableau to the specified effigy, and for naming 112 * the tableau. 113 * Subclasses should not call show() in createTableau(), it is the 114 * responsibility of the caller to check the return value and 115 * call show() after doing things like adjusting the size. 116 * @param effigy The model effigy. 117 * @return A tableau for the effigy, or null if one cannot be created. 118 * @exception Exception If the factory should be able to create a 119 * Tableau for the effigy, but something goes wrong. 120 */ 121 public Tableau createTableau(Effigy effigy) throws Exception { 122 Tableau tableau = null; 123 Iterator factories = attributeList(TableauFactory.class).iterator(); 124 125 while (factories.hasNext() && tableau == null) { 126 TableauFactory factory = (TableauFactory) factories.next(); 127 tableau = factory.createTableau(effigy); 128 if (tableau != null) { 129 factory._configureTableau(tableau); 130 } 131 } 132 133 return tableau; 134 } 135 136 /** Configure the tableau factory with data from the specified input source 137 * (a URL) and/or textual data. The data is recorded locally without 138 * parsing. 139 * @param base The base relative to which references within the input 140 * are found, or null if this is not known, or there is none. 141 * @param source The input source, which specifies a URL, or null 142 * if none. 143 * @param text Configuration information given as text, or null if 144 * none. 145 * @exception Exception If something goes wrong. No thrown in this class. 146 */ 147 @Override 148 public void configure(URL base, String source, String text) 149 throws Exception { 150 _configureSource = source; 151 _configureText = text; 152 } 153 154 /** Return the input source that was specified the last time the configure 155 * method was called. 156 * @return The string representation of the input URL, or null if the 157 * no source has been used to configure this object, or null if no 158 * external source need be used to configure this object. 159 */ 160 @Override 161 public String getConfigureSource() { 162 return _configureSource; 163 } 164 165 /** Return the text string that represents the current configuration of 166 * this object. Note that any configuration that was previously 167 * specified using the source attribute need not be represented here 168 * as well. 169 * @return A configuration string, or null if no configuration 170 * has been used to configure this object, or null if no 171 * configuration string need be used to configure this object. 172 */ 173 @Override 174 public String getConfigureText() { 175 return _configureText; 176 } 177 178 /** Configure the given tableau with the configuration data attached to this 179 * tableau factory, if any. 180 * 181 * @param tableau The tableau to be configured. 182 */ 183 protected void _configureTableau(final Tableau tableau) { 184 if (_configureText != null) { 185 SwingUtilities.invokeLater(new Runnable() { 186 @Override 187 public void run() { 188 MoMLChangeRequest request = new MoMLChangeRequest(this, 189 tableau, _configureText); 190 tableau.requestChange(request); 191 } 192 }); 193 } 194 } 195 196 /** The input source that was specified the last time the configure method 197 * was called. 198 */ 199 private String _configureSource; 200 201 /** The text string that represents the current configuration of this 202 * object. 203 */ 204 private String _configureText; 205}