001    /*
002     * SpiroControl.java
003     *
004     * Created on December 5, 2002, 12:02 PM
005     */
006    
007    package spirograph;
008    
009    import java.awt.Frame;
010    import java.util.Vector;
011    import javax.swing.JTabbedPane;
012    import java.awt.event.WindowEvent;
013    import javax.swing.event.ChangeEvent;
014    
015    /** This is a replacement class for the current main class of the
016     * Etch-a-sketch (aka apirograph). This implementation intends
017     * to ensure that the entire application fits on a single screen,
018     * and operates with a clean, intuitive interface. By the time this
019     * problem set is fully reworked it should implement a MVC architecture.
020     *
021     * <p>Copyright © 2002-2003 Franklin W. Olin College of Engineering.</p>
022     *
023     * @author Patrick G. Heck, gus.heck@olin.edu
024     * @version $Id: EtchControl.java,v 1.7 2003/01/15 18:26:50 gus Exp $
025     */
026    public class EtchControl extends javax.swing.JFrame {
027        
028        private static String xArg;
029        private static String yArg;
030        private static Thread xSpirit;
031        private static Thread ySpirit;
032        private static Accelerator xAccel;
033        private static Accelerator yAccel;
034        private static AccelHandler xHandler;
035        private static AccelHandler yHandler;
036        private static Coord xCoord = new Coord();
037        private static Coord yCoord = new Coord();
038        
039        
040        private boolean ready2Go = false;
041        private boolean xStarted, yStarted;
042        private boolean running = false;
043    
044        private DotFrame myFrame;
045        
046        // our initial recipies
047        private Recipie vert = new Recipie();
048        private Recipie horz = new Recipie();
049        
050        // these are our code mergers that do the work of translating studen
051        // input into useable code at the click of a button 
052        private CodeMerger vMerger = new CodeMerger("Vertical",
053                                                    vert,yHandler,xHandler);
054        private CodeMerger hMerger = new CodeMerger("Horizontal",
055                                                    horz,xHandler, yHandler);
056        
057    
058        // These are for notifying any listening EtchControlListeners
059        private Vector listeners = new Vector();
060        private ChangeEvent ce = new ChangeEvent(this);
061    
062        
063        /** Creates new form SpiroControl. There should only ever be a single 
064         *  <code>EtchControl</code> an thus this constructor is private.
065         */
066        private EtchControl() {
067            
068            initComponents();
069            
070            recipieViewVert.setRecipie(vert);
071            addEtchControlListener(recipieViewVert);
072            
073            // Set the title on the tab to match the recipie's id num
074            ((JTabbedPane) recipieViewVert.getParent()).setTitleAt(
075             ((JTabbedPane) recipieViewVert.getParent()).
076                indexOfComponent(recipieViewVert), 
077             "Recipie " + recipieViewVert.getRecipieNum());
078    
079            recipieViewHorz.setRecipie(horz);
080            addEtchControlListener(recipieViewHorz);
081            
082            // Set the title on the tab to match the recipie's id num
083            ((JTabbedPane) recipieViewHorz.getParent()).setTitleAt(
084             ((JTabbedPane) recipieViewHorz.getParent()).
085                indexOfComponent(recipieViewHorz), 
086             "Recipie " + recipieViewHorz.getRecipieNum());
087            
088            updateListeners();
089            ready2Go = true;
090            recipieTabsStateChanged(ce);
091            
092            myFrame = new DotFrame(xCoord, yCoord);
093    
094        }
095        
096        /** This method is called from within the constructor to
097         * initialize the form.
098         * WARNING: Do NOT modify this code. The content of this method is
099         * always regenerated by the Form Editor.
100         */
101        private void initComponents() {//GEN-BEGIN:initComponents
102            java.awt.GridBagConstraints gridBagConstraints;
103    
104            titleLabelPanel = new javax.swing.JPanel();
105            titleLabel = new javax.swing.JLabel();
106            centerPanel = new javax.swing.JPanel();
107            recipieTabs = new javax.swing.JTabbedPane();
108            recipieViewVert = new spirograph.RecipieView();
109            recipieViewHorz = new spirograph.RecipieView();
110            ControlButtonPanel = new javax.swing.JPanel();
111            startButton = new javax.swing.JButton();
112            stopButton = new javax.swing.JButton();
113            resetButton = new javax.swing.JButton();
114            newRecipieButton = new javax.swing.JButton();
115            menuBar = new javax.swing.JMenuBar();
116            fileMenu = new javax.swing.JMenu();
117            newRecipie = new javax.swing.JMenuItem();
118            advOptionsMenuItem = new javax.swing.JMenuItem();
119            jSeparator1 = new javax.swing.JSeparator();
120            exitMenuItem = new javax.swing.JMenuItem();
121            recipieMenu = new javax.swing.JMenu();
122            useVertCheckBoxMenuItem = new javax.swing.JCheckBoxMenuItem();
123            useHorzCheckBoxMenuItem = new javax.swing.JCheckBoxMenuItem();
124            jSeparator2 = new javax.swing.JSeparator();
125            compileRecipieMenuItem = new javax.swing.JMenuItem();
126            compileBothRecipieMenuItem = new javax.swing.JMenuItem();
127            standaloneRecipieMenuItem = new javax.swing.JMenuItem();
128    
129            setTitle("Etch-a-Sketch");
130            addWindowListener(new java.awt.event.WindowAdapter() {
131                public void windowClosing(java.awt.event.WindowEvent evt) {
132                    exitForm(evt);
133                }
134            });
135    
136            titleLabelPanel.setMinimumSize(new java.awt.Dimension(0, 0));
137            titleLabelPanel.setPreferredSize(new java.awt.Dimension(100, 25));
138            titleLabel.setFont(new java.awt.Font("Dialog", 1, 18));
139            titleLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
140            titleLabel.setText("Etch-a-Sketch Controls");
141            titleLabelPanel.add(titleLabel);
142    
143            getContentPane().add(titleLabelPanel, java.awt.BorderLayout.NORTH);
144    
145            centerPanel.setLayout(new java.awt.GridBagLayout());
146    
147            centerPanel.setPreferredSize(new java.awt.Dimension(801, 350));
148            recipieTabs.addChangeListener(new javax.swing.event.ChangeListener() {
149                public void stateChanged(javax.swing.event.ChangeEvent evt) {
150                    recipieTabsStateChanged(evt);
151                }
152            });
153    
154            recipieViewVert.setBorder(null);
155            recipieTabs.addTab("tab4", recipieViewVert);
156    
157            recipieTabs.addTab("tab5", recipieViewHorz);
158    
159            gridBagConstraints = new java.awt.GridBagConstraints();
160            gridBagConstraints.gridx = 0;
161            gridBagConstraints.gridy = 1;
162            gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
163            gridBagConstraints.weightx = 1.0;
164            gridBagConstraints.weighty = 1.0;
165            centerPanel.add(recipieTabs, gridBagConstraints);
166    
167            getContentPane().add(centerPanel, java.awt.BorderLayout.CENTER);
168    
169            ControlButtonPanel.setLayout(new java.awt.GridLayout(2, 0));
170    
171            startButton.setText("Start");
172            startButton.addActionListener(new java.awt.event.ActionListener() {
173                public void actionPerformed(java.awt.event.ActionEvent evt) {
174                    startButtonActionPerformed(evt);
175                }
176            });
177    
178            ControlButtonPanel.add(startButton);
179    
180            stopButton.setText("Stop");
181            stopButton.addActionListener(new java.awt.event.ActionListener() {
182                public void actionPerformed(java.awt.event.ActionEvent evt) {
183                    stopButtonActionPerformed(evt);
184                }
185            });
186    
187            ControlButtonPanel.add(stopButton);
188    
189            resetButton.setText("Reset");
190            resetButton.addActionListener(new java.awt.event.ActionListener() {
191                public void actionPerformed(java.awt.event.ActionEvent evt) {
192                    resetButtonActionPerformed(evt);
193                }
194            });
195    
196            ControlButtonPanel.add(resetButton);
197    
198            newRecipieButton.setText("New Recipie");
199            newRecipieButton.setMargin(new java.awt.Insets(2, 8, 2, 8));
200            newRecipieButton.addActionListener(new java.awt.event.ActionListener() {
201                public void actionPerformed(java.awt.event.ActionEvent evt) {
202                    newRecipieButtonActionPerformed(evt);
203                }
204            });
205    
206            ControlButtonPanel.add(newRecipieButton);
207    
208            getContentPane().add(ControlButtonPanel, java.awt.BorderLayout.SOUTH);
209    
210            fileMenu.setText("File");
211            fileMenu.addActionListener(new java.awt.event.ActionListener() {
212                public void actionPerformed(java.awt.event.ActionEvent evt) {
213                    fileMenuActionPerformed(evt);
214                }
215            });
216    
217            newRecipie.setText("New Recipie");
218            newRecipie.setToolTipText("Create a new Etch-a-Sketch Recipie");
219            newRecipie.addActionListener(new java.awt.event.ActionListener() {
220                public void actionPerformed(java.awt.event.ActionEvent evt) {
221                    newRecipieActionPerformed(evt);
222                }
223            });
224    
225            fileMenu.add(newRecipie);
226            advOptionsMenuItem.setText("Advanced Options...");
227            advOptionsMenuItem.setToolTipText("Configure Advanced Etch-a-Sketch Options");
228            advOptionsMenuItem.addActionListener(new java.awt.event.ActionListener() {
229                public void actionPerformed(java.awt.event.ActionEvent evt) {
230                    advOptionsMenuItemActionPerformed(evt);
231                }
232            });
233    
234            fileMenu.add(advOptionsMenuItem);
235            fileMenu.add(jSeparator1);
236            exitMenuItem.setText("Exit");
237            exitMenuItem.setToolTipText("Exit the program");
238            exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
239                public void actionPerformed(java.awt.event.ActionEvent evt) {
240                    exitMenuItemActionPerformed(evt);
241                }
242            });
243    
244            fileMenu.add(exitMenuItem);
245            menuBar.add(fileMenu);
246            recipieMenu.setText("Recipie");
247            recipieMenu.addMenuListener(new javax.swing.event.MenuListener() {
248                public void menuSelected(javax.swing.event.MenuEvent evt) {
249                    recipieMenuMenuSelected(evt);
250                }
251                public void menuDeselected(javax.swing.event.MenuEvent evt) {
252                }
253                public void menuCanceled(javax.swing.event.MenuEvent evt) {
254                }
255            });
256    
257            useVertCheckBoxMenuItem.setText("Use for Vertical");
258            useVertCheckBoxMenuItem.setToolTipText("Use this rule to determine vertical position of the pen in the drawing window");
259            useVertCheckBoxMenuItem.addActionListener(new java.awt.event.ActionListener() {
260                public void actionPerformed(java.awt.event.ActionEvent evt) {
261                    useVertCheckBoxMenuItemActionPerformed(evt);
262                }
263            });
264    
265            recipieMenu.add(useVertCheckBoxMenuItem);
266            useHorzCheckBoxMenuItem.setText("Use for Horizontal");
267            useHorzCheckBoxMenuItem.setToolTipText("Use this rule to determine horizontal position of the pen in the drawing window");
268            useHorzCheckBoxMenuItem.addActionListener(new java.awt.event.ActionListener() {
269                public void actionPerformed(java.awt.event.ActionEvent evt) {
270                    useHorzCheckBoxMenuItemActionPerformed(evt);
271                }
272            });
273    
274            recipieMenu.add(useHorzCheckBoxMenuItem);
275            recipieMenu.add(jSeparator2);
276            compileRecipieMenuItem.setText("Compile");
277            compileRecipieMenuItem.setToolTipText("Compile and load the code in this recipie");
278            compileRecipieMenuItem.setEnabled(false);
279            compileRecipieMenuItem.addActionListener(new java.awt.event.ActionListener() {
280                public void actionPerformed(java.awt.event.ActionEvent evt) {
281                    compileRecipieMenuItemActionPerformed(evt);
282                }
283            });
284    
285            recipieMenu.add(compileRecipieMenuItem);
286            compileBothRecipieMenuItem.setText("Compile Both");
287            compileBothRecipieMenuItem.setToolTipText("Compile both vert and horz recipies");
288            compileBothRecipieMenuItem.addActionListener(new java.awt.event.ActionListener() {
289                public void actionPerformed(java.awt.event.ActionEvent evt) {
290                    compileBothRecipieMenuItemActionPerformed(evt);
291                }
292            });
293    
294            recipieMenu.add(compileBothRecipieMenuItem);
295            standaloneRecipieMenuItem.setText("Standalone View");
296            standaloneRecipieMenuItem.setToolTipText("View this recipie in it's own window");
297            standaloneRecipieMenuItem.addActionListener(new java.awt.event.ActionListener() {
298                public void actionPerformed(java.awt.event.ActionEvent evt) {
299                    standaloneRecipieMenuItemActionPerformed(evt);
300                }
301            });
302    
303            recipieMenu.add(standaloneRecipieMenuItem);
304            menuBar.add(recipieMenu);
305            setJMenuBar(menuBar);
306    
307            pack();
308            java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
309            setSize(new java.awt.Dimension(400, 500));
310            setLocation((screenSize.width-400)/2,(screenSize.height-500)/2);
311        }//GEN-END:initComponents
312    
313        private void compileBothRecipieMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_compileBothRecipieMenuItemActionPerformed
314            // Add your handling code here:
315            synchronized (vert) {
316                vMerger = new CodeMerger("Vertical",vert,yHandler,xHandler);
317                vMerger.actionPerformed(evt);
318                vert.setCompiled(true);
319            }
320            synchronized (horz) {
321                hMerger = new CodeMerger("Horizontal",horz,xHandler,yHandler);
322                hMerger.actionPerformed(evt);
323                horz.setCompiled(true);
324            }
325        }//GEN-LAST:event_compileBothRecipieMenuItemActionPerformed
326    
327        private void advOptionsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_advOptionsMenuItemActionPerformed
328            // Add your handling code here:
329            myFrame.showAdvEnv();
330        }//GEN-LAST:event_advOptionsMenuItemActionPerformed
331    
332        private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetButtonActionPerformed
333            // Add your handling code here:
334            myFrame.showResetMenu();
335        }//GEN-LAST:event_resetButtonActionPerformed
336    
337        private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startButtonActionPerformed
338            // Add your handling code here:
339            running = true;
340            if(xStarted) {
341                xSpirit.resume();
342            } else {
343                xSpirit.start();
344                xStarted = true;
345            }
346            if(yStarted) {
347                ySpirit.resume();
348            } else {
349                ySpirit.start();
350                yStarted = true;            
351            }
352            myFrame.beginPainting();
353    
354        }//GEN-LAST:event_startButtonActionPerformed
355    
356        private void standaloneRecipieMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_standaloneRecipieMenuItemActionPerformed
357            // Add your handling code here:
358            new SoloRecipie(((RecipieView)recipieTabs.getSelectedComponent()).
359                getRecipie(), this, recipieTabs.getTitleAt(
360                recipieTabs.getSelectedIndex())).show();
361            updateListeners();
362        }//GEN-LAST:event_standaloneRecipieMenuItemActionPerformed
363    
364        private void compileRecipieMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_compileRecipieMenuItemActionPerformed
365            // Add your handling code here:
366            Recipie currentRecipie = ((RecipieView)recipieTabs.
367                getSelectedComponent()).getRecipie();
368            synchronized (currentRecipie) {
369                if (isHorzRecipie(currentRecipie)) {
370                    hMerger = new CodeMerger("Horizontal",
371                                             currentRecipie,xHandler,yHandler);
372                    hMerger.actionPerformed(evt);
373                }
374                if (isVertRecipie(currentRecipie)) {
375                    vMerger = new CodeMerger("Vertical",
376                                             currentRecipie,yHandler,xHandler);
377                    vMerger.actionPerformed(evt);
378                }
379                ((RecipieView) recipieTabs.getSelectedComponent()).
380                    getRecipie().setCompiled(true);
381            }
382            compileRecipieMenuItem.setEnabled(false);
383        }//GEN-LAST:event_compileRecipieMenuItemActionPerformed
384    
385        private void recipieMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_recipieMenuMenuSelected
386            // Add your handling code here:
387            
388            // Turn on the compile menuItem if the selected recipie has been 
389            // compiled.
390            boolean needsCompiled = !((RecipieView) recipieTabs.
391                getSelectedComponent()).getRecipie().isCompiled();
392            compileRecipieMenuItem.setEnabled(needsCompiled && !running);
393            
394            // Turn on the compile both menuitem if either the vert or the horz
395            // recipies have not been compiled.
396            boolean eitherNeedCompile = !(vert.isCompiled() && horz.isCompiled());
397            compileBothRecipieMenuItem.setEnabled(eitherNeedCompile && !running);
398        }//GEN-LAST:event_recipieMenuMenuSelected
399    
400        private void newRecipieButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newRecipieButtonActionPerformed
401            // Add your handling code here:
402            newRecipieActionPerformed(evt);
403        }//GEN-LAST:event_newRecipieButtonActionPerformed
404    
405        private void newRecipieActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newRecipieActionPerformed
406            // Add your handling code here:
407            Recipie newRecipie = new Recipie();
408            RecipieView newView = new RecipieView();
409            newView.setRecipie(newRecipie);
410            addEtchControlListener(newView);
411            recipieTabs.add(newView);
412                    // Set the title on the tab to match the recipie's id num
413            ((JTabbedPane) newView.getParent()).setTitleAt(
414             ((JTabbedPane) newView.getParent()).indexOfComponent(newView), 
415             "Recipie " + newView.getRecipieNum());
416            updateListeners();
417        }//GEN-LAST:event_newRecipieActionPerformed
418    
419        private void useHorzCheckBoxMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useHorzCheckBoxMenuItemActionPerformed
420            // Add your handling code here:
421            if (useHorzCheckBoxMenuItem.getState() == true) {
422                horz = ((RecipieView)recipieTabs.getSelectedComponent()).
423                    getRecipie();
424            } else {
425                horz = Recipie.nullRecipie;
426            }
427            updateListeners();
428        }//GEN-LAST:event_useHorzCheckBoxMenuItemActionPerformed
429    
430        private void useVertCheckBoxMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useVertCheckBoxMenuItemActionPerformed
431            // Add your handling code here:
432            if (useVertCheckBoxMenuItem.getState() == true) {
433                vert = ((RecipieView)recipieTabs.getSelectedComponent()).
434                    getRecipie();
435            } else {
436                vert = Recipie.nullRecipie;
437            }
438            updateListeners();        
439        }//GEN-LAST:event_useVertCheckBoxMenuItemActionPerformed
440    
441        private void recipieTabsStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_recipieTabsStateChanged
442            // Add your handling code here:
443            if (!ready2Go) { return; }  // this keeps us from processing events 
444                                        // before the components in the tabs are 
445                                        // created and added.
446            
447            useHorzCheckBoxMenuItem.setState(isHorzRecipie(
448                ((RecipieView)recipieTabs.getSelectedComponent()).getRecipie())); 
449            useVertCheckBoxMenuItem.setState(isVertRecipie(
450                ((RecipieView)recipieTabs.getSelectedComponent()).getRecipie())); 
451            //useHorzCheckBoxMenuItem
452            updateListeners();
453        }//GEN-LAST:event_recipieTabsStateChanged
454    
455        private void stopButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_stopButtonActionPerformed
456            // Add your handling code here:
457            running = false;
458            this.xSpirit.suspend();
459            this.ySpirit.suspend();
460            myFrame.suspendPainting(); 
461        }//GEN-LAST:event_stopButtonActionPerformed
462    
463        private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
464            // Add your handling code here:
465            exitForm(new java.awt.event.WindowEvent(this,
466                                                    WindowEvent.WINDOW_CLOSING));
467        }//GEN-LAST:event_exitMenuItemActionPerformed
468    
469        private void fileMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileMenuActionPerformed
470            // Add your handling code here:
471        }//GEN-LAST:event_fileMenuActionPerformed
472        
473        /** Exit the Application */
474        private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
475            
476            myFrame.setVisible(false);
477            myFrame.dispose();
478            xSpirit.stop();
479            ySpirit.stop();
480            System.exit(0);
481        }//GEN-LAST:event_exitForm
482        
483        /**
484         * Test a recipie to see if it is currently being used for the vertical axis.
485         * Note that isHorzRecipie and isVertRecipie may both return true at the
486         * same time.
487         *
488         * @param r The recipie to test
489         * @return <code>true</code> if r is the vertical recipie, <code>false</code>
490         */    
491        public boolean isVertRecipie(Recipie r) {
492            return r.getIdNum() == vert.getIdNum();
493        }
494    
495        /**
496         * Test a recipie to see if it is currently being used for the Horizontal axis.
497         * Note that isHorzRecipie and isVertRecipie may both return true at the
498         * same time.
499         *
500         * @param r The recipie to test
501         * @return <code>true</code> if r is the horizontal recipie, <code>false</code>
502         */    
503        public boolean isHorzRecipie(Recipie r) {
504            return r.getIdNum() == horz.getIdNum();
505        }
506    
507        /** Regester a class that implements {@link EtchControlListener}. Listeners will
508         * be notified when Recipies are added or removed, or assigned to the vertical
509         * or horizontal rule positions.
510         * @param el The listnener to add.
511         */    
512        public void addEtchControlListener(EtchControlListener el) {
513            listeners.add(el);        
514        }
515        
516        /** Unregister an EtchControlListener.
517         * @param el The listner to unregister
518         */    
519        public void removeEtchControlListener(EtchControlListener el) {
520            listeners.remove(el);
521        }
522    
523        private void updateListeners() {
524            for (int i=0; i<listeners.size(); i++){
525                ((EtchControlListener) listeners.get(i)).etchControlUpdated(ce);
526            }
527        }
528    
529        
530        /** The main point of entry for Spirograph when using this interface.
531         * @param args the command line arguments
532         */
533        public static void main(String args[]) {
534            switch (args.length) {
535                case 0: xArg = null; yArg = null; break; 
536                case 1: xArg = args[0]; yArg = null; break; 
537                case 2: xArg = args[0]; yArg =  args[1]; break; 
538                default: System.out.println("Only  0, 1, or 2 arguments accpeted.");
539            }
540            
541            if ( xArg == null ) {
542                xAccel = new Dummy();
543            } else {
544                System.out.println ("Trying to get class: " + xArg);        
545                xAccel = SpiroUtils.createAccel(xArg);      
546            }
547            
548            if ( yArg == null )
549                yAccel = new Dummy();
550            else {
551                System.out.println ("Trying to get class: " + yArg);        
552                yAccel = SpiroUtils.createAccel(yArg);
553            }
554            
555            if ((xAccel == null)||(yAccel == null)) {
556                System.exit(0);
557            }
558            
559            
560            xHandler = new AccelHandler(xAccel, xCoord, yCoord);
561            yHandler = new AccelHandler(yAccel, yCoord, xCoord);
562            xSpirit = new Thread(xHandler);
563            ySpirit = new Thread(yHandler);
564    
565            new EtchControl().show();
566        }
567        
568    
569        // Variables declaration - do not modify//GEN-BEGIN:variables
570        private javax.swing.JLabel titleLabel;
571        private javax.swing.JPanel titleLabelPanel;
572        private javax.swing.JSeparator jSeparator2;
573        private spirograph.RecipieView recipieViewVert;
574        private javax.swing.JMenu fileMenu;
575        private javax.swing.JCheckBoxMenuItem useHorzCheckBoxMenuItem;
576        private javax.swing.JPanel ControlButtonPanel;
577        private javax.swing.JButton stopButton;
578        private javax.swing.JMenuItem exitMenuItem;
579        private javax.swing.JPanel centerPanel;
580        private javax.swing.JCheckBoxMenuItem useVertCheckBoxMenuItem;
581        private spirograph.RecipieView recipieViewHorz;
582        private javax.swing.JMenuItem newRecipie;
583        private javax.swing.JMenuItem advOptionsMenuItem;
584        private javax.swing.JButton startButton;
585        private javax.swing.JMenuBar menuBar;
586        private javax.swing.JSeparator jSeparator1;
587        private javax.swing.JButton newRecipieButton;
588        private javax.swing.JButton resetButton;
589        private javax.swing.JMenu recipieMenu;
590        private javax.swing.JTabbedPane recipieTabs;
591        private javax.swing.JMenuItem compileRecipieMenuItem;
592        private javax.swing.JMenuItem standaloneRecipieMenuItem;
593        private javax.swing.JMenuItem compileBothRecipieMenuItem;
594        // End of variables declaration//GEN-END:variables
595    
596        /*
597         * $Log: EtchControl.java,v $
598         * Revision 1.7  2003/01/15 18:26:50  gus
599         * accomodate the renamining of editRecipie to setRecipie in RecipieVeiw
600         *
601         * Revision 1.6  2003/01/15 17:27:07  gus
602         * Javadoc tweaks
603         *
604         * Revision 1.5  2003/01/14 22:50:04  gus
605         * Added javadocs
606         *
607         * Revision 1.4  2003/01/08 18:51:02  gus
608         * Added an item to the recipie menu that allows the user to compile both
609         * rules at once in response to bug 39. Also shortend some long lines
610         *
611         * Revision 1.3  2003/01/06 18:45:59  gus
612         * Prevent recompilation while code is running.
613         *
614         * Revision 1.2  2002/12/20 21:49:08  gus
615         * Connect the new GUI with the old backend.
616         *
617         * Revision 1.1  2002/12/19 18:55:51  gus
618         * A new GUI for editing and displaying the code to control the behavior of the ball.
619         *
620         */
621    }