001/* An actor that generates an empty token in response to a click of a button.
002
003 @Copyright (c) 1998-2014 The Regents of the University of California.
004 All rights reserved.
005
006 Permission is hereby granted, without written agreement and without
007 license or royalty fees, to use, copy, modify, and distribute this
008 software and its documentation for any purpose, provided that the
009 above copyright notice and the following two paragraphs appear in all
010 copies of this software.
011
012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
016 SUCH DAMAGE.
017
018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
023 ENHANCEMENTS, OR MODIFICATIONS.
024
025 PT_COPYRIGHT_VERSION 2
026 COPYRIGHTENDKEY
027 */
028package ptolemy.domains.de.lib;
029
030import java.awt.Color;
031import java.awt.Container;
032import java.awt.event.ActionEvent;
033import java.awt.event.ActionListener;
034
035import javax.swing.JButton;
036import javax.swing.JFrame;
037import javax.swing.SwingUtilities;
038
039import ptolemy.actor.gui.Placeable;
040import ptolemy.actor.lib.Source;
041import ptolemy.data.Token;
042import ptolemy.data.type.BaseType;
043import ptolemy.kernel.CompositeEntity;
044import ptolemy.kernel.util.IllegalActionException;
045import ptolemy.kernel.util.InternalErrorException;
046import ptolemy.kernel.util.NameDuplicationException;
047import ptolemy.kernel.util.StringAttribute;
048
049///////////////////////////////////////////////////////////////////
050//// EventButton
051
052/**
053 Output a Token in response to a click of a button. This class is closely
054 related to the ButtonTime class in SR domain by Paul Whitaker.
055
056 @author  Winthrop Williams
057 @version $Id$
058 @since Ptolemy II 2.0
059 @deprecated Use ptolemy.actor.lib.gui.EventButton, it is domain polymorphic.
060 @Pt.ProposedRating Red (winthrop)
061 @Pt.AcceptedRating Red (winthrop)
062 */
063@Deprecated
064public class EventButton extends Source implements Placeable {
065    // FIXME: This actor is almost identitcal to the SR ButtonTime actor.
066    // There is no need to have a copy here. An alternative design is to
067    // put one of them into actor.lib direcory.
068
069    /** Construct an actor with an input multiport of type GENERAL.
070     *  @param container The container.
071     *  @param name The name of this actor.
072     *  @exception IllegalActionException If the entity cannot be contained
073     *   by the proposed container.
074     *  @exception NameDuplicationException If the container already has an
075     *   actor with this name.
076     */
077    public EventButton(CompositeEntity container, String name)
078            throws IllegalActionException, NameDuplicationException {
079        super(container, name);
080
081        text = new StringAttribute(this, "text");
082        text.setExpression("Click!");
083
084        output.setTypeEquals(BaseType.GENERAL);
085
086        _self = this;
087    }
088
089    ///////////////////////////////////////////////////////////////////
090    ////        public variables and parameters                    ////
091
092    /** The text to put on the button. */
093    public StringAttribute text;
094
095    ///////////////////////////////////////////////////////////////////
096    ////                         public methods                    ////
097
098    /** Fire the actor.
099     */
100    @Override
101    public void fire() throws IllegalActionException {
102        super.fire();
103        if (_buttonPressed) {
104            output.broadcast(new Token());
105        }
106    }
107
108    /** Get the background color.
109     *  @return The Color of the background.
110     *  @see #setBackground(Color)
111     */
112    public Color getBackground() {
113        return _button.getBackground();
114    }
115
116    /** Create a button on the screen, if necessary. If a graphical
117     *  container has
118     *  not been specified, place the button into its own frame.
119     *  Otherwise, place it in the specified container.
120     *  @exception IllegalActionException If the parent class throws it.
121     */
122    @Override
123    public void initialize() throws IllegalActionException {
124        super.initialize();
125        _buttonPressed = false;
126
127        if (_button == null) {
128            place(_container);
129        }
130
131        if (_frame != null) {
132            _frame.setVisible(true);
133            _frame.toFront();
134        }
135    }
136
137    /** An instance of JButton will be added to the specified container.
138     *  This method needs to be called before the first call to initialize().
139     *  Otherwise, an instance of JButton will be placed in its own frame.
140     *  @param container The container into which to place the button.
141     */
142    @Override
143    public void place(Container container) {
144        _container = container;
145        _button = new JButton(text.getExpression());
146        _button.addActionListener(new ButtonListener());
147
148        if (_container == null) {
149            System.out.println("Container is null");
150
151            // place the button in its own frame.
152            _frame = new JFrame(getFullName());
153            _frame.getContentPane().add(_button);
154        } else {
155            _container.add(_button);
156
157            //_button.setBackground(Color.red);
158        }
159    }
160
161    /** Reset the state of the actor and return whatever the superclass
162     *  returns.
163     *  @exception IllegalActionException If there is no director.
164     */
165    @Override
166    public boolean postfire() throws IllegalActionException {
167        if (_buttonPressed) {
168            _buttonPressed = false;
169        }
170
171        return super.postfire();
172    }
173
174    /** Set the background color.
175     *  @param background The background color.
176     *  @see #getBackground()
177     */
178    public void setBackground(Color background) {
179        _button.setBackground(background);
180    }
181
182    /** Override the base class to remove the display from its graphical
183     *  container if the argument is null.
184     *  @param container The proposed container.
185     *  @exception IllegalActionException If the base class throws it.
186     *  @exception NameDuplicationException If the base class throws it.
187     */
188    @Override
189    public void setContainer(CompositeEntity container)
190            throws IllegalActionException, NameDuplicationException {
191        super.setContainer(container);
192
193        if (container == null) {
194            _remove();
195        }
196    }
197
198    ///////////////////////////////////////////////////////////////////
199    ////                         private methods                   ////
200
201    /** Remove the display from the current container, if there is one.
202     */
203    private void _remove() {
204        SwingUtilities.invokeLater(new Runnable() {
205            @Override
206            public void run() {
207                if (_button != null) {
208                    if (_container != null) {
209                        _container.remove(_button);
210                        _container.invalidate();
211                        _container.repaint();
212                    } else if (_frame != null) {
213                        _frame.dispose();
214                    }
215                }
216            }
217        });
218    }
219
220    ///////////////////////////////////////////////////////////////////
221    ////                         private members                   ////
222    // The button.
223    private JButton _button;
224
225    // A flag indicating whether the button has been pressed in the current
226    // iteration
227    private boolean _buttonPressed;
228
229    // The container of the JButton.
230    private Container _container;
231
232    // The frame into which to put the text widget, if any.
233    private JFrame _frame;
234
235    private EventButton _self;
236
237    ///////////////////////////////////////////////////////////////////
238    ////                         inner classes                     ////
239    class ButtonListener implements ActionListener {
240        @Override
241        public void actionPerformed(ActionEvent event) {
242            try {
243                _buttonPressed = true;
244                getDirector().fireAtCurrentTime(_self);
245            } catch (IllegalActionException ex) {
246                // Should never happen
247                throw new InternalErrorException(ex.getMessage());
248            }
249        }
250    }
251}