FileDocCategorySizeDatePackage
ChatRoom.javaAPI DocExample6145Tue Dec 25 20:04:08 GMT 2001None

ChatRoom

public class ChatRoom extends Applet
Simple Chat Room Applet. Writing a Chat Room seems to be one of many obligatory rites (or wrongs) of passage for Java experts these days.

This one is a toy because it doesn't much of a command protocol, which means we can't query the server as to * who's logged in, or anything fancy like that. However, it works OK for small groups.

Uses client socket w/ two Threads (main and one constructed), one for reading and one for writing.

Server multiplexes messages back to all clients.

TODO in V2: use Java's MultiCastSocket, if it works OK on '95.

author
Ian Darwin, ian@darwinsys.com
version
$Id: ChatRoom.java,v 1.5 2001/12/26 01:04:09 ian Exp $

Fields Summary
protected boolean
inAnApplet
Whether we are being run as an Applet or an Application
protected boolean
loggedIn
The state of logged-in-ness
protected Frame
cp
protected static int
PORTNUM
The default port number
protected int
port
The actual port number
protected Socket
sock
The network socket
protected BufferedReader
is
BufferedReader for reading from socket
protected PrintWriter
pw
PrintWriter for sending lines on socket
protected TextField
tf
TextField for input
protected TextArea
ta
TextArea to display conversations
protected Button
lib
The Login button
protected Button
lob
The LogOUT button
static final String
TITLE
The TitleBar title
protected String
paintMessage
The message that we paint
protected String
serverHost
Constructors Summary
Methods Summary
public voidinit()
Init, inherited from Applet


	     
	   
		paintMessage = "Creating Window for Chat";
		repaint();
		cp = new Frame(TITLE);
		cp.setLayout(new BorderLayout());
		String portNum = null;
		if (inAnApplet)
			portNum = getParameter("port");
		port = PORTNUM;
		if (portNum != null)
			port = Integer.parseInt(portNum);

		// The GUI
		ta = new TextArea(14, 80);
		ta.setEditable(false);		// readonly
		ta.setFont(new Font("Monospaced", Font.PLAIN, 11));
		cp.add(BorderLayout.NORTH, ta);

		Panel p = new Panel();
		Button b;

		// The login button
		p.add(lib = new Button("Login"));
		lib.setEnabled(true);
		lib.requestFocus();
		lib.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				login();
				lib.setEnabled(false);
				lob.setEnabled(true);
				tf.requestFocus();	// set keyboard focus in right place!
			}
		});

		// The logout button
		p.add(lob = new Button("Logout"));
		lob.setEnabled(false);
		lob.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				logout();
				lib.setEnabled(true);
				lob.setEnabled(false);
				lib.requestFocus();
			}
		});

		p.add(new Label("Message here:"));
		tf = new TextField(40);
		tf.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (loggedIn) {
					pw.println(Chat.CMD_BCAST+tf.getText());
					tf.setText(""); 
				}
			}
		});
		p.add(tf);

		cp.add(BorderLayout.SOUTH, p);

        cp.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				// If we do setVisible and dispose, then the Close completes
				ChatRoom.this.cp.setVisible(false);
				ChatRoom.this.cp.dispose();
				logout();
			}
		});
		cp.pack();
		// After packing the Frame, centre it on the screen.
		Dimension us = cp.getSize(), 
			them = Toolkit.getDefaultToolkit().getScreenSize();
		int newX = (them.width - us.width) / 2;
		int newY = (them.height- us.height)/ 2;
		cp.setLocation(newX, newY);
		cp.setVisible(true);
		paintMessage = "Window should now be visible";
		repaint();
	
public voidlogin()
LOG ME IN TO THE CHAT


	       
	   
		showStatus("In login!");
		if (loggedIn)
			return;
		if (inAnApplet)
			serverHost = getCodeBase().getHost();
		try {
			sock = new Socket(serverHost, port);
			is = new BufferedReader(new InputStreamReader(sock.getInputStream()));
			pw = new PrintWriter(sock.getOutputStream(), true);
		} catch(IOException e) {
			showStatus("Can't get socket to " + 
				serverHost + "/" + port + ": " + e);
			cp.add(new Label("Can't get socket: " + e));
			return;
		}
		showStatus("Got socket");

		// Construct and start the reader: from server to textarea.
		// Make a Thread to avoid lockups.
		new Thread(new Runnable() {
			public void run() {
				String line;
				try {
					while (loggedIn && ((line = is.readLine()) != null))
						ta.append(line + "\n");
				} catch(IOException e) {
					showStatus("GAA! LOST THE LINK!!");
					return;
				}
			}
		}).start();

		// FAKE LOGIN FOR NOW
		pw.println(Chat.CMD_LOGIN + "AppletUser");
		loggedIn = true;
	
public voidlogout()
Log me out, Scotty, there's no intelligent life here!

		if (!loggedIn)
			return;
		loggedIn = false;
		try {
			if (sock != null)
				sock.close();
		} catch (IOException ign) {
			// so what?
		}
	
public static voidmain(java.lang.String[] args)
A main method to allow the client to be run as an Application

		ChatRoom room101 = new ChatRoom();
		room101.inAnApplet = false;
		room101.init();
		room101.start();
	
public voidpaint(java.awt.Graphics g)
Paint paints the small window that appears in the HTML, telling the user to look elsewhere!

		Dimension d = getSize();
		int h = d.height;
		int w = d.width;
		g.fillRect(0, 0, w, 0);
		g.setColor(Color.black);
		g.drawString(paintMessage, 10, (h/2)-5);
	
public voidshowStatus(java.lang.String mesg)
a showStatus that works for Applets or non-Applets alike

		if (inAnApplet)
			super.showStatus(mesg);
		System.out.println(mesg);