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}