|
GUILoginConsole |
|
1 // joi/10/juno/GUILoginConsole.java 2 // 3 // 4 // Copyright 2003 Bill Campbell and Ethan Bolker 5 6 import javax.swing.*; 7 import javax.swing.event.*; 8 import java.awt.*; 9 import java.awt.event.*; 10 11 /** 12 * The graphical user interface to Juno. 13 */ 14 15 public class GUILoginConsole extends JFrame 16 implements OutputInterface 17 { 18 private static final int FIELDWIDTH = 30; 19 private static final int FIELDHEIGHT = 5; 20 21 private final Juno junoSystem; 22 private WindowCloser closeMe; // to shut down Juno 23 24 private String title; // title for the windows 25 26 // The interpreter interprets one-line commands. 27 private InterpreterInterface interpreter; 28 private boolean echoInput; 29 30 // All output goes to messages. 31 private JTextArea messages; 32 33 /** 34 * Construct a GUI console for Juno. 35 * 36 * @param title the title for this window. 37 * @param junoSystem the Juno system for which this is a GUI 38 * @param interpreter the object to which to send user input. 39 * @param echoInput true when input echoes to this console. 40 */ 41 42 public GUILoginConsole( String title, Juno junoSystem, 43 InterpreterInterface interpreter, 44 boolean echoInput) 45 { 46 super( title ); 47 this.title = title; 48 this.junoSystem = junoSystem; 49 this.interpreter = interpreter; 50 this.echoInput = echoInput; 51 this.closeMe = new WindowCloser( junoSystem ); 52 53 // Set up the look and feel; 54 // Everthing is placed on a panel (using BorderLayout) 55 56 JPanel panel = new JPanel(); 57 panel.setLayout( new BorderLayout() ); 58 59 // First a tabbed pane, with two tabs: 60 // one for login, one for registration 61 62 JTabbedPane tabs = new JTabbedPane(); 63 tabs.addTab( "Login" , null, 64 new LoginPane( interpreter, echoInput, closeMe ) ); 65 tabs.addTab( "Register", null, 66 new RegisterPane( interpreter, echoInput ) ); 67 tabs.setSelectedIndex( 0 ); // Login selected by default 68 panel.add( tabs, BorderLayout.NORTH ); 69 70 // and the output messages area. 71 panel.add( new JLabel( "Messages:" ), BorderLayout.CENTER ); 72 messages = new JTextArea( FIELDHEIGHT, FIELDWIDTH ); 73 panel.add( messages, BorderLayout.SOUTH ); 74 75 // Add the panel to this JFrame 76 this.getContentPane().add( panel ); 77 78 // Closing this window 79 this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 80 this.addWindowListener( closeMe ); 81 82 // Size and display this JFrame 83 pack(); 84 show(); 85 } 86 87 // Implementing the OutputInterface. Everything goes to the 88 // single message area. 89 90 /** 91 * Write a String followed by a newline 92 * to message area. 93 * 94 * @param str - the string to write 95 */ 96 97 public void println(String str ) 98 { 99 messages.append( str + "\n" ); 100 } 101 102 /** 103 * Write a String followed by a newline 104 * to message area. 105 * 106 * @param str - the String to write 107 */ 108 109 public void errPrintln(String str ) 110 { 111 println( str ); 112 } 113 114 /** 115 * Query what kind of console this is. 116 * 117 * @return true if and only if echoing input. 118 */ 119 120 public boolean isEchoInput() 121 { 122 return echoInput; 123 } 124 125 /** 126 * Query what kind of console this is. 127 * 128 * @return true if and only if GUI 129 */ 130 131 public boolean isGUI() 132 { 133 return true; 134 } 135 136 /** 137 * Query what kind of console this is. 138 * 139 * @return true if and only if remote 140 */ 141 142 public boolean isRemote() 143 { 144 return false; 145 } 146 147 // The Login pane is specified in a private inner class, 148 // visible only here. 149 150 private class LoginPane extends JPanel 151 { 152 // The login pane has two text fields and two buttons. 153 private JTextField nameField; 154 private JTextField passwordField; 155 156 private JButton ok; 157 private JButton exit; 158 159 private WindowCloser closeMe; // to shut down Juno 160 // Construct the login pane and set up its listeners. 161 162 public LoginPane( InterpreterInterface interpreter, 163 boolean echoInput, WindowCloser closeMe ) 164 { 165 super(); 166 this.closeMe = closeMe; 167 168 // Set up the look and feel. 169 // Everything will go into a vertical Box, a container 170 // whose contents are laid out using BoxLayout 171 172 Box box = Box.createVerticalBox(); 173 174 // First a panel, containing the two text fields 175 176 JPanel p = new JPanel(); 177 p.setLayout( new GridLayout( 4 , 1 ) ); 178 179 p.add( new JLabel( "Login:" ) ); 180 nameField = new JTextField( FIELDWIDTH ); 181 p.add( nameField ); 182 183 p.add( new JLabel( "Password:" ) ); 184 passwordField = new JPasswordField( FIELDWIDTH ); 185 p.add( passwordField ); 186 box.add( p ); 187 box.add( Box.createVerticalStrut( 15 ) ); 188 189 // Then a horizontal Box containing the two buttons 190 191 Box row = Box.createHorizontalBox(); 192 row.add( Box.createGlue() ); 193 194 ok = new JButton( "OK" ); 195 row.add( ok ); 196 row.add( Box.createGlue() ); 197 198 exit = new JButton( "Exit" ); 199 row.add( exit ); 200 row.add( Box.createGlue() ); 201 box.add( row ); 202 box.add( Box.createVerticalStrut( 15 ) ); 203 204 this.setLayout( new BorderLayout() ); 205 this.add( box, BorderLayout.CENTER ); 206 207 // Set up the listeners (the semantics) 208 209 ok.addActionListener( new LoginProcessor() ); 210 exit.addActionListener( closeMe ); // shuts down Juno 211 } 212 213 // An inner inner class for the semantics 214 // when the user clicks OK. 215 216 private class LoginProcessor implements ActionListener 217 { 218 public void actionPerformed(ActionEvent e) 219 { 220 String str = nameField.getText() + " " + 221 passwordField.getText(); 222 nameField.setText(""); 223 passwordField.setText(""); 224 messages.setText(str+'\n'); // for debugging 225 interpreter.interpret( str ); 226 } 227 } 228 } 229 230 // The Register pane is specified in a private inner class, 231 // visible only here. 232 233 private class RegisterPane extends JPanel 234 { 235 // The register pane has four textfields and two buttons. 236 private JTextField chosenName; 237 private JTextField fullName; 238 private JTextField password1; 239 private JTextField password2; 240 241 private JButton register; 242 private JButton clear; 243 244 public RegisterPane( InterpreterInterface interpreter, 245 boolean echoInput) 246 { 247 super(); 248 249 // Define the look and feel 250 // Everything goes into a vertical Box 251 Box box = Box.createVerticalBox(); 252 253 // First a panel containing the text fields 254 255 JPanel p = new JPanel(); 256 p.setLayout( new GridLayout( 0 , 1 ) ); 257 258 p.add( new JLabel( "Choose login name:" ) ); 259 chosenName = new JTextField( FIELDWIDTH ); 260 p.add( chosenName ); 261 262 p.add( new JLabel( "Give full name:" ) ); 263 fullName = new JTextField( FIELDWIDTH ); 264 p.add( fullName ); 265 266 p.add( new JLabel( "Choose password:" ) ); 267 password1 = new JPasswordField( FIELDWIDTH ); 268 p.add( password1 ); 269 270 p.add( new JLabel( "Retype password:" ) ); 271 password2 = new JPasswordField( FIELDWIDTH ); 272 p.add( password2 ); 273 274 box.add( p ); 275 box.add( Box.createVerticalStrut( 15 ) ); 276 277 // Then a horizontal Box containing the buttons 278 279 Box row = Box.createHorizontalBox(); 280 row.add( Box.createGlue() ); 281 register = new JButton( "Register" ); 282 row.add( register ); 283 row.add( Box.createGlue() ); 284 clear = new JButton( "Clear" ); 285 row.add( clear ); 286 row.add( Box.createGlue() ); 287 box.add( row ); 288 box.add( Box.createVerticalStrut( 15 ) ); 289 290 this.setLayout( new BorderLayout() ); 291 this.add( box, BorderLayout.CENTER ); 292 293 // Set up the listeners (the semantics) 294 295 register.addActionListener( new Registration() ); 296 clear.addActionListener( new Cleanser() ); 297 } 298 299 // An inner inner class for the semantics when the user 300 // clicks Register. 301 302 private class Registration implements ActionListener 303 { 304 public void actionPerformed(ActionEvent e) 305 { 306 if ( password1.getText().trim().equals( 307 password2.getText().trim() ) ) { 308 String str = "register " + 309 chosenName.getText() + " " + 310 password1.getText() + " " + 311 fullName.getText() ; 312 chosenName.setText(""); 313 fullName.setText(""); 314 messages.setText(str+'\n'); // for debugging 315 interpreter.interpret(str); 316 } 317 else { 318 messages.setText( 319 "Sorry, passwords don't match.\n" ); 320 } 321 password1.setText(""); 322 password2.setText(""); 323 } 324 } 325 326 // An inner inner class for the semantics when the user 327 // clicks Clear. 328 329 private class Cleanser implements ActionListener { 330 public void actionPerformed(ActionEvent e) { 331 chosenName.setText(""); 332 fullName.setText(""); 333 password1.setText(""); 334 password2.setText(""); 335 } 336 } 337 } 338 339 // A WindowCloser instance handles close events generated 340 // by the underlying window system with its windowClosing 341 // method, and close events from buttons or other user 342 // components with its actionPerformed method. 343 // 344 // The action is to shut down Juno. 345 346 private static class WindowCloser extends WindowAdapter 347 implements ActionListener 348 { 349 Juno system; 350 351 public WindowCloser( Juno system ) 352 { 353 this.system = system; 354 } 355 356 public void windowClosing (WindowEvent e) 357 { 358 this.actionPerformed( null ); 359 } 360 361 public void actionPerformed(ActionEvent e) 362 { 363 if (system != null) { 364 system.shutDown(); 365 } 366 System.exit(0); 367 } 368 } 369 370 /** 371 * main() in GUILoginConsole class for 372 * unit testing during development. 373 */ 374 375 public static void main( String[] args ) 376 { 377 new GUILoginConsole( "GUItest", null, null, true ).show(); 378 } 379 } 380 381
|
GUILoginConsole |
|