001/* A tableau representing a matrix token in a table.
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.MatrixToken;
033import ptolemy.data.Token;
034import ptolemy.kernel.util.IllegalActionException;
035import ptolemy.kernel.util.NameDuplicationException;
036import ptolemy.kernel.util.NamedObj;
037
038///////////////////////////////////////////////////////////////////
039//// MatrixTokenTableau
040
041/**
042 A tableau representing matrix tokens in a top-level window with a table.
043 This should be constructed using the provided factory, to ensure that
044 the matrix pane is created.
045
046 @author  Edward A. Lee
047 @version $Id$
048 @since Ptolemy II 2.1
049 @Pt.ProposedRating Yellow (eal)
050 @Pt.AcceptedRating Red (cxh)
051 @see TokenEffigy
052 */
053public class MatrixTokenTableau extends TokenTableau {
054    /** Construct a new tableau for the model represented by the given effigy.
055     *  Use setFrame() to specify the plot frame after construction.
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 MatrixTokenTableau(Effigy container, String name)
064            throws IllegalActionException, NameDuplicationException {
065        super(container, name);
066    }
067
068    /** Construct a new tableau for the model represented by the given effigy,
069     *  using the specified frame.
070     *  @param container The container.
071     *  @param name The name.
072     *  @param frame The frame to use.
073     *  @exception IllegalActionException If the container does not accept
074     *   this entity (this should not occur).
075     *  @exception NameDuplicationException If the name coincides with an
076     *   attribute already in the container.
077     */
078    public MatrixTokenTableau(Effigy container, String name, TableauFrame frame)
079            throws IllegalActionException, NameDuplicationException {
080        super(container, name, frame);
081    }
082
083    ///////////////////////////////////////////////////////////////////
084    ////                         public methods                    ////
085
086    /** Display the specified token.
087     *  If the display is not a MatrixPane, or the token is not
088     *  a MatrixToken, do nothing.
089     *  @param token The token to append.
090     */
091    @Override
092    public void append(Token token) {
093        if (_pane != null && token instanceof MatrixToken) {
094            _pane.display((MatrixToken) token);
095        }
096    }
097
098    /** Display the specified tokens.
099     *  If the display is not a MatrixPane, or the tokens are not
100     *  instances of MatrixToken, do nothing.
101     */
102    @Override
103    public void append(List list) {
104        if (_pane != null) {
105            Iterator tokens = list.iterator();
106
107            while (tokens.hasNext()) {
108                Object token = tokens.next();
109
110                if (token instanceof MatrixToken) {
111                    _pane.display((MatrixToken) token);
112                }
113            }
114        }
115    }
116
117    /** Return true if this tableau can display the specified token.
118     *  @param token A candidate token to display.
119     *  @return True if the argument is a MatrixToken.
120     */
121    public static boolean canDisplay(Token token) {
122        if (token instanceof MatrixToken) {
123            return true;
124        } else {
125            return false;
126        }
127    }
128
129    /** Clear the display.
130     */
131    @Override
132    public void clear() {
133        if (_pane != null) {
134            _pane.clear();
135        }
136    }
137
138    /** Create a matrix frame to view the data.  If the argument is null,
139     *  then a new TableauFrame is created.
140     *  This is called in the constructor.
141     *  @see MatrixPane
142     *  @exception IllegalActionException If the frame cannot be created.
143     */
144    @Override
145    public void createFrame(TableauFrame frame) throws IllegalActionException {
146        TokenEffigy effigy = (TokenEffigy) getContainer();
147
148        if (frame == null) {
149            // The second argument prevents a status bar.
150            frame = new TableauFrame(this, null);
151        }
152
153        setFrame(frame);
154        _pane = new MatrixPane();
155        frame.getContentPane().add(_pane);
156
157        // Display current data.
158        Iterator tokens = effigy.getTokens().iterator();
159
160        while (tokens.hasNext()) {
161            Object token = tokens.next();
162            _pane.display((MatrixToken) token);
163        }
164    }
165
166    ///////////////////////////////////////////////////////////////////
167    ////                         private members                   ////
168    // The pane to display matrices.
169    private MatrixPane _pane;
170
171    ///////////////////////////////////////////////////////////////////
172    ////                         inner classes                     ////
173
174    /** A factory that creates a matrix token tableau.
175     */
176    public static class Factory extends TableauFactory {
177        /** Create a factory with the given name and container.
178         *  @param container The container.
179         *  @param name The name.
180         *  @exception IllegalActionException If the container is incompatible
181         *   with this attribute.
182         *  @exception NameDuplicationException If the name coincides with
183         *   an attribute already in the container.
184         */
185        public Factory(NamedObj container, String name)
186                throws IllegalActionException, NameDuplicationException {
187            super(container, name);
188        }
189
190        ///////////////////////////////////////////////////////////////////
191        ////                         public methods                    ////
192
193        /** If the specified effigy already contains a tableau named
194         *  "tokenTableau", then return that tableau; otherwise, create
195         *  a new instance of MatrixTokenTableau in the specified
196         *  effigy, and name it "tokenTableau".  If the specified
197         *  effigy is not an instance of TokenEffigy, then do not
198         *  create a tableau and return null.  This method will also
199         *  create a frame for viewing the token data.  Which frame
200         *  is created depends on the type of the data in the effigy.
201         *  The fallback is a TextEditor. It is the
202         *  responsibility of callers of this method to check the
203         *  return value and call show().
204         *
205         *  @param effigy The effigy, which is expected to be a TokenEffigy.
206         *  @return An instance of MatrixTokenTableau, or null if one cannot be
207         *    found or created.
208         *  @exception Exception If the factory should be able to create a
209         *   tableau for the effigy, but something goes wrong.
210         */
211        @Override
212        public Tableau createTableau(Effigy effigy) throws Exception {
213            if (effigy instanceof TokenEffigy) {
214                // Indicate to the effigy that this factory contains effigies
215                // offering multiple views of the effigy data.
216                effigy.setTableauFactory(this);
217
218                // First see whether the effigy already contains a
219                // TokenTableau.
220                TokenTableau tableau = (TokenTableau) effigy
221                        .getEntity("tokenTableau");
222
223                if (tableau != null) {
224                    return tableau;
225                }
226
227                // Next, check compatibility of the data.
228                Iterator tokens = ((TokenEffigy) effigy).getTokens().iterator();
229
230                while (tokens.hasNext()) {
231                    Object token = tokens.next();
232
233                    if (!MatrixTokenTableau.canDisplay((Token) token)) {
234                        return null;
235                    }
236                }
237
238                return new MatrixTokenTableau(effigy, "tokenTableau");
239            }
240
241            return null;
242        }
243    }
244}