001    /*
002     *  AdvEnv.java
003     *      Part of the Spirograph problem set.
004     *
005     * Developed for "Rethinking CS101", a project of Lynn Andrea Stein's AP Group.
006     * For more information, see <a href="http://www.ai.mit.edu/projects/cs101/">the
007     * CS101 homepage</a> or email <las@ai.mit.edu>.
008     *
009     * Copyright (C) 1998 Massachusetts Institute of Technology.
010     * Please do not redistribute without obtaining permission.
011     */
012    
013    package spirograph;
014    
015    import java.awt.*;
016    import java.awt.event.*;
017    
018    /**
019     * This class  creates the window that appears when the user clicks on
020     * the Advanced Environment Options button. It has several Checkboxes
021     * and a method to add listeners to those buttons.
022     *
023     * <p>Copyright © 1998 Massachusetts Institute of Technology.<br />
024     * Copyright © 2003 Franklin W. Olin College of Engineering.</p>
025     *
026     * @author Luis Sarmenta, lfgs@cag.lcs.mit.edu
027     * @author Henry Wong, henryw@mit.edu
028     * @author Patrick G. Heck, gus.heck@olin.edu
029     * @version $Id: AdvEnv.java,v 1.3 2004/02/09 20:55:03 gus Exp $
030     */
031    public class AdvEnv extends Frame {
032      private Checkbox circularMode = new Checkbox("Circular");
033    
034      // This container holds the Textareas, the button and the labels
035      // that are used to set the velocity.
036      private Panel velCont = new Panel();
037      private Button setVel = new Button("Set velocity");
038      private DotPanel myPanel;
039      private Checkbox bounceMode = new Checkbox("Bouncing");
040      private Checkbox wrapMode = new Checkbox("Wraparound");
041    
042      /** Constructs the Advanced Environment Features menu with a default
043       * font.
044       *
045       * @param thePanel The <code>DotPanel</code> to which the advanced options apply
046       * @param xVel A <code>TextField</code> from which to get the velocity in
047       *             the x direction
048       * @param yVel A <code>TextField</code> from which to get the velocity in
049       *             the y direction
050       */
051      public AdvEnv(TextField xVel, TextField yVel, DotPanel thePanel) {
052            
053        this(xVel, yVel, thePanel, Spirograph.DEFAULTFONT);
054      }
055    
056      /** Specifies rules for switching the DotPanel to a circular mode,
057       * switching the border behavior between wraparound and bounce,
058       * setting position, velocity, and acceleration, and for closing the
059       * window.
060       *
061       * @see DotPanel
062       * @param xVel A <code>TextField</code> from which to get the velocity in
063       *             the x direction
064       * @param yVel A <code>TextField</code> from which to get the velocity in
065       *             the y direction
066       * @param thePanel The <code>DotPanel</code> to which the advanced options apply
067       * @param f A custom font for the panel
068       */
069      public AdvEnv(TextField xVel, TextField yVel, DotPanel thePanel, Font f) {
070            
071        myPanel = thePanel;
072            
073        this.setFont(f);
074        this.setTitle("Advanced Environment Features.");
075    
076        // border behavior modes
077        circularMode.addItemListener(new ItemListener() {       
078          public void itemStateChanged (ItemEvent ie) {
079            if (ie.getStateChange() == ItemEvent.SELECTED) {
080              if (myPanel.inEllipse()) {
081                myPanel.setCirc(true);
082                bounceMode.setState(true);
083                wrapMode.setState(false);
084              } else {
085                System.out.println ("You can't change to circular" +
086                                    " mode if the ball would be" +
087                                    " outside the circle.");
088                circularMode.setState(false);
089              }
090            } else {
091              myPanel.setCirc(false);
092            }
093          }
094        });
095    
096        bounceMode.addItemListener(new ItemListener() {
097          public void itemStateChanged(ItemEvent ie) {
098            if(ie.getStateChange() == 1) {
099              if(!myPanel.getWrap()) {
100                myPanel.setBounce(true);
101              } else {
102                System.out.println("You can't turn bouncing on while wraparound is on.");
103                bounceMode.setState(false);
104              }
105            } else {
106              myPanel.setBounce(false);
107            }
108          }
109        });
110        wrapMode.addItemListener(new ItemListener() {
111          public void itemStateChanged(ItemEvent ie) {
112            if(ie.getStateChange() == 1) {
113              if(!myPanel.getBounce() && !myPanel.getCirc()) {
114                myPanel.setWrap(true);
115              } else {
116                System.out.println("Wraparound cannot be used with bouncing or circular mode.");
117                wrapMode.setState(false);
118              }
119            } else {
120              myPanel.setWrap(false);
121            }
122          }
123        });
124    
125        // position/vel/accel mode
126        CheckboxGroup modeGroup = new CheckboxGroup();
127        Checkbox posMode = new Checkbox("Position control.", modeGroup, true);
128        posMode.addItemListener(new ItemListener() {
129          public void itemStateChanged(ItemEvent ie) {
130            myPanel.setMode(AccelHandler.POSMODE);
131          }
132        });
133        Checkbox velMode = new Checkbox("Velocity control.", modeGroup, false);
134        velMode.addItemListener(new ItemListener() {
135          public void itemStateChanged(ItemEvent ie) {
136            myPanel.setMode(AccelHandler.VELMODE);
137          }
138        });
139        Checkbox accelMode = new Checkbox("Acceleration control.", modeGroup, false);
140        accelMode.addItemListener(new ItemListener() {
141          public void itemStateChanged(ItemEvent ie) {
142            myPanel.setMode(AccelHandler.ACCELMODE);
143          }
144        });
145    
146        // Set up the velocity setting container
147        velCont.setLayout(new FlowLayout(FlowLayout.LEFT)); 
148        velCont.add (new Label ("X vel:"));
149        velCont.add (xVel);
150        velCont.add (new Label ("Y vel:"));
151        velCont.add (yVel);
152        velCont.add (setVel);
153    
154        Button close = new Button ("Close this window");
155        // Window disappears when the close Button is pushed
156        close.addActionListener(new ActionListener() {
157          public void actionPerformed(ActionEvent ae) {
158            AdvEnv.this.setVisible(false);
159          }
160        });
161            
162        // The settings are implemented in a new Panel
163        this.setLayout(new BorderLayout(2, 2));
164        Panel top1 = new Panel();
165        top1.setLayout(new GridLayout(3, 2));
166        top1.add(circularMode);
167        top1.add(posMode);
168        top1.add(bounceMode);
169        top1.add(velMode);
170        top1.add(wrapMode);
171        top1.add(accelMode);
172        this.add("North", top1);
173        this.add("Center", velCont);
174        this.add("South", close);
175        this.pack();
176      }
177    
178      /** Add an actionListener to the setVel button
179       * @param velSetter A listener that wants to know when the setVel button is pressed.
180       */  
181      public void addListener(ActionListener velSetter) {
182        setVel.addActionListener(velSetter);
183      }
184    }
185    
186    /*
187     * $Log: AdvEnv.java,v $
188     * Revision 1.3  2004/02/09 20:55:03  gus
189     * javadoc fixes
190     *
191     * Revision 1.2  2003/01/10 22:17:18  gus
192     * Complete the javadocs and clean up arguments for constructors
193     *
194     */