Chapter 2. Network Chat

Similar documents
CPSC 441 Tutorial TCP Server. Department of Computer Science University of Calgary

CONTENTS. Chapter 1 Getting Started with Java SE 6 1. Chapter 2 Exploring Variables, Data Types, Operators and Arrays 13

Lab 1 : Java Sockets

Virtualians.ning.pk. 2 - Java program code is compiled into form called 1. Machine code 2. native Code 3. Byte Code (From Lectuer # 2) 4.

Multimedia Programming

Week 13 Lab - Exploring Connections & Remote Execution

Java: Graphical User Interfaces (GUI)

CS 351 Design of Large Programs Sockets Example

Java Intro 3. Java Intro 3. Class Libraries and the Java API. Outline

Come & Join Us at VUSTUDENTS.net

Object-Oriented Software Engineering (Re-exam for Object-Oriented Analysis, Design and Programming)

Give one example where you might wish to use a three dimensional array

Hanley s Survival Guide for Visual Applications with NetBeans 2.0 Last Updated: 5/20/2015 TABLE OF CONTENTS

G51PGP Programming Paradigms. Lecture 009 Concurrency, exceptions

DHANALAKSHMI SRINIVASAN COLLEGE OF ENGINEERING AND TECHNOLOGY ACADEMIC YEAR (ODD SEM)

Event Driven Programming

THIS EXAMINATION PAPER MUST NOT BE REMOVED FROM THE EXAMINATION ROOM

CS 51 Laboratory # 12

SELF-STUDY. Glossary

ICOM 4015-Advanced Programming. Spring Instructor: Dr. Amir H. Chinaei. TAs: Hector Franqui, Jose Garcia, and Antonio Tapia. Reference: Big Java

Reading from URL. Intent - open URL get an input stream on the connection, and read from the input stream.

1 OBJECT-ORIENTED PROGRAMMING 1

Java Socket Application. Distributed Systems IT332

CS 251 Intermediate Programming GUIs: Event Listeners

Graphical User Interfaces (GUIs)

Java for Interfaces and Networks

Introduction to concurrency and GUIs

Graphical User Interface (GUI)

Pieter van den Hombergh Richard van den Ham. March 17, 2018

Multiple Choice Questions: Identify the choice that best completes the statement or answers the question. (15 marks)

Chapter 3: A Larger Example: SocketChat

Pace University. Fundamental Concepts of CS121 1

Java Input/Output. 11 April 2013 OSU CSE 1

Input from Files. Buffered Reader

Control Flow: Overview CSE3461. An Example of Sequential Control. Control Flow: Revisited. Control Flow Paradigms: Reacting to the User

CS506 Web Programming and Development Solved Subjective Questions With Reference For Final Term Lecture No 1

Interactive Programming In Java

Networking Code CSCI 201 Principles of Software Development

VALLIAMMAI ENGINEERING COLLEGE

COMP 213. Advanced Object-oriented Programming. Lecture 20. Network Programming

Jonathan Aldrich Charlie Garrod

Building a Java First-Person Shooter

Table of Contents. Chapter 1 Getting Started with Java SE 7 1. Chapter 2 Exploring Class Members in Java 15. iii. Introduction of Java SE 7...

Chapter 4: Processes

CS506 Web Design & Development Final Term Solved MCQs with Reference

School of Informatics, University of Edinburgh

Java s Implementation of Concurrency, and how to use it in our applications.

Graphical User Interface (GUI)

Java Support for developing TCP Network Based Programs

The JFrame Class Frame Windows GRAPHICAL USER INTERFACES. Five steps to displaying a frame: 1) Construct an object of the JFrame class

Course Status Networking GUI Wrap-up. CS Java. Introduction to Java. Andy Mroczkowski

Network Programming. Powered by Pentalog. by Vlad Costel Ungureanu for Learn Stuff

Supporting Materials

Part I: Learn Common Graphics Components

Quiz on Tuesday April 13. CS 361 Concurrent programming Drexel University Fall 2004 Lecture 4. Java facts and questions. Things to try in Java

B2.52-R3: INTRODUCTION TO OBJECT ORIENTATED PROGRAMMING THROUGH JAVA

protocols September 15,

Lesson 3: Accepting User Input and Using Different Methods for Output

B2.52-R3: INTRODUCTION TO OBJECT-ORIENTED PROGRAMMING THROUGH JAVA

Networking Basics. network communication.

Assignment 1. Due date February 6, 2007 at 11pm. It must be submitted using submit command.

Syllabus & Curriculum for Certificate Course in Java. CALL: , for Queries

Network. Dr. Jens Bennedsen, Aarhus University, School of Engineering Aarhus, Denmark

LTBP INDUSTRIAL TRAINING INSTITUTE

Principles, Models, and Applications for Distributed Systems M

DEMYSTIFYING PROGRAMMING: CHAPTER SIX METHODS (TOC DETAILED) CHAPTER SIX: METHODS 1

Graphical interfaces & event-driven programming

Tommy Färnqvist, IDA, Linköping University

CS 351 Design of Large Programs Threads and Concurrency

CS2307 NETWORKS LAB 1. Programs using TCP Sockets (like date and time server & client, echo server & client, etc.) 2. Programs using UDP Sockets

Input, Output and Exceptions. COMS W1007 Introduction to Computer Science. Christopher Conway 24 June 2003

Web Server Project. Tom Kelliher, CS points, due May 4, 2011

Java for Interfaces and Networks (DT3029)

Introduction to GUIs. Principles of Software Construction: Objects, Design, and Concurrency. Jonathan Aldrich and Charlie Garrod Fall 2014

IT101. Graphical User Interface

13 th Windsor Regional Secondary School Computer Programming Competition

M257 Past Paper Oct 2007 Attempted Solution

Advanced Java Programming. Networking

Asynchronous Communication using Messaging

Introduction This assignment will ask that you write a simple graphical user interface (GUI).

Swing: Building GUIs in Java

CSCI 136 Written Exam #1 Fundamentals of Computer Science II Spring 2013

CSCD 330 Network Programming Spring 2018

Java for Programmers Course (equivalent to SL 275) 36 Contact Hours

DOWNLOAD PDF CORE JAVA APTITUDE QUESTIONS AND ANSWERS

A Quick Tour p. 1 Getting Started p. 1 Variables p. 3 Comments in Code p. 6 Named Constants p. 6 Unicode Characters p. 8 Flow of Control p.

CSCD 330 Network Programming Spring 2018

Core Java Syllabus. Pre-requisite / Target Audience: C language skills (Good to Have)

Java Networking (sockets)

Java Programming. Price $ (inc GST)

Midterm assessment - MAKEUP Fall 2010

Internet Technology 2/7/2013

CSCD 330 Network Programming Winter 2019

Swing: Building GUIs in Java

CMSC 331 Second Midterm Exam

Simple Java Reference

Introduction... xv SECTION 1: DEVELOPING DESKTOP APPLICATIONS USING JAVA Chapter 1: Getting Started with Java... 1

Merge Sort Quicksort 9 Abstract Windowing Toolkit & Swing Abstract Windowing Toolkit (AWT) vs. Swing AWT GUI Components Layout Managers Swing GUI

String temp [] = {"a", "b", "c"}; where temp[] is String array.

Which of the following syntax used to attach an input stream to console?

Transcription:

Chapter 2. Network Chat In a multi-player game, different players interact with each other. One way of implementing this is to have a centralized server that interacts with each client using a separate socket. This chapter first presents the basics of secure SSL socket programming via naive client and server programs (Section 1), then extends the programs to command-line chat programs where both the client and the server are multi-threaded (Section 2), and finally extends to GUI chat programs (Section 3). 1 Naive Socket Example The code for this section appears in package jwg.ch2.naive. To test-run, first run ServerNaive, then run ClientNaive. Because the console window in MyEclipse only shows system output for the most recently executed program, to view output of both the server and the client you will need to run at least one of the programs using some command-line console outside MyEclipse. For instance, to run the server program, in a command-line console, cd to the jwg code directory, then type java jwg.ch2.naive.servernaive. This section illustrates the basics of socket programming via a naive client program and a server program. The programs follow the protocol as shown in Figure 1. CLIENT Connect to server. Write an integer (=7). Read an integer (=49). SERVER Create a server socket. Accept a client connection. Read an integer (=7). Write its square (=49). Figure 1: The protocol for the naive socket example. Figure 2 shows the naive client program. The client program first connects to a server on a given host and at a given port. In this example, the host is hard coded as localhost (i.e. on the same machine the client runs on), and the port number is hard coded as 6789. Here the port number must be between 1024 and 65535. This is because a port number less than 1024 can only be created by a superuser, and 65535 is the maximum number a 16 bit integer can represent. To connect to the server, Line 15 gets a default SSLSocketFactory, and then Line 16 creates an SSLSocket from the SSLSocketFactory. We suggest to use SSLSocket instead of Socket for security reason. Lines 17 and 18 instruct the client socket to use an anonymous cipher suite, so that a KeyManager or TrustManager is not needed. Lines 20-23 show how to create input and output streams from the socket. We suggest to use BufferedReader for input and PrintWriter for output, although these are not the only choices. We chose the variable name is to represent input stream, and the variable name os to represent output stream. Finally, Lines 26 and 27 illustrate how to write to the server and read from the server. In this program, the client writes an integer 7 to the server, then reads an integer (the square of 7) from the server and prints it out. 1

1. // Figure 2. ClientNaive.java: Naive socket client. 2. 3. package jwg.ch2.naive; 4. import java.io.*; 5. import javax.net.ssl.*; 6. 7. public class ClientNaive { 8. public static void main(string[] args) { 9. String hostname = "localhost"; 10. int port = 6789; 11. SSLSocket clientsocket = null; 12. 13. try { 14. // connect to the server and create a client socket 15. SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault(); 16. clientsocket = (SSLSocket)factory.createSocket(hostname, port); 17. final String[] enabledciphersuites = { "SSL DH anon WITH RC4 128 MD5" }; 18. clientsocket.setenabledciphersuites(enabledciphersuites); 19. 20. BufferedReader is = new BufferedReader( 21. new InputStreamReader(clientSocket.getInputStream())); 22. PrintWriter os = new PrintWriter(new OutputStreamWriter( 23. clientsocket.getoutputstream()), true); 24. 25. // write an integer to the server and receive an integer 26. os.println(7); 27. String line = is.readline(); 28. System.out.println("Server says the square of 7 is: " + line + "."); 29. 30. // clean up 31. os.close(); 32. is.close(); 33. clientsocket.close(); 34. } catch (IOException e) { 35. e.printstacktrace(); 36. } 37. } 38. } Figure 2: Naive socket client. Figure 3 shows the corresponding naive server program. Lines 15-19 create a server socket using parameters that match those used by the client. In particular, the port number and enabled cipher suites should be the same as those used by the client. Line 23 is a blocking call (serversocket.accept()) that waits for a client to connect. Lines 30-33 read from the client an integer and then write its square back to the client. Note that reading from the client (is.readline()) is also a blocking call. The client-server socket programs in this section are naive for several reasons. First, the server can only accept one client connection. Second, the protocol is sequential. In a chat program, the server should be able to establish sockets with multiple clients, and the protocol should be parallel. For instance, while a client is waiting for its user to input a message to broadcast to other clients (via the server), it should also be waiting for the server to send it messages from the other clients. Obviously, both a chat 2

1. // Figure 3. ServerNaive.java: Naive socket server. 2. 3. package jwg.ch2.naive; 4. import java.io.*; 5. import javax.net.ssl.*; 6. 7. public class ServerNaive { 8. public static void main(string args[]) { 9. SSLServerSocket serversocket = null; 10. SSLSocket clientsocket = null; 11. int port = 6789; 12. 13. try { 14. // create a server socket 15. SSLServerSocketFactory factory = (SSLServerSocketFactory) 16. SSLServerSocketFactory.getDefault(); 17. serversocket =(SSLServerSocket)factory.createServerSocket(port); 18. final String[] enabledciphersuites = { "SSL DH anon WITH RC4 128 MD5" }; 19. serversocket.setenabledciphersuites(enabledciphersuites); 20. System.out.println( "Server started, waiting for client..." ); 21. 22. // accept a client connection 23. clientsocket = (SSLSocket)serverSocket.accept(); 24. BufferedReader is = new BufferedReader( 25. new InputStreamReader(clientSocket.getInputStream())); 26. PrintWriter os = new PrintWriter(new OutputStreamWriter( 27. clientsocket.getoutputstream()), true); 28. 29. // read an integer from the client and write its square back 30. String line = is.readline(); 31. System.out.println( "Received " + line + " from client." ); 32. int n = Integer.parseInt(line); 33. os.println( n*n ); 34. 35. // clean up 36. is.close(); 37. os.close(); 38. clientsocket.close(); 39. serversocket.close(); 40. } catch (IOException e) { 41. e.printstacktrace(); 42. } 43. } 44. } Figure 3: Naive socket server. 3

server and a chat client should be multi-threaded. The next section presents a command-line solution to multi-threaded chat. 2 Command-Line Chat The code for this section appears in package jwg.ch2.chatcl. To test-run: first run the server (ServerChatCL), then run one or multiple copies of the client (ClientChatCL). Similar to the naive case, you should run these programs in separate command-line consoles outside MyEclipse. This section presents command-line chat programs. They use the basic operators learned from Section 1 (e.g. create SSL sockets, read from the socket and write to the socket), while addressing the limitations. Let s first examine the protocol in Figure 4 and see how it addresses the limitations of the naive socket protocol. CLIENT Connect to server. Create a ClientSideListener. Get a nickname from keyboard. Write the nickname. Get a message from keyboard. Write the message. SERVER Create a server socket. Create a ServerSidePlayerGroup. Accept a client connection. Create a ServerSideListener thread. SERVERSIDELISTENER Read a nickname. Create a ServerSidePlayer object, and add to ServerSidePlayerGroup. Broadcast a welcome message. Read a chat message. Broadcast the chat message. CLIENTSIDELISTENER Read a message. Display the message. Figure 4: The protocol for the command-line chat example. In a chat program, a client should have two separate threads to get user input (from keyboard in this section) and to read server messages from the socket. This is because both of these two operations are blocking calls. For instance, in the naive example (Figure 1), while the singlethreaded client is trying to read an integer (=49) from the socket, it sits there waiting for the server to send a message, and therefore cannot get user input. In the new protocol (Figure 4), the client creates a ClientSideListener thread which takes care of reading from the socket, thereby freeing up the client thread to get user input. In a chat program, the server should be able to establish socket connections with multiple clients. This was not done in the naive example (Figure 1). The new protocol (Figure 4) achieves this goal because the server creates a ServerSideListener thread for every client. A follow-up requirement is that in a chat program, the server should maintain information for all the connected clients (e.g. their client sockets and their nicknames). In the programs developed in this section, two more classes are created for this purpose: ServerSidePlayer and ServerSide- PlayerGroup. A ServerSidePlayer object keeps the information for one connected client. The ServerSidePlayerGroup object simply keeps an array of ServerSidePlayer objects. One might 4

wonder: why can t the server simply keep an array of ServerSidePlayer objects without introducing a new ServerSidePlayerGroup class? The answer is that with a wrapper class, operations to access the shared array of ServerSidePlayer objects can be easily synchronized. There are six programs in this section (package jwg.ch2.chatcl): ClientChatCL.java: the client program. ServerChatCL.java: the server program. ClientSideListenerChatCL.java: the client-side listener. ServerSideListenerChatCL.java: the server-side listener. ServerSidePlayerChatCL.java: the information of one client maintained at the server. ServerSidePlayerGroupChatCL.java: the group of client information. All the programs should be easy to understand. ClientChatCL.java, ServerChatCL.java, clientsidelistenerchatcl.java, and ServerSideListener.java closely follow the procedures as described in the corresponding boxes in Figure 4. ServerSidePlayerChatCL.java maintains some information for a client. And ServerSidePlayerGroupChatCL.java simply maintains an array of such client information. Let s examine the implementation of server broadcast to better understand the mechanism. As Figure 4 shows, ServerSideListener has a loop that keeps reading a chat message (from one client) and broadcasting it (to the other clients). Figure 5 shows excerpts of three functions (one in each java source file) that work together to implement server broadcast. ServerSideListenerChatCL.run() Here ServerSideListenerChatCL is a class extending Thread. When a thread executes, its run() function will automatically be called. Here the run() function includes an infinite while loop (Lines 7-10) which reads a chat message (String message=is.readline()) and broadcasts to the other clients (players.broadcast(nickname, message)). ServerSidePlayerGroupChatCL.Broadcast() The ServerSidePlayerGroupChatCL class maintains an ArrayList of ServerSidePlayerChatCL objects, one for each player (client). To broadcast a message from a client with a given nickname, the synchronized Broadcast function examines all these players and call player.send(message) for each player who is not the message source. Please note that if a Java object is visible to multiple threads, all read and write operations to the object should be done through synchronized methods. Java Virtual Machine ensures that (i) invocations to synchronized methods on the same object do not interleave; and (ii) the changes made by a synchronized method are visible to all the other threads. Also note the special syntax of for statement in Line 17. Such a for statement, which was introduced in Java 5, allows easier scanning for a collection. In general the syntax is: for (type item : collection) statement; ServerSidePlayerChatCL.Send() ServerSidePlayerChatCL.java maintains three variables for a client: a PrintWriter for writing to the server through socket, the nickname of the player, and the client socket. To send a message to the client, as Line 33 shows, it calls os.println(message), where os is the PrintWriter object. 5

1. // Figure 5. Excerpts of code implementing server broadcast in command-line chat. 2. 3. public class ServerSideListenerChatCL extends Thread { 4. private BufferedReader is; 5. private ServerSidePlayerGroupChatCL players; 6. public void run() { 7. while (true) { 8. String message = is.readline(); 9. players.broadcast(nickname, message); 10. } 11. } 12. } 13. 14. public class ServerSidePlayerGroupChatCL { 15. private ArrayList<ServerSidePlayerChatCL> players; 16. synchronized public void Broadcast( String nickname, String message ) { 17. for ( ServerSidePlayerChatCL player: players ) { 18. if (!player.match(nickname)) player.send(message); 19. } 20. } 21. } 22. 23. public class ServerSidePlayerChatCL { 24. private PrintWriter os; 25. public String nickname; 26. private Socket clientsocket; 27. 28. public boolean Match(String nickname) { 29. return nickname.equals(this.nickname); 30. } 31. 32. public void Send(String message) { 33. os.println(message); 34. } 35. } Figure 5: Excerpts of code implementing server broadcast in command-line chat. 6

3 GUI Chat The code for this section appears in package jwg.ch2.chatgui. To test-run: first run the server (ServerChatGUI), then run one or multiple copies of the client (ClientChatGUI). Unlike Sections 1 and 2, all these executions can be invoked from within MyEclipse. Since each instance creates a new window (JFrame for the server and JApplet for the client), their output do not interfere with each other. Also, because ClientChatGUI is a JApplet which does not have a main function, you cannot invoke it at command line as you did for the non GUI version. To invoke it at command line you need to run appletviewer. This section transforms the programs in the command-line chat section to include GUI interface. In particular, this section again has six java files, which have one-to-one mapping to the six java files in Section 2. But, there are two additional files: ClientChatGUI.form and ServerChatGUI.form. These are created using Matisse4MyEclipse. This software is included in the MyEclipse professional version. It provides drag-and-drop abilities when designing user interfaces (an ability that used to attract many users to NetBeans). Before studying this section, you should go through the Matisse4MyEclipse tutorial. In the MyEclipse IDE, 1. Select the menu item Help Welcome. 2. Click Tutorials. 3. Select Creating a Swing Application with Matisse4MyEclipse. After you go through the tutorial, you should know these concepts: Any GUI component created by Matisse4MyEclipse has two files: a.java file and a.form file. Open the.form file, and you can see, at the bottom of the window, a source tab and a design tab. Click the design tab to modify the GUI design. Click the source tab to view or modify the java source. You never need to open the.java file directly. In the generated source file, there are two parts you are not supposed to directly change whatsoever. These parts are enclosed within //GEN-BEGIN and //GEN-END. To indirectly change things in these parts, you modify in the GUI design mode. The GUI client is illustrated in Figure 6. The client JApplet has, at the bottom, a line of four components used for sending a message. Besides those, it has four JTabbedPane windows, with labels World, Char+Who+Option, Chat, and System Messages. Let s first explain the four controls at the bottom. The JComboBox with label All. This component tells to whom the message should be sent. The default value means to send to all players currently online. The other choices in the JComboBox are: Local meaning to send only to players in the current scene; Group meaning to send to those players who are in the same group; and Individual meaning to send to an individual recipient. In this sample code, this component is not actually used. 7

Figure 6: The GUI client. Figure 7: The GUI server. 8

The disabled JComboBox with label Select Recipient. This component should be enabled if Individual is selected in the first component. The intention is that the nickname of one individual recipient can then be selected here. In this sample code, this component is not used, either. The long and empty JTextField. The player can input a message here. The JButton with label Send. Clicking on this button will send the message. Let s now explain the four JTabbedPane windows. The JTabbedPane with label World. This is the main game canvas. The isometric graphics, play sprites, and so on, all should appear here. In this sample code, this panel is empty. The JTabbedPane with several panels labeled Char, Who, and Option. These panels are meant to show supplementary information. For instance, the Char panel should display the player s character data, such as level, life, experience, and so on. The Who panel should display the list of players that are online. The Option panel should allow the users to specify certain preferences, e.g. to block messages that are sent to All. In this sample code, this panel is empty, too. The JTabbedPane with label Chat. messages. This panel contains a JTextArea that displays the chat The JTabbedPane with label System Messages. This panel contains a JTextArea that displays the system messages. The GUI server is illustrated in Figure 7. This simple server GUI only has two pieces: A JTextArea on the top, which is an output console. A JTable at the bottom, which displays the list of clients that are currently connected. Out of the six java source files, only two are significantly different from their counterparts in the command-line chat. These are the client GUI (ClientChatGUI.java) and the server GUI (ServerChat- GUI.java). The rest of this section focuses on explaining the key points in ClientChatGUI.java, after which the server GUI source code should be easy to understand. Figure 8 shows excerpts from ClientChatGUI.java. Line 3 suppresses the warning message that the serializable class does not declare a static final serialversionuid field. Line 4 tells that class ClientChatGUI inherits from JApplet. Lines 5-17 are the init() function, which is automatically called when initializing this JApplet. The initialization code, however, is not directly put inside the init() function. Rather, it is wrapped by the EventQueue.invokeLater() function as follows: java.awt.eventqueue.invokelater(new Runnable() { public void run() { // initialization codes } }); 9

1. // Figure 8. ClientChatGUI.java: GUI Chat Client. 2. 3. @SuppressWarnings("serial") 4. public class ClientChatGUI extends javax.swing.japplet { 5. public void init() { 6. java.awt.eventqueue.invokelater(new Runnable() { 7. public void run() { 8. initcomponents(); 9. 10. (new java.util.timer()).schedule(new java.util.timertask() { 11. public void run() { 12. // omitted: connect to the server and create a client-side listener 13. } 14. }, 50); 15. } 16. }); 17. } 18. 19. private void sendandclear() { 20. String message = jtextfieldinput.gettext(); 21. jtextfieldinput.settext(""); 22. os.println(message); 23. } 24. 25. synchronized public void showchatmessage(string nickname, String message) { 26. jtextareaoutput.append("[[" + nickname + "]] " + message + "\n"); 27. if (jtextareaoutput.getdocument().getlength() > maxtextareaoutputlength) { 28. jtextareaoutput.replacerange("", 0, 200); 29. } 30. jtextareaoutput.setcaretposition(jtextareaoutput.getdocument().getlength()); 31. } 32. 33. private void jtextfieldinputkeytyped(java.awt.event.keyevent evt) { 34. if (evt.getkeychar() == \n ) sendandclear(); 35. } 36. 37. private void jbuttonsendactionperformed(java.awt.event.actionevent evt) { 38. sendandclear(); 39. } 40. 41. //GEN-BEGIN:initComponents 42. private void initcomponents() { // omitted } 43. //GEN-END:initComponents 44. 45. //GEN-BEGIN:variables 46. // omitted 47. //GEN-END: variables 48. } Figure 8: GUI Chat Client. 10

Here the invokelater() function takes as input a Runnable object, whose run() function will automatically be called. This method should be used whenever an application thread needs to update the GUI. Because all GUI updates go to the same AWT event queue, this wrapper ensures that the initialization code is executed asynchronously on the AWT event dispatching thread after all pending AWT events have been processed. Without this wrapper, programs with complex GUI might halt during execution. Let s now take a closer look at the initialization code. Line 8 calls the one function whose name is not determined by you or me but by Matisse4MyEclipse. The function is called initcomponents(). It initializes the GUI components. As illustrated later in Lines 41-43, the definition of the function is enclosed between //GEN-BEGIN and //GEN-END. When you use Matisse4MyEclipse to update the GUI interface and save, this function definition will automatically be updated. So be cautious not to directly modify the content of it, but to modify in the design mode. Lines 10-14 wrap the code to connect to server into Timer.schedule() function. This function has several forms. In the form that our code adopts, the first parameter is a TimerTask object whose run() function contains the connection code, and the second parameter is the delay in terms of milliseconds. For instance, the sample code says to try connect to the server in a separate thread after 50 milliseconds. This wrapping, by connecting to the server asynchronously, allows the GUI to immediately display even if it takes a long time to establish server connection. Lines 19-23 show how to get a message from the input JTextField, clear the JTextField, and then send the message to the server. Lines 25-31 are a synchronized function to display a message in the chat window. Here synchronization is needed because both the GUI part (when the user tries to send a message to the server, the message is echoed) and the ClientSideListener (when receiving a server message) will call this function to update the chat window. Lines 27-29 make sure the chat window does not display too much data (to prevent memory overflow). Whenever the JTextArea for displaying chat messages contains more than a certain number of characters, the oldest 200 characters will be erased. Line 30 sets the caret position to the end of the JTextArea. Even though no caret is shown because the JTextArea is not editable, this statement is still useful because it scrolls the window upwards upon displaying a new message. Lines 33-39 show two callback functions whose names can be set by you and me, but through Matisse4MyEclipse in the design mode. The name of the callback function jtextfieldinputkeytyped is set as follows. 1. In MyEclipse, open ClientSideGUI.form. This automatically goes to the design mode. 2. Click the input JTextField in the client GUI. 3. If the properties window is not visible, open it by selecting Windows Show View Properties. 4. In the properties window, there are four tabs: Properties, Binding, Events, and Code. Select the Events tab. 5. Scroll down to the keytyped event and provide the desired function name. This function ensures that when the user presses the ENTER key in the input JTextField, the function sendandclear is called. The name of the callback function jbuttonsendactionperformed is set similarly. This function ensures that when the user clicks on the Send button, again the function sendandclear is called. Therefore the user can send a message in two ways. Such flexibility provides slightly more friendly user interface. Finally, Lines 41-47 show the two parts that are generated by Matisse4MyEclipse: the initcomponents() function and the set of variables of the GUI components. 11