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 }