001/* Base class for AWT and Swing implementation of actors the implement
002PortablePlaceable.
003
004 @Copyright (c) 1998-2014 The Regents of the University of California.
005 All rights reserved.
006
007 Permission is hereby granted, without written agreement and without
008 license or royalty fees, to use, copy, modify, and distribute this
009 software and its documentation for any purpose, provided that the
010 above copyright notice and the following two paragraphs appear in all
011 copies of this software.
012
013 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
014 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
015 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
016 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
017 SUCH DAMAGE.
018
019 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
020 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
021 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
022 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
023 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
024 ENHANCEMENTS, OR MODIFICATIONS.
025
026 PT_COPYRIGHT_VERSION 2
027 COPYRIGHTENDKEY
028 */
029
030package ptolemy.actor.gui;
031
032import java.awt.Component;
033import java.awt.event.WindowAdapter;
034import java.awt.event.WindowEvent;
035import java.io.IOException;
036import java.io.Writer;
037
038import javax.swing.JFrame;
039
040import ptolemy.actor.TypedAtomicActor;
041import ptolemy.kernel.util.IllegalActionException;
042import ptolemy.kernel.util.NameDuplicationException;
043
044///////////////////////////////////////////////////////////////////
045////AbstractAWTPlaceable
046
047/**
048Base class for AWT and Swing implementation of actors the implement
049PortablePlaceable.
050
051@author Edward A. Lee, Ishwinder Singh
052@version $Id$
053@since Ptolemy II 10.0
054@Pt.ProposedRating Red (ishwinde)
055@Pt.AcceptedRating Red (ishwinde)
056 */
057
058public abstract class AbstractPlaceableJavaSE {
059
060    /** Initialize the specified actor with window properties and pane size attributes.
061     *  @param actor The actor contained in the Window.
062     *  @exception IllegalActionException If the entity cannot be contained
063     *   by the proposed container.
064     *  @exception NameDuplicationException If the container already has an
065     *   actor with this name.
066     */
067    public void init(TypedAtomicActor actor)
068            throws IllegalActionException, NameDuplicationException {
069        // An actor may already have _windowProperties set.
070        _windowProperties = (WindowPropertiesAttribute) actor.getAttribute(
071                "_windowProperties", WindowPropertiesAttribute.class);
072        if (_windowProperties == null) {
073            _windowProperties = new WindowPropertiesAttribute(actor,
074                    "_windowProperties");
075        }
076
077        // Note that we have to force this to be persistent because
078        // there is no real mechanism for the value of the properties
079        // to be updated when the window is moved or resized. By
080        // making it persistent, when the model is saved, the
081        // attribute will determine the current size and position
082        // of the window and save it.
083        _windowProperties.setPersistent(true);
084
085        _paneSize = (SizeAttribute) actor.getAttribute("_paneSize",
086                SizeAttribute.class);
087        if (_paneSize == null) {
088            _paneSize = new SizeAttribute(actor, "_paneSize");
089        }
090        _paneSize.setPersistent(true);
091    }
092
093    /** Specify the associated frame and set its properties (size, etc.)
094     *  to match those stored in the _windowProperties attribute.
095     *  @param frame The associated frame.
096     */
097    public void setFrame(JFrame frame) {
098
099        if (_frame != null) {
100            _frame.removeWindowListener(_windowClosingAdapter);
101        }
102
103        if (frame == null) {
104            _frame = null;
105            return;
106        }
107
108        _frame = frame;
109
110        _windowClosingAdapter = new WindowClosingAdapter();
111        frame.addWindowListener(_windowClosingAdapter);
112
113        _windowProperties.setProperties(_frame);
114
115        // Regrettably, since setSize() in swing doesn't actually
116        // set the size of the frame, we have to also set the
117        // size of the internal component.
118        Component[] components = _frame.getContentPane().getComponents();
119
120        if (components.length > 0) {
121            _paneSize.setSize(components[0]);
122        }
123    }
124
125    ///////////////////////////////////////////////////////////////////
126    ////                         protected methods                 ////
127
128    /** Free up memory when closing. */
129    protected void cleanUp() {
130        setFrame(null);
131    }
132
133    /** Write a MoML description of the contents of this object. This
134     *  overrides the base class to make sure that the current frame
135     *  properties, if there is a frame, are recorded.
136     *  @param output The output stream to write to.
137     *  @param depth The depth in the hierarchy, to determine indenting.
138     *  @exception IOException If an I/O error occurs.
139     */
140    protected void _exportMoMLContents(
141            /*TypedAtomicActor actor, */Writer output, int depth)
142            throws IOException {
143        // Make sure that the current position of the frame, if any,
144        // is up to date.
145        if (_frame != null) {
146            _windowProperties.recordProperties(_frame);
147
148            // Regrettably, have to also record the size of the contents
149            // because in Swing, setSize() methods do not set the size.
150            // Only the first component size is recorded.
151            Component[] components = _frame.getContentPane().getComponents();
152
153            if (components.length > 0) {
154                _paneSize.recordSize(components[0]);
155            }
156        }
157    }
158
159    ///////////////////////////////////////////////////////////////////
160    ////                         protected variables               ////
161
162    /** The associated frame. */
163    protected JFrame _frame;
164
165    /** A specification of the size of the pane if it's in its own window. */
166    protected SizeAttribute _paneSize;
167
168    /** A specification for the window properties of the frame. */
169    protected WindowPropertiesAttribute _windowProperties;
170
171    /** A reference to the listener for removal purposes. */
172    protected WindowClosingAdapter _windowClosingAdapter;
173
174    ///////////////////////////////////////////////////////////////////
175    ////                         inner classes                     ////
176
177    /** Listener for windowClosing action. */
178    public class WindowClosingAdapter extends WindowAdapter {
179        @Override
180        public void windowClosing(WindowEvent e) {
181            cleanUp();
182        }
183    }
184
185}