发表时间:2010-03-16
最后修改:2010-03-16
本例开发实现了一个多用户的P2P在线聊天程序,C/S结构,客户端可发送消息,然后其他的用户接收到该消息并将其显示在界面中,服务器对信息进行有关处理并向适当的用户发送,同时在服务器端还将显示所有的在线用户,网络管理员即服务器端管理员可选中某用户并将其踢出该聊天室。
本篇为第四篇,如果您是第一次进来请从第一篇开始,此程序不用修改完全可用,第一篇地址:http://java161.iteye.com/blog/616113
4、编写客户端Applet类(Applet1.java)
创建一个Applet类,在给Applet的design视图中加入一个文本框textField、textArea1、label1、button1,并利用paneLayout对空间进行适当的布局。
在Applet中,需要提供用户登录、发送信息和显示信息三个区域,在本次开发中,将登录和发送信息合成一个文本框,即当用户第一次进入或该用户被网络管理员踢出时该文本框为输入登录信息框,当用户登录后该文本框为发送信息框,同时利用一个按钮来控制这个过程,该按钮的响应事件为action():
void action()
{
String str=textField1.getText();
if(str.equals("")) return;
try
{
if(!login)
{
userName=str;
simpleClient=new SimpleClient(this,hostname,4321);
simpleClient.sendString("login:%:"+str);
simpleClient.start();
login=true;
label1.setText("消息:");
button1.setLabel("发言");
textField1.setText("");
}
else
{
simpleClient.sendString(userName+":%:"+str);
}
}
catch(Exception ee)
{
ee.printStackTrace();
}
}
其中SimpleClient是一个用户实例,该实例中包含有和服务器建立连接Socket的输出流对象,并实例化了发送信息方法sendString()。最后得到SimpleClient类如源码包中SimpleClient.java 所示。
用户进行登录时,需要实例化一个用户线程,用来建立和服务器端指定端口的Socket连接,若成功则向该端口发送如下的用户登录信息,即该用户的登陆名称:
Socket serverSock=new Socket(hostName,portNumber);
simpleClient.sendString("login:%:"+str);
其中hostName为服务器名称或IP地址,postName为指定端口,str为用户所输入的登录名称,“:%:”为分隔符,simpleClient为该用户实例化线程,线程中包含有和服务器的Socket连接的输出流:
protected DataOutputStream outStream;
outStream =new DataOutputStream(serverSock.getOutputStream());
登录完成后,将控制按钮文字改变为“发言”,同时将登录标志为true。
程序清单:
Applet1.java
package Client;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.net.*;
import com.borland.jbcl.layout.*;
import com.borland.jbcl.control.*;
/**
* <p>Title: </p>
*
* <p>Description: </p>
*
* <p>Copyright: Copyright (c) 2010</p>
*
* <p>Company: </p>
*
* @author www.jianfei5u.com
* @version 1.0
*/
public class Applet1 extends Applet {
boolean isStandalone=false;
Button button1=new Button() ;
Label label1=new Label() ;
TextField textField1=new TextField();
GroupBox groupBox1=new GroupBox();
TextArea textArea1=new TextArea();
PaneLayout paneLayout1=new PaneLayout();
PaneLayout paneLayout2=new PaneLayout();
boolean login=false;
SimpleClient simpleClient=null;
static String userName="";
String hostname="202.117.115.228";
//Construct the Applet
public Applet1() {
}
//Initialize the Applet
public void init()
{
try
{
URL url=this.getCodeBase();
String te=url.toString();
String temp=url.getHost();
if(!(temp.equals("")))
hostname=temp; //得到服务器的ip地址
else hostname="202.117.115.228";
jbInit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
//Component initialization
private void jbInit() throws Exception
{
this.setSize(new Dimension(444,263));
button1.setLabel("登陆");
label1.setAlignment(2);
label1.setText("用户名");
textField1.addActionListener(new Applet1_textField1_actionAdapter(this));
groupBox1.setLayout(paneLayout1);
groupBox1.setLabel("信息");
button1.addActionListener(new Applet1_button1_actionAdapter(this));
this.setLayout(paneLayout2);
this.add(groupBox1,new PaneConstraints("groupBox1","groupBox1",
PaneConstraints.ROOT,0.5f));
groupBox1.add(textArea1,new PaneConstraints("textArea1","textArea1",
PaneConstraints.ROOT,1.0f));
this.add(label1,new PaneConstraints("label1","groupBox1",
PaneConstraints.BOTTOM,0.09505701f));
this.add(textField1,new PaneConstraints("textField1","label1",
PaneConstraints.RIGHT,0.83229816f));
this.add(button1,new PaneConstraints("button1","textField1",
PaneConstraints.RIGHT,0.30223882f));
}
//Get Applet information
public String getAppletInfo()
{
return "Applet Information";
}
//Get parameter information
public String[][] getParameterInfo()
{
return null;
}
public void destroy()
{
try
{
simpleClient.sendString("quit");
simpleClient.stop();
}
catch(Exception e)
{}
}
void action()
{
String str=textField1.getText();
if(str.equals("")) return;
try
{
if(!login)
{
userName=str;
simpleClient=new SimpleClient(this,hostname,4321);
simpleClient.sendString("login:%:"+str);
simpleClient.start();
login=true;
label1.setText("消息:");
button1.setLabel("发言");
textField1.setText("");
}
else
{
simpleClient.sendString(userName+":%:"+str);
}
}
catch(Exception ee)
{
ee.printStackTrace();
}
}
void button1_actionPerformed(ActionEvent e)
{
action();
}
void textField1_actionPerformed(ActionEvent e)
{
action();
}
}
class Applet1_button1_actionAdapter implements java.awt.event.ActionListener
{
Applet1 adaptee;
Applet1_button1_actionAdapter(Applet1 adaptee)
{
this.adaptee=adaptee;
}
public void actionPerformed(ActionEvent e)
{
adaptee.button1_actionPerformed(e);
}
}
class Applet1_textField1_actionAdapter implements java.awt.event.ActionListener
{
Applet1 adaptee;
Applet1_textField1_actionAdapter(Applet1 adaptee)
{
this.adaptee=adaptee;
}
public void actionPerformed(ActionEvent e)
{
adaptee.textField1_actionPerformed(e);
}
}
SimpleClient.java
package Client;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.*;
import com.borland.jbcl.layout.*;
import com.borland.jbcl.control.*;
/**
* <p>Title: </p>
*
* <p>Description: </p>
*
* <p>Copyright: Copyright (c) 2010</p>
*
* <p>Company: </p>
*
* @author www.jianfei5u.com
* @version 1.0
*/
public class SimpleClient extends Object implements Runnable
{
protected Socket serverSock;
protected DataOutputStream outStream;
protected Thread clientThread;
protected UserThread reader;
public SimpleClient(Applet1 applet,String hostName,
int portNumber)throws IOException
{
Socket serverSock=new Socket(hostName,portNumber);
outStream =new DataOutputStream(serverSock.getOutputStream());
reader=new UserThread(applet,serverSock);
reader.start();
}
public void start()
{
run();
}
public void stop()
{
clientThread.stop();
clientThread=null;
}
public synchronized void sendString(String str)throws IOException
{
outStream.writeUTF(str);
}
public void run()
{
try
{
sendString("");
}
catch(Exception oops)
{
oops.printStackTrace();
disconnect();
stop();
}
}
public void disconnect()
{
try
{
reader.closeConnection();
}
catch(Exception badclose)
{}
}
}
未完待续。。。下篇 编写客户端用户监听线程
地址: http://java161.iteye.com/blog/616663