topPanel.setBackground(new Color(255, 255, 200));
topPanel.add(prompt);
topPanel.add(namefield);
add("North", topPanel);
idList = new List(10, false);
add("West", idList );
dialogArea = new TextArea();
dialogArea.setEditable( false );
add("Center", dialogArea );
}
public void start() {
try {
showStatus("Connecting to " + serverName);
server = new ServerConnection(this,serverName);
server.start();
showStatus("Connected: " + serverName);
} catch (Exception e) {
single = true;
}
}
public void stop() {
if (!single)
server.quit();
}
void add(String id, String hostname, String name) {
delete(id); // in case it is already there.
idList.addItem("(" + id + ") " + name + "@" + hostname);
}
void delete(String id) {
for (int i = 0; i < idList.countItems(); i++) {
String s = idList.getItem(i);
s = s.substring(s.indexOf("(") + 1, s.indexOf(")"));
if (s.equals(id)) {
idList.delItem(i);
break;
}
}
if (idList.countItems() == 0)
showStatus("Wait for other players to arrive.");
}
private String getName(String id) {
for (int i = 0; i < idList.countItems(); i++) {
String s = idList.getItem(i);
String id1 = s.substring(s.indexOf("(") + 1, s.indexOf(")"));
if (id1.equals(id)) {
return s.substring(s.indexOf(" ") + 3, s.indexOf("@"));
}
}
return null;
}
void chat(String id, String s) {
dialogArea.appendText(id + ": " + s+ "\n");//append
showStatus(id + ": " + s);
}
void quit(String id) {
showStatus(id + " just quit.");
delete(id);
}
private void nameEntered(String s) {
if (s.equals(""))
return;
System.out.println(s);
name = s;
if( !single )
{
server.setName(name);
showStatus("Wait for other players to arrive.");
}
prompt.setText("You say:");
name_set = true;
}
public boolean action(Event evt, Object arg) {
System.out.println("a");
if(evt.id == Event.ACTION_EVENT)
if (evt.target == namefield){
if( name_set ){
dialogArea.appendText(name + ": " + namefield.getText()+"\n");
if(!single)
server.sendTo((String)arg, idList.getSelectedItem());
}
else nameEntered((String)arg);
namefield.setText("");
}
return true;
}
}
Цей клас є розширенням класу Applet, отже є аплетом. В цьому класі створюється об’єкт класу ServerConnection, через якій здійснюється обмін інформацією з сервером. Графічний інтерфейс цього класу представляє 3 області: поле вводу, в яке спочатку вводиться ім’я користувача, а потім - повідомлення, адресовані іншим клієнтам, список клієнтів, в якому треба обирати адресата, та текстова область в якій відбивається текст діалога. Метод action реалізує обробку події вводу тексту в область вводу. Методи add, delete, chat, nameEntered, quit є реакцією на наступні події: підключення нового клієнта, зникнення клієнта, надходження повідомлення від клієнта, ідентифікація та вихід. Ці методи визиваються класом ServerConnection при надходженні відповідних повідомлень, або ж всередині аплета, якщо джерелом події є сам клієнт.
клас ServerConnection:
import java.io.*;
import java.net.*;
import java.util.*;
class ServerConnection implements Runnable {
void sendTo(String s, String id)
{
if( id!= null )
out.println("to "+id+" "+s);
}
private static final int port = 6564;
private static final String CRLF = "\r\n";
private DataInputStream in;
private PrintStream out;
private String id, toid = null;
private Client client;
public ServerConnection(Scrabblet sc, String site) throws IOException {
Socket server = new Socket(site, port);
in = new DataInputStream(server.getInputStream());
out = new PrintStream(server.getOutputStream(), true);
}
public ServerConnection( Client c,String site) throws IOException {
client = c;
Socket server = new Socket(site, port);
in = new DataInputStream(server.getInputStream());
out = new PrintStream(server.getOutputStream(), true);
}
private String readline() {
try {
return in.readLine();
} catch (IOException e) {
return null;
}
}
void setName(String s) {
out.println("name " + s);
}
void delete() {
out.println("delete " + id);
}
void setTo(String to) {
toid = to;
}
void send(String s) {
if (toid != null)
out.println("to " + toid + " " + s);
}
void chat(String s) {
send("chat " + id + " " + s);
}
void quit() {
send("quit " + id); // tell other player
out.println("quit");
stop();
}
private Thread t;
void start() {
t = new Thread(this);
t.start();
}
void stop() {
t.stop();
}
private static final int ID = 1;
private static final int ADD = 2;
private static final int DELETE = 3;
private static final int CHAT = 4;
private static final int QUIT = 5;
private static Hashtable keys = new Hashtable();
private static String keystrings[] = {
"", "id", "add", "delete","chat",
"quit"
};
static {
for (int i = 0; i < keystrings.length; i++)
keys.put(keystrings[i], new Integer(i));
}
private int lookup(String s) {
Integer i = (Integer) keys.get(s);
return i == null ? -1 : i.intValue();
}
public void run() {
String s;
StringTokenizer st;
while ((s = readline()) != null) {
st = new StringTokenizer(s);
String keyword = st.nextToken();
switch (lookup(keyword)) {
default:
System.out.println("bogus keyword: " + keyword + "\r");
break;
case ID:
id = st.nextToken();
break;
case ADD: {
String id = st.nextToken();
String hostname = st.nextToken();
String name = st.nextToken(CRLF);
client.add(id, hostname, name);
}
break;
case CHAT: {
String from = st.nextToken();
client.chat(from, st.nextToken(CRLF));
}
break;
case QUIT: {
String from = st.nextToken();
client.quit(from);
}
break;
}
}
}
}
Цей клас є дзеркальним відображенням класу ClientConnection. Але він більш тісно переплетений з класом Client. В ньому реалізований потік, який опитує сокет, через який клієнт під’єднано до сервера, здійснює аналіз надходячих повідомлень та викликає потрібні методи класу Client. Крім того в ньому є методи, які викликаються класом Client для відсилання інформації на сервер.