001    /*
002     * RecipieView.java
003     *
004     * Created on December 9, 2002, 4:47 PM
005     */
006    
007    package spirograph;
008    
009    import spirograph.Recipie;
010    
011    import java.awt.Color;
012    import java.awt.Insets;
013    import java.awt.GridLayout;
014    import java.awt.BorderLayout;
015    import java.awt.GridBagLayout;
016    import java.awt.GridBagConstraints;
017    
018    import java.awt.event.KeyEvent;
019    import java.awt.event.FocusEvent;
020    import java.awt.event.KeyAdapter;
021    import java.awt.event.ActionEvent;
022    import java.awt.event.FocusAdapter;
023    import java.awt.event.ActionListener;
024    
025    import javax.swing.JPanel;
026    import javax.swing.JLabel;
027    import javax.swing.JButton;
028    import javax.swing.JTextArea;
029    import javax.swing.JCheckBox;
030    import javax.swing.JScrollPane;
031    import javax.swing.JTabbedPane;
032    import javax.swing.JToggleButton;
033    
034    import javax.swing.border.BevelBorder;
035    import javax.swing.border.EmptyBorder;
036    
037    
038    /**
039     * This component displays the text of a {@link Recipie}, and it's usage status.
040     * It registers as a {@link RecipieListener} and a {@link EtchControlListener}
041     * to actively monitor and react to changes in the <code>Recipie</code> fields or
042     * in the assignment of the displayed <code>Recipie</code> to the vertical or
043     * horizontal axes.
044     *
045     * <p>Copyright © 2003 Franklin W. Olin College of Engineering.</p>
046     *
047     * @author Patrick G. Heck, gus.heck@olin.edu
048     * @version $Id: RecipieView.java,v 1.6 2004/02/09 20:55:03 gus Exp $
049     */
050    public class RecipieView extends javax.swing.JPanel implements RecipieListener, EtchControlListener{
051        
052        private JTextArea statementTextArea;
053        private JPanel fieldPanel;
054        private JPanel hvCheckPanel;
055        private JPanel statementPanel;
056        private JTextArea fieldTextArea;
057        private JScrollPane fieldScrollPane;
058        private JLabel statementLabel;
059        private JLabel fieldLabel;
060        private JPanel recipieButtonPanel;
061        private JPanel recipieControlPanel;
062        private JScrollPane statementScrollPane;
063        private JToggleButton fieldsToggleButton;
064        private JLabel statusHeaderLabel;
065        private JLabel statusLabel;
066        
067        private Recipie theRecipie = Recipie.nullRecipie;
068        // End of variables declaration
069    
070        /** Creates a new instance of <code>RecipieView</code>. The new instance will
071         * view {@link Recipie#nullRecipie} until a new <code>Recipie</code> is set.
072         * This makes it safe to add this component and initialize it at a later time.
073         * Without this feature, there is a danger of of a a call to
074         * {@link RecipieView#recipieUpdated} throwing a
075         * <code>NullPointerException</code> before the <code>Recipie</code> is set.
076         */
077        public RecipieView() {
078            initComponents();
079            setBorder(new javax.swing.border.EtchedBorder());
080        }
081        
082        private void initComponents() {
083            GridBagConstraints gridBagConstraints;
084    
085            fieldPanel = new JPanel();
086            fieldPanel.setVisible(false);
087            fieldLabel = new JLabel();
088            fieldScrollPane = new JScrollPane();
089            fieldTextArea = new JTextArea();
090            statementPanel = new JPanel();
091            statementLabel = new JLabel();
092            statementScrollPane = new JScrollPane();
093            statementTextArea = new JTextArea();
094            recipieControlPanel = new JPanel();
095            recipieButtonPanel = new JPanel();
096            fieldsToggleButton = new JToggleButton();
097            hvCheckPanel = new JPanel();
098            statusHeaderLabel = new JLabel();
099            statusLabel = new JLabel();
100    
101            setLayout(new GridBagLayout());
102    
103            fieldPanel.setLayout(new BorderLayout());
104    
105            fieldLabel.setText("Enter your Recipie Fields Here");
106            fieldLabel.setBorder(new EmptyBorder(new Insets(1, 1, 5, 1)));
107            fieldPanel.add(fieldLabel, BorderLayout.NORTH);
108    
109            fieldTextArea.setColumns(30);
110            fieldTextArea.setRows(4);
111            fieldTextArea.setBorder(new BevelBorder(BevelBorder.LOWERED));
112            fieldTextArea.addKeyListener( new KeyAdapter() {
113                public void keyReleased(KeyEvent ke) {
114                    fieldTextAreaKeyReleased(ke);
115                }
116            });
117    
118            fieldScrollPane.setViewportView(fieldTextArea);
119    
120            fieldPanel.add(fieldScrollPane, BorderLayout.CENTER);
121    
122            gridBagConstraints = new GridBagConstraints();
123            gridBagConstraints.gridx = 0;
124            gridBagConstraints.gridy = 0;
125            gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
126            add(fieldPanel, gridBagConstraints);
127    
128            statementPanel.setLayout(new BorderLayout());
129    
130            statementLabel.setText("Enter a Recipie Below");
131            statementLabel.setBorder(new EmptyBorder(new Insets(10, 1, 5, 1)));
132            statementPanel.add(statementLabel, BorderLayout.NORTH);
133    
134            statementTextArea.setColumns(30);
135            statementTextArea.setRows(8);
136            statementTextArea.setBorder(new BevelBorder(BevelBorder.LOWERED));
137            statementTextArea.addKeyListener( new KeyAdapter() {
138                public void keyReleased(KeyEvent ke) {
139                    statementTextAreaKeyReleased(ke);
140                }
141            });
142            statementScrollPane.setViewportView(statementTextArea);
143    
144            statementPanel.add(statementScrollPane, BorderLayout.CENTER);
145    
146            gridBagConstraints = new GridBagConstraints();
147            gridBagConstraints.gridx = 0;
148            gridBagConstraints.gridy = 1;
149            gridBagConstraints.fill = GridBagConstraints.BOTH;
150            gridBagConstraints.weightx = 1.0;
151            gridBagConstraints.weighty = 1.0;
152            add(statementPanel, gridBagConstraints);
153    
154            recipieControlPanel.setLayout(new GridBagLayout());
155    
156            recipieButtonPanel.setLayout(new GridBagLayout());
157    
158            fieldsToggleButton.setText("Add Fields");
159            fieldsToggleButton.setToolTipText("Click to hide or unhide the" + 
160                " fields box");
161            fieldsToggleButton.addActionListener(new ActionListener() {
162                public void actionPerformed(ActionEvent evt) {
163                    fieldsToggleButtonActionPerfomred(evt);
164                }
165            });
166            
167            gridBagConstraints = new GridBagConstraints();
168            gridBagConstraints.gridx = 0;
169            gridBagConstraints.gridy = 0;
170            gridBagConstraints.fill = GridBagConstraints.NONE;
171            gridBagConstraints.anchor = GridBagConstraints.CENTER;
172            recipieButtonPanel.add(fieldsToggleButton, gridBagConstraints);
173    
174    
175            gridBagConstraints = new GridBagConstraints();
176            gridBagConstraints.gridx = 0;
177            gridBagConstraints.gridy = 0;
178            gridBagConstraints.weightx = 1.0;
179            gridBagConstraints.weighty = 1.0;
180            gridBagConstraints.fill = GridBagConstraints.BOTH;
181            gridBagConstraints.anchor = GridBagConstraints.CENTER;
182            recipieControlPanel.add(recipieButtonPanel, gridBagConstraints);
183    
184            hvCheckPanel.setLayout(new GridBagLayout());
185    
186            statusHeaderLabel.setText("This recipe used for");
187    
188            gridBagConstraints = new GridBagConstraints();
189            gridBagConstraints.gridx = 1;
190            gridBagConstraints.gridy = 0;
191            gridBagConstraints.anchor = GridBagConstraints.WEST;
192            gridBagConstraints.weightx = 2.0;
193            hvCheckPanel.add(statusHeaderLabel, gridBagConstraints);
194    
195            statusLabel.setText("None");
196            statusLabel.setFont(new java.awt.Font("Dialog", 1, 16));
197            statusLabel.setForeground(Color.red);
198    
199            gridBagConstraints = new GridBagConstraints();
200            gridBagConstraints.gridx = 1;
201            gridBagConstraints.gridy = 1;
202            gridBagConstraints.anchor = GridBagConstraints.CENTER;
203            gridBagConstraints.weightx = 1.0;
204            hvCheckPanel.add(statusLabel, gridBagConstraints);
205    
206            gridBagConstraints = new GridBagConstraints();
207            gridBagConstraints.weightx = 1.0;
208            gridBagConstraints.weighty = 1.0;
209            recipieControlPanel.add(hvCheckPanel, gridBagConstraints);
210    
211            gridBagConstraints = new GridBagConstraints();
212            gridBagConstraints.gridx = 0;
213            gridBagConstraints.gridy = 4;
214            gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
215            gridBagConstraints.insets = new Insets(10, 0, 0, 0);
216            gridBagConstraints.weightx = 1.0;
217            add(recipieControlPanel, gridBagConstraints);
218    
219    
220        }
221    
222        private void fieldTextAreaKeyReleased(KeyEvent ke) {
223            theRecipie.setFields(fieldTextArea.getText());
224        }
225    
226        private void statementTextAreaKeyReleased(KeyEvent ke) {
227            theRecipie.setCode(statementTextArea.getText());
228        }
229        
230        private void fieldsToggleButtonActionPerfomred(ActionEvent evt) {
231            fieldPanel.setVisible(!fieldPanel.isVisible());
232        }
233        
234        // no javadoc - inherits from EtchControlListener
235        public void etchControlUpdated(javax.swing.event.ChangeEvent ce) {
236            boolean isVert = ((EtchControl)ce.getSource()).isVertRecipie(theRecipie);
237            boolean isHorz = ((EtchControl)ce.getSource()).isHorzRecipie(theRecipie);
238            if (isVert && isHorz) {
239                statusLabel.setText("Both");
240                statusLabel.setForeground(Color.blue);
241                if (getParent() instanceof JTabbedPane) {
242                    ((JTabbedPane) getParent()).setForegroundAt(
243                    ((JTabbedPane) getParent()).indexOfComponent(this), 
244                    Color.blue);
245                    
246                    ((JTabbedPane) getParent()).setToolTipTextAt(
247                    ((JTabbedPane) getParent()).indexOfComponent(this), 
248                    "The recipie currently used for both vertical and horizontal positioning of the pen");
249                    
250                }
251            }
252            if (isVert && !isHorz) {
253                statusLabel.setText("Vertical");
254                statusLabel.setForeground(new Color(0,128,0));
255                if (getParent() instanceof JTabbedPane) {
256                    ((JTabbedPane) getParent()).setForegroundAt(
257                    ((JTabbedPane) getParent()).indexOfComponent(this), 
258                    new Color(0,128,0));
259                    ((JTabbedPane) getParent()).setToolTipTextAt(
260                    ((JTabbedPane) getParent()).indexOfComponent(this), 
261                    "The recipie currently used for vertical positioning of the pen");
262    
263                }
264            }
265            if (!isVert && isHorz) {
266                statusLabel.setText("Horizontal");
267                statusLabel.setForeground(Color.magenta);
268                if (getParent() instanceof JTabbedPane) {
269                    ((JTabbedPane) getParent()).setForegroundAt(
270                    ((JTabbedPane) getParent()).indexOfComponent(this), 
271                    Color.magenta);
272                    ((JTabbedPane) getParent()).setToolTipTextAt(
273                    ((JTabbedPane) getParent()).indexOfComponent(this), 
274                    "The recipie currently used for horizontal positioning of the pen");
275                }
276            }
277            if (!isVert && !isHorz) {
278                statusLabel.setText("None");
279                statusLabel.setForeground(Color.red);
280                if (getParent() instanceof JTabbedPane) {
281                    ((JTabbedPane) getParent()).setForegroundAt(
282                    ((JTabbedPane) getParent()).indexOfComponent(this), 
283                    Color.black);
284                    ((JTabbedPane) getParent()).setToolTipTextAt(
285                    ((JTabbedPane) getParent()).indexOfComponent(this), 
286                    "A recipie not currently in use");
287                }
288            }
289                
290        }
291    
292        // no javadoc - inherits from RecipieListener
293        public void recipieUpdated(javax.swing.event.ChangeEvent ce) {
294            int caretPos = statementTextArea.getCaretPosition();
295            statementTextArea.setText(((Recipie) ce.getSource()).getCode());
296            statementTextArea.setCaretPosition(caretPos);
297            caretPos = fieldTextArea.getCaretPosition();
298            fieldTextArea.setText(((Recipie) ce.getSource()).getFields());
299            fieldTextArea.setCaretPosition(caretPos);
300        }
301        
302        /**
303         * Set the {@link Recipie} for this view to display.
304         *
305         * @param r The <code>Recipie</code> to View
306         */    
307        public void setRecipie(Recipie r) {
308            theRecipie = r;
309            r.addRecipieListener(this);
310        }
311        
312        /**
313         * Get a reference to the {@link Recipie} object currently displayed by this view.
314         *
315         * @return The <code>Recipie</code> being viewed.
316         */    
317        public Recipie getRecipie() {
318            return theRecipie;
319        }
320    
321        /** Identify the {@link Recipie} being displayed.
322         * @return The unique identifier for the <code>Recipie</code> being displayed.
323         */    
324        public int getRecipieNum() {
325            return theRecipie.getIdNum();
326        }
327        
328      
329        /*
330         * $Log: RecipieView.java,v $
331         * Revision 1.6  2004/02/09 20:55:03  gus
332         * javadoc fixes
333         *
334         * Revision 1.5  2003/01/15 18:48:10  gus
335         * finished Javadoc and removed unused method
336         *
337         * Revision 1.4  2003/01/15 18:25:59  gus
338         * Some javadoc added, and editRecipie changed to more standard name of
339         * setRecipie.
340         *
341         * Revision 1.3  2003/01/15 16:15:45  gus
342         * accomodate changes in the Recipie class
343         *
344         * Revision 1.2  2002/12/20 21:49:08  gus
345         * Connect the new GUI with the old backend.
346         *
347         * Revision 1.1  2002/12/19 18:55:51  gus
348         * A new GUI for editing and displaying the code to control the behavior of the ball.
349         *
350         */
351    }