public class ClientGUI extends JFrame
1: // Fig. 24.28: ClientGUI.java
2: // ClientGUI provides a user interface for sending and receiving
3: // messages to and from the DeitelMessengerServer.
4: package com.deitel.messenger;
5:
6: import java.awt.BorderLayout;
7: import java.awt.event.ActionEvent;
8: import java.awt.event.ActionListener;
9: import java.awt.event.WindowAdapter;
10: import java.awt.event.WindowEvent;
11: import javax.swing.Box;
12: import javax.swing.BoxLayout;
13: import javax.swing.Icon;
14: import javax.swing.ImageIcon;
15: import javax.swing.JButton;
16: import javax.swing.JFrame;
17: import javax.swing.JLabel;
18: import javax.swing.JMenu;
19: import javax.swing.JMenuBar;
20: import javax.swing.JMenuItem;
21: import javax.swing.JOptionPane;
22: import javax.swing.JPanel;
23: import javax.swing.JScrollPane;
24: import javax.swing.JTextArea;
25: import javax.swing.SwingUtilities;
26: import javax.swing.border.BevelBorder;
27:
28: public class ClientGUI extends JFrame
29: {
30: private JMenu serverMenu; // for connecting/disconnecting server
31: private JTextArea messageArea; // displays messages
32: private JTextArea inputArea; // inputs messages
33: private JButton connectButton; // button for connecting
34: private JMenuItem connectMenuItem; // menu item for connecting
35: private JButton disconnectButton; // button for disconnecting
36: private JMenuItem disconnectMenuItem; // menu item for disconnecting
37: private JButton sendButton; // sends messages
38: private JLabel statusBar; // label for connection status
39: private String userName; // userName to add to outgoing messages
40: private MessageManager messageManager; // communicates with server
41: private MessageListener messageListener; // receives incoming messages
42:
43: // ClientGUI constructor
44: public ClientGUI( MessageManager manager )
45: {
46: super( "Deitel Messenger" );
47:
48: messageManager = manager; // set the MessageManager
49:
50: // create MyMessageListener for receiving messages
51: messageListener = new MyMessageListener();
52:
53: serverMenu = new JMenu ( "Server" ); // create Server JMenu
54: serverMenu.setMnemonic( 'S' ); // set mnemonic for server menu
55: JMenuBar menuBar = new JMenuBar(); // create JMenuBar
56: menuBar.add( serverMenu ); // add server menu to menu bar
57: setJMenuBar( menuBar ); // add JMenuBar to application
58:
59: // create ImageIcon for connect buttons
60: Icon connectIcon = new ImageIcon(
61: getClass().getResource( "images/Connect.gif" ) );
62:
63: // create connectButton and connectMenuItem
64: connectButton = new JButton( "Connect", connectIcon );
65: connectMenuItem = new JMenuItem( "Connect", connectIcon );
66: connectMenuItem.setMnemonic( 'C' );
67:
68: // create ConnectListener for connect buttons
69: ActionListener connectListener = new ConnectListener();
70: connectButton.addActionListener( connectListener );
71: connectMenuItem.addActionListener( connectListener );
72:
73: // create ImageIcon for disconnect buttons
74: Icon disconnectIcon = new ImageIcon(
75: getClass().getResource( "images/Disconnect.gif" ) );
76:
77: // create disconnectButton and disconnectMenuItem
78: disconnectButton = new JButton( "Disconnect", disconnectIcon );
79: disconnectMenuItem = new JMenuItem( "Disconnect", disconnectIcon );
80: disconnectMenuItem.setMnemonic( 'D' );
81:
82: // disable disconnect button and menu item
83: disconnectButton.setEnabled( false );
84: disconnectMenuItem.setEnabled( false );
85:
86: // create DisconnectListener for disconnect buttons
87: ActionListener disconnectListener = new DisconnectListener();
88: disconnectButton.addActionListener( disconnectListener );
89: disconnectMenuItem.addActionListener( disconnectListener );
90:
91: // add connect and disconnect JMenuItems to fileMenu
92: serverMenu.add( connectMenuItem );
93: serverMenu.add( disconnectMenuItem );
94:
95: // add connect and disconnect JButtons to buttonPanel
96: JPanel buttonPanel = new JPanel();
97: buttonPanel.add( connectButton );
98: buttonPanel.add( disconnectButton );
99:
100: messageArea = new JTextArea(); // displays messages
101: messageArea.setEditable( false ); // disable editing
102: messageArea.setWrapStyleWord( true ); // set wrap style to word
103: messageArea.setLineWrap( true ); // enable line wrapping
104:
105: // put messageArea in JScrollPane to enable scrolling
106: JPanel messagePanel = new JPanel();
107: messagePanel.setLayout( new BorderLayout( 10, 10 ) );
108: messagePanel.add( new JScrollPane( messageArea ),
109: BorderLayout.CENTER );
110:
111: inputArea = new JTextArea( 4, 20 ); // for entering new messages
112: inputArea.setWrapStyleWord( true ); // set wrap style to word
113: inputArea.setLineWrap( true ); // enable line wrapping
114: inputArea.setEditable( false ); // disable editing
115:
116: // create Icon for sendButton
117: Icon sendIcon = new ImageIcon(
118: getClass().getResource( "images/Send.gif" ) );
119:
120: sendButton = new JButton( "Send", sendIcon ); // create send button
121: sendButton.setEnabled( false ); // disable send button
122: sendButton.addActionListener(
123: new ActionListener()
124: {
125: // send new message when user activates sendButton
126: public void actionPerformed( ActionEvent event )
127: {
128: messageManager.sendMessage( userName,
129: inputArea.getText() ); // send message
130: inputArea.setText( "" ); // clear inputArea
131: } // end method actionPerformed
132: } // end anonymous inner class
133: ); // end call to addActionListener
134:
135: Box box = new Box( BoxLayout.X_AXIS ); // create new box for layout
136: box.add( new JScrollPane( inputArea ) ); // add input area to box
137: box.add( sendButton ); // add send button to box
138: messagePanel.add( box, BorderLayout.SOUTH ); // add box to panel
139:
140: // create JLabel for statusBar with a recessed border
141: statusBar = new JLabel( "Not Connected" );
142: statusBar.setBorder( new BevelBorder( BevelBorder.LOWERED ) );
143:
144: add( buttonPanel, BorderLayout.NORTH ); // add button panel
145: add( messagePanel, BorderLayout.CENTER ); // add message panel
146: add( statusBar, BorderLayout.SOUTH ); // add status bar
147:
148: // add WindowListener to disconnect when user quits
149: addWindowListener (
150: new WindowAdapter ()
151: {
152: // disconnect from server and exit application
153: public void windowClosing ( WindowEvent event )
154: {
155: messageManager.disconnect( messageListener );
156: System.exit( 0 );
157: } // end method windowClosing
158: } // end anonymous inner class
159: ); // end call to addWindowListener
160: } // end ClientGUI constructor
161:
162: // ConnectListener listens for user requests to connect to server
163: private class ConnectListener implements ActionListener
164: {
165: // connect to server and enable/disable GUI components
166: public void actionPerformed( ActionEvent event )
167: {
168: // connect to server and route messages to messageListener
169: messageManager.connect( messageListener );
170:
171: // prompt for userName
172: userName = JOptionPane.showInputDialog(
173: ClientGUI.this, "Enter user name:" );
174:
175: messageArea.setText( "" ); // clear messageArea
176: connectButton.setEnabled( false ); // disable connect
177: connectMenuItem.setEnabled( false ); // disable connect
178: disconnectButton.setEnabled( true ); // enable disconnect
179: disconnectMenuItem.setEnabled( true ); // enable disconnect
180: sendButton.setEnabled( true ); // enable send button
181: inputArea.setEditable( true ); // enable editing for input area
182: inputArea.requestFocus(); // set focus to input area
183: statusBar.setText( "Connected: " + userName ); // set text
184: } // end method actionPerformed
185: } // end ConnectListener inner class
186:
187: // DisconnectListener listens for user requests to disconnect
188: // from DeitelMessengerServer
189: private class DisconnectListener implements ActionListener
190: {
191: // disconnect from server and enable/disable GUI components
192: public void actionPerformed( ActionEvent event )
193: {
194: // disconnect from server and stop routing messages
195: messageManager.disconnect( messageListener );
196: sendButton.setEnabled( false ); // disable send button
197: disconnectButton.setEnabled( false ); // disable disconnect
198: disconnectMenuItem.setEnabled( false ); // disable disconnect
199: inputArea.setEditable( false ); // disable editing
200: connectButton.setEnabled( true ); // enable connect
201: connectMenuItem.setEnabled( true ); // enable connect
202: statusBar.setText( "Not Connected" ); // set status bar text
203: } // end method actionPerformed
204: } // end DisconnectListener inner class
205:
206: // MyMessageListener listens for new messages from MessageManager and
207: // displays messages in messageArea using MessageDisplayer.
208: private class MyMessageListener implements MessageListener
209: {
210: // when received, display new messages in messageArea
211: public void messageReceived( String from, String message )
212: {
213: // append message using MessageDisplayer
214: SwingUtilities.invokeLater(
215: new MessageDisplayer( from, message ) );
216: } // end method messageReceived
217: } // end MyMessageListener inner class
218:
219: // Displays new message by appending message to JTextArea. Should
220: // be executed only in Event thread; modifies live Swing component
221: private class MessageDisplayer implements Runnable
222: {
223: private String fromUser; // user from which message came
224: private String messageBody; // body of message
225:
226: // MessageDisplayer constructor
227: public MessageDisplayer( String from, String body )
228: {
229: fromUser = from; // store originating user
230: messageBody = body; // store message body
231: } // end MessageDisplayer constructor
232:
233: // display new message in messageArea
234: public void run()
235: {
236: // append new message
237: messageArea.append( "\n" + fromUser + "> " + messageBody );
238: } // end method run
239: } // end MessageDisplayer inner class
240: } // end class ClientGUI
241:
242:
243: /**************************************************************************
244: * (C) Copyright 1992-2005 by Deitel & Associates, Inc. and *
245: * Pearson Education, Inc. All Rights Reserved. *
246: * *
247: * DISCLAIMER: The authors and publisher of this book have used their *
248: * best efforts in preparing the book. These efforts include the *
249: * development, research, and testing of the theories and programs *
250: * to determine their effectiveness. The authors and publisher make *
251: * no warranty of any kind, expressed or implied, with regard to these *
252: * programs or to the documentation contained in these books. The authors *
253: * and publisher shall not be liable in any event for incidental or *
254: * consequential damages in connection with, or arising out of, the *
255: * furnishing, performance, or use of these programs. *
256: *************************************************************************/