Internet Programming with Java Course

2.4.: chat

Creating Applet Client for NakovChatServer

/**

* Chat applet client for Nakov Chat Server.

* Author: Nikolay Nedyalkov, 2002

*

* ChatApplet class provides applet-based graphical user interface

* for the clients of NakovChatServer.

*/

import java.awt.*;

import java.awt.event.*;

import java.applet.*;

import java.util.Vector;

import java.util.Enumeration;

 

public class ChatApplet extends Applet implements ActionListener, MouseListener {

boolean isStandalone = false;

 

private ChatClient cl = new ChatClient (this);

private PopupMenu popupMenu1 = new PopupMenu ();

private MenuItem menuItem1 = new MenuItem ();

private MenuItem menuItem2 = new MenuItem ();

private Vector allUsers = new Vector ();

private Vector deniedUsers = new Vector ();

private boolean isConnected = false;

 

private TextField textField1 = new TextField();

private Button connectButton = new Button ();

private Button disconnectButton = new Button ();

private Button sendButton = new Button ();

private Button clearButton = new Button ();

private Button exitButton = new Button ();

 

public TextArea textArea1 = new TextArea();

public List list1 = new List();

 

public void setConnected(boolean aConnected) {

isConnected = aConnected;

}

 

public boolean getConnected() {

return isConnected;

}

 

/**

* Method is called from ChatClient to get reference to ChatApplet.textArea1.

* @return java.awt.TextArea

*/

public TextArea getTextArea () {

return textArea1;

}

 

/**

* Method is called from ChatClient to get reference to ChatApplet.list1.

* @return java.awt.List

*/

public List getList () {

return list1;

}

 

/**

* Method is called from ChatClient to register anUser in allUsers vector

* and list1 visual control.

* @param anUser - user to be included.

*/

public synchronized void addUser (String anUser) {

if (!allUsers.contains(anUser)) {

allUsers.addElement (anUser);

list1.add (anUser);

}

}

 

/**

* Method is called from ChatClient to append given message to the

* ChatApplet's TextArea. It also checks whether anUser is in our

* Ignore list and ignores the message in this case.

* @param anUser - user that have sent the message

* @param aText - message to be appened to the applet's TextArea

*/

public synchronized void addText (String aText, String anUser) {

if (!deniedUsers.contains(anUser)) {

textArea1.append (aText + "\n");

}

}

 

public synchronized void addSystemMessage(String aText) {

textArea1.append(aText + "\n");

}

 

/**

* Applet life cycle initiliazation.

*/

public void init() {

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

 

/**

* Component initialization.

* @throws Exception

*/

private void jbInit() throws Exception {

this.setLayout (null);

 

// -- Begin buttons section

sendButton.setLabel("Send");

sendButton.setBounds (new Rectangle(316, 245, 68, 23));

sendButton.addActionListener (this);

this.add(sendButton);

 

connectButton.setLabel("connect");

connectButton.setBounds(new Rectangle(34, 270, 95, 22));

connectButton.addActionListener(this);

this.add(connectButton, null);

 

disconnectButton.addActionListener(this);

disconnectButton.setBounds(new Rectangle(175, 270, 108, 22));

disconnectButton.setLabel("disconnect");

this.add(disconnectButton, null);

 

clearButton.setLabel("Clear");

clearButton.addActionListener(this);

clearButton.setBounds(new Rectangle(316, 270, 68, 23));

this.add(clearButton, null);

 

exitButton.setBackground(Color.gray);

exitButton.setForeground(Color.lightGray);

exitButton.setLabel("Q");

exitButton.setBounds(new Rectangle(388, 245, 32, 48));

exitButton.addActionListener(this);

this.add(exitButton, null);

// -- End buttons section

 

// -- Begin edit controls

textField1.setBounds(new Rectangle(10, 245, 303, 23));

textField1.addActionListener(this);

textField1.setBackground(Color.lightGray);

this.add(textField1, null);

 

textArea1.setBounds(new Rectangle(10, 10, 303, 233));

textArea1.setBackground(Color.lightGray);

this.add(textArea1, null);

// -- End edit controls

 

// -- Begin menus section

popupMenu1.setLabel("User menu");

menuItem1.setLabel("Ignore user");

menuItem1.setActionCommand ("BAN");

menuItem1.addActionListener (this);

menuItem2.setLabel("Deignore user");

menuItem2.setActionCommand ("UNBAN");

menuItem2.addActionListener (this);

popupMenu1.add(menuItem1);

popupMenu1.addSeparator();

popupMenu1.add(menuItem2);

// -- End menus section

 

list1.setBounds(new Rectangle(316, 11, 104, 233));

list1.add (popupMenu1);

list1.addActionListener (this);

list1.addMouseListener (this);

list1.setBackground(Color.lightGray);

this.add (popupMenu1);

this.add(list1, null);

 

this.setBackground(Color.cyan);

}

 

/**

* Method sends aMessage to server through ChatClient.

* @param aMessage

*/

public void sendMessage (String aMessage) {

cl.getOutput().println (aMessage);

cl.getOutput().flush();

}

 

/**

* Method handles ActionEvent event, registered by "this" Action listener.

* @param ae - ActionEvent which we used to indicate "sender".

*/

public void actionPerformed (ActionEvent ae) {

 

if (ae.getSource().equals(textField1)) {

// catch ActionEvents coming from textField1

sendButtonPressed();

} else if (ae.getSource().equals(connectButton)) {

// catch ActionEvents coming connect button from textField1

if (!isConnected) {

addSystemMessage("Connecting...");

isConnected = cl.connect();

} else {

addSystemMessage("Already connected.");

}

} else if (ae.getSource().equals(sendButton)) {

// catch ActionEvents coming send button from textField1

sendButtonPressed();

} else if (ae.getSource().equals(menuItem1)) {

// catch ActionEvents comming from popupMenu->menuItem1->"Ignore"

String selectedUser = list1.getSelectedItem();

deniedUsers.addElement (selectedUser);

addSystemMessage("User added to ban list.");

} else if (ae.getSource().equals(menuItem2)) {

// catch ActionEvents comming from popupMenu->menuItem1->"Deignore"

String selectedUser = list1.getSelectedItem();

if (!deniedUsers.removeElement (selectedUser))

addSystemMessage("No such user in ban list.");

else

addSystemMessage("User removed from ban list.");

} else if (ae.getSource().equals(clearButton)) {

// catch ActionEvents comming from clear button

textArea1.setText("");

} else if (ae.getSource().equals(disconnectButton)) {

// catch ActionEvents comming from disconnect button

cl.disconnect();

} else if (ae.getSource().equals(exitButton)) {

// catch ActionEvents comming from exit button

System.exit(0);

}

}

 

private void sendButtonPressed() {

if (!isConnected) {

textArea1.append("Please connect first.\n");

return;

}

String text = textField1.getText();

if (text.equals(""))

return;

sendMessage (text);

textField1.setText ("");

}

 

public void mouseClicked(MouseEvent e) {}

public void mouseReleased(MouseEvent e) {}

public void mouseEntered(MouseEvent e) {}

public void mouseExited(MouseEvent e) {}

 

/**

* Method handles mousePressed event, registered by "this" MouseListener.

* @param e MouseEvent

*/

public void mousePressed(MouseEvent e) {

// register when user pressed right mouse button

// - e.getModifiers()==e.BUTTON3_MASK -

// and when is "mouse down" - e.MOUSE_PRESSED==501.

if ((e.getModifiers()==e.BUTTON3_MASK)&&(e.MOUSE_PRESSED==501)) {

popupMenu1.show (list1, e.getX(), e.getY());

}

}

 

}

 
 

/**

* Chat applet client for Nakov Chat Server.

* Author: Nikolay Nedyalkov, 2002

*

* ChatClient class handles the communication with the chat server.

*/

import java.io.*;

import java.net.*;

import java.awt.*;

import java.awt.event.*;

import java.applet.*;

import java.util.Hashtable;

 

public class ChatClient

{

public static final int SERVER_PORT = 2002;

 

private Socket m_Socket = null;

private BufferedReader in = null;

private PrintWriter out = null;

private ChatApplet m_Applet;

 

/**

* Constructor initialize ChatClient and sets ChatApplet refferences.

*/

public ChatClient (ChatApplet anApplet) {

this.m_Applet = anApplet;

}

 

/**

* Method is called from ChatApplet.

* @return PrintWriter reference to server connection.

*/

public PrintWriter getOutput () {

return out;

}

 

/**

* Method is called from ChatApplet.

* @return BufferedReader reference to server connection.

*/

public BufferedReader getInput () {

return in;

}

 

/**

* Method is called from ChatApplet to establish connection to NakovChatServer.

* In case of the applet is started locally from a file (not from a web server),

* "localhost" is used as taget server, otherwise getCodeBase().getHost() is used.

*/

public boolean connect () {

boolean successfull = true;

String serverHost = m_Applet.getCodeBase().getHost();

if (serverHost.length()==0) {

m_Applet.addSystemMessage("Warning: Applet is loaded from a local file,");

m_Applet.addSystemMessage("not from a web server. Web browser's security");

m_Applet.addSystemMessage("will probably disable socket connections.");

serverHost = "localhost";

}

try {

m_Socket = new Socket(serverHost, SERVER_PORT);

in = new BufferedReader(

new InputStreamReader(m_Socket.getInputStream()));

out = new PrintWriter(

new OutputStreamWriter(m_Socket.getOutputStream()));

m_Applet.addSystemMessage("Connected to server " +

serverHost + ":" + SERVER_PORT);

} catch (SecurityException se) {

m_Applet.addSystemMessage("Security policy does not allow " +

"connection to " + serverHost + ":" + SERVER_PORT);

successfull = false;

} catch (IOException e) {

m_Applet.addSystemMessage("Can not establish connection to " +

serverHost + ":" + SERVER_PORT);

successfull = false;

}

 

// Create and start Listener thread

Listener listener = new Listener(m_Applet, in);

listener.setDaemon(true);

listener.start();

 

return successfull;

}

 

public void disconnect() {

if (!m_Applet.getConnected()) {

m_Applet.addSystemMessage("Can not disconnect. Not connected.");

return;

}

m_Applet.setConnected(false);

try {

m_Socket.close();

} catch (IOException ioe) {

}

m_Applet.addSystemMessage("Disconnected.");

}

 

/**

* Listener class - thread is used for receiving data that comes from

* the server and then "forward" it to ChatApplet.

*/

class Listener extends Thread

{

private BufferedReader mIn;

private ChatApplet mCA;

 

/**

* Constructor initiliaze InputStream, and ChatApplet reference

* @param aCA - ChatApplet reference

* @param aIn - InputStream from server connection

*/

public Listener (ChatApplet aCA, BufferedReader aIn) {

mCA = aCA;

mIn = aIn;

}

 

public void run() {

try {

while (!isInterrupted()) {

String message = mIn.readLine();

int colon2index = message.indexOf(":",message.indexOf(":")+1);

String user = message.substring(0, colon2index-1);

mCA.addText (message, user);

mCA.addUser (user);

}

} catch (Exception ioe) {

if (m_Applet.getConnected())

m_Applet.addSystemMessage("Communication error.");

}

m_Applet.setConnected(false);

}

}

}

 

NakovChatServer 1.9 ( chat /).

Running the Applet

chat HTML , . (ChatApplet.html):

<html>

 

<head>

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

<title>Chat Applet</title>

</head>

 

<body>

 

ChatApplet will appear below in a Java enabled browser.<br>

 

<applet

codebase = "."

code = "ChatApplet.class"

name = "TestApplet"

width = "430"

height = "300"

hspace = "0"

vspace = "0"

align = "middle"

>

</applet>

</body>

 

</html>

e AppletViewer appletviewer, bin JDK:

C:\Projects\ChatApplet> set PATH=%PATH%;C:\jdk1.3.1\bin

C:\Projects\ChatApplet> javac *.java

C:\Projects\ChatApplet> appletviewer ChatApplet.html

, web- ( Internet Explorer 5.0), web- URL-, . , , .class, . , ( URL) ChatApplet.html, , . , web- . , , getCodeBase().getHost() . , web-, getCodeBase().getHost() IP . , (web-), web-, .