局域网象棋 Java

为了学习一下套接字,借鉴老师给出的课题——象棋,我自己用Java写了一个可以局域网对战的象棋,老师当时要求用C++写,完成老师的课题后,我就学着Socket写了一个局域网的,我是从零开始,所以我借鉴了 Java亮剑PDF里的局域网象棋的服务器和客户端线程的代码,这才有了一点思路,了解到是如何传递信息的,可也仅仅知道了如何传递字符串,这里有个投机取巧的地方是用户的昵称只允许0-9个字符,因为在传递聊天信息的时候,读取聊天信息字符串的时候,为了计算内容的大小,需要知道给哪一个客户端发信息,而传递昵称的时候,判断传递的是两个还是三个字符串甚至更多,这样太麻烦了,干脆局限在一个字符好了。一开始打算写个人机博弈的算法,可时间不多,而且我没有那么聪明,不能把自己的想法改写成算法,就不开发人机博弈了。

下面就是我做的象棋的界面:



整个界面有以下几部分构成,菜单,棋局,时间板,文本框和按钮区,以及聊天列表、按钮,我的开发顺序:
一、可以自由行棋,无规则,所有棋子都保存在9X10的二维数组里
二、添加时间面板,使用Timer倒计时,这里不是很好要是可以使用分钟及秒的那种时间就完美了
三、加入规则判断,行棋是否合法,就是对数组进行计算
四、制作服务器端,客户端,连接通信,Socket的使用,其实就两个,readUTF和writeUTF传递字符串
五、连接客户端行棋,每次都需要使用for循环查找是哪一个客户端接收信息判断传递的字符串的开头进行分类
六、完善聊天框
七、代码优化,对鼠标点击事件进行修改
主类:Chess.java
package chessc;

import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.Socket;
import java.util.Random;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListModel;


public class Chess extends JFrame implements ActionListener,MouseListener{
	JLabel play[]=new JLabel[32];//棋子
	boolean initplay=true;//棋子初始化标志
	JLabel table;//棋盘
	int BORDER_LEFT=50,BORDER_UP=55;
	int UPDOWN=25,RIGLFT=20,SQUARE=58;//上下边界25像素,左右边界20像素,每个格子58像素
	int array[][]=new int[9][10];//10行9列数组代表棋子位置
	JLabel selected;//被选中标志
	JLabel terminus;//走棋后,给棋子标记
	int WHO=2;//红色方为2 黑色方为1
	JLabel jlHost=new JLabel("主机名");//创建提示输入主机名的标签
	JLabel jlPort=new JLabel("端口号");////创建提示输入端口号标签
	JLabel jlNickName=new JLabel("昵    称");//创建提示输入昵称的标签
	JTextField jtfHost=new JTextField("127.0.0.1");//创建输入主机名的文本框,默认值是"127.0.0.1"
	JTextField jtfPort=new JTextField("9999");//创建输入端口号的文本框,默认值是9999
	JTextField jtfNickName=new JTextField("Play1");//创建输入昵称的文本框,默认值是Play1
	JButton jbConnect=new JButton("连  接");//创建"连接"按钮
	JButton jbDisconnect=new JButton("断  开");//创建"断开"按钮
	JButton jbFail=new JButton("认  输");//创建"认输"按钮
	JButton jbChallenge=new JButton("挑  战");//创建"挑战"按钮
	JComboBox jcbNickList=new JComboBox();//创建存放当前用户的下拉列表框
	JList jlistChat=new JList();//创建用于显示当前用户的JList
	JScrollPane jspx=new JScrollPane(jlistChat);//将显示当前用户的JList放在JScrollPane中
	JButton jbYChallenge=new JButton("接受");//创建"接受挑战"按钮
	JButton jbNChallenge=new JButton("拒绝");//创建"拒绝挑战"按钮
	JMenuBar menubar = new JMenuBar();///*************************************************************************************/
	JMenu mehelp=  new JMenu("帮助");///*************************www.caeser.cn***********************************************/
	JMenu chmodel=new JMenu("模式选择");///*********************************************************************************/
	JMenuItem item[] = {new JMenuItem("帮助信息"),new JMenuItem("退出"),new JMenuItem("人人同机"),new JMenuItem("人机博弈"),new JMenuItem("局域网对战") };
	JLabel jlt1=new JLabel("红方剩余时间 / 秒"),jlt2=new JLabel("黑方剩余时间 / 秒");
	TimeController time[]={new TimeController(),new TimeController()};
	JPanel timePane[]={new JPanel(),new JPanel()};
	JLabel timeBLUE[]={new JLabel(new ImageIcon("image\\BLUE.PNG")),new JLabel(new ImageIcon("image\\BLUE.PNG"))};
	JLabel timSQUARE1;
	JLabel jlChat=new JLabel("聊天室");
	JTextField jtfChat=new JTextField("输入聊天内容");
	JButton jbChat=new JButton("发送(alt+enter)");
	int ModelFlag=0;//模式选择
	Rules rules;//行棋规则判断
	int startX=0,startY=0,endX=0,endY=0;
	Socket sc;//声明Socket引用
	ClientAgentThread cat;//声明客户端代理线程的引用
	String chatTp="";//传递聊天内容
	int Pdisappear=0;//让被吃棋子消失
	boolean helpFLAG=false;//窗口重复点击提示
	boolean serFLAG=false;//窗口重复点击提示
	Server serf;//窗口重复点击提示
	Help helpf;//窗口重复点击提示
	public Chess(){
		this.loadp();
		this.initialChess();//初始化棋子
		this.initialComponent();//初始化控件
		this.addListener();//为相应控件注册事件监听器
		this.initialState();//初始化状态
		this.initialFrame();//初始化窗体
	}
	public void initialComponent(){
		this.setLayout(null);//空布局
		selected.setBounds(0, 0, 55, 55);//选中标志
		this.add(selected);//添加选中标志到窗口
		terminus.setBounds(0, 0, 55, 55);//和选中标志一样
		this.add(terminus);//叫终止标志,添加到窗口
		this.table.setBounds(0,0, 558, 620);//棋盘
		this.add(table);//添加棋盘到窗口
		this.chmodel.add(item[2]);//模式选择里添加 菜单选项 人人同机
		this.chmodel.add(item[3]);//人机博弈
		this.chmodel.add(item[4]);//局域网
		this.mehelp.add(item[0]);//帮助信息里添加 菜单选项 帮助
		this.mehelp.add(item[1]);//退出
		this.menubar.add(chmodel);//菜单栏添加 模式选择
		this.menubar.add(mehelp);//帮助信息
		this.setJMenuBar(menubar);//设置菜单栏
		
		timePane[0]=time[0].getPane();//黑方时间
		timePane[0].setBounds(680, 12, 30, 10);//设置时间位置
		this.add(timePane[0]);//添加到窗口
		timePane[1]=time[1].getPane();//红方时间
		timePane[1].setBounds(680, 582, 30, 10);//设置时间位置
		this.add(timePane[1]);//添加到窗口
		this.jlt1.setBounds(570, 9, 100, 15);//黑方倒计时
		this.jlt1.setForeground(Color.white);//设置字颜色
		this.add(jlt1);//添加到窗口
		this.jlt2.setBounds(570, 580, 100, 15);//红方倒计时
		this.jlt2.setForeground(Color.white);//设置字颜色
		this.add(jlt2);//添加到窗口
		this.jlHost.setBounds(575, 60, 50, 20);//主机名称
		this.add(jlHost);//添加到窗口
		this.jtfHost.setBounds(625, 60, 100, 20);//主机名输入
		this.add(jtfHost);//添加到窗口
		this.jlPort.setBounds(575, 90, 50, 20);//端口
		this.add(jlPort);//添加到窗口
		this.jtfPort.setBounds(625, 90, 100, 20);//端口号输入
		this.add(jtfPort);//添加到窗口
		this.jlNickName.setBounds(575, 120, 50, 20);//昵称
		this.add(jlNickName);//添加到窗口
		this.jtfNickName.setBounds(625, 120, 100, 20);//昵称输入
		this.add(jtfNickName);//添加到窗口
		this.jbConnect.setBounds(570, 150, 80, 20);//连接按钮
		this.add(jbConnect);//添加到窗口
		this.jbDisconnect.setBounds(660, 140, 80, 20);//断开按钮
		this.add(jbDisconnect);//添加到窗口
		this.jbChallenge.setBounds(570, 180, 80, 20);//挑战按钮
		this.add(jbChallenge);//添加到窗口
		this.jbFail.setBounds(660, 162, 80, 20);//认输按钮
		this.add(jbFail);//添加到窗口
		this.jcbNickList.setBounds(570, 210, 80, 20);//挑战名单
		this.add(jcbNickList);//添加到窗口
		this.jbYChallenge.setBounds(660, 184, 80, 20);//接受挑战
		this.add(jbYChallenge);//添加到窗口
		this.jbNChallenge.setBounds(660, 206, 80, 20);//拒绝挑战
		this.add(jbNChallenge);//添加到窗口
		timSQUARE1.setBounds(560, 0, 200, 300);//美化标志
		this.add(timSQUARE1);//添加到窗口
		this.jlChat.setBounds(570, 265, 50, 20);//聊天室
		this.add(jlChat);//添加到窗口
		this.jspx.setBounds(570, 285, 180, 200);//聊天内容
		this.add(jspx);//添加到窗口
		
		this.jtfChat.setBounds(570, 490, 180, 20);//输入聊天
		this.add(jtfChat);//添加到窗口
		this.jbChat.setBounds(600, 520, 150, 20);//发送按钮
		this.jbChat.setMnemonic(KeyEvent.VK_ENTER);//设置为快捷键alt+enter
		this.add(jbChat);//添加到窗口
		this.timeBLUE[0].setBounds(550, 0, 220, 35);//时间面板背景
		this.add(timeBLUE[0]);//添加到窗口
		this.timeBLUE[1].setBounds(550, 570, 220, 35);//时间面板背景
		this.add(timeBLUE[1]);//添加到窗口
	}
	public void addListener(){
		for(int a=0;a<item.length;a++){//给菜单二级选项添加监听
			item[a].addActionListener(this);
		}//添加监听
		this.jtfChat.addActionListener(this);//聊天输入框
		this.jtfHost.addActionListener(this);//主机号
		this.jtfNickName.addActionListener(this);//昵称
		this.jtfPort.addActionListener(this);//端口
		
		this.jbChallenge.addActionListener(this);//挑战按钮
		this.jbChat.addActionListener(this);//发生聊天按钮
		this.jbConnect.addActionListener(this);//连接按钮
		this.jbDisconnect.addActionListener(this);//断开按钮
		this.jbFail.addActionListener(this);//认输按钮
		this.jbNChallenge.addActionListener(this);//拒绝挑战按钮
		this.jbYChallenge.addActionListener(this);//接受挑战按钮
		this.table.addMouseListener(this);//棋盘
		for(int a=0;a<play.length;a++){//棋子
			play[a].addMouseListener(this);
		}
	}
	public void initialState(){
		selected.setVisible(false);
		terminus.setVisible(false);
		timePane[1].setVisible(true);
		timePane[0].setVisible(true);
		this.jtfHost.setEditable(true);
		this.jtfNickName.setEditable(true);
		this.jtfPort.setEditable(true);
		this.jbChallenge.setEnabled(false);
		this.jbConnect.setEnabled(false);
		this.jbDisconnect.setEnabled(false);
		this.jbFail.setEnabled(false);
		this.jbNChallenge.setEnabled(false);
		this.jbYChallenge.setEnabled(false);
		this.jtfChat.setEditable(false);
		this.jbChat.setEnabled(false);
		this.jtfChat.addFocusListener(new FocusListener() {
			public void focusGained(FocusEvent e) {
				JTextField src = (JTextField) e.getSource();
				if (src.getText().equals("输入聊天内容")) {
					src.setText(null);
				}//这里实现文本框未输入信息时显示提示信息
			}
			public void focusLost(FocusEvent e) {
				JTextField src = (JTextField) e.getSource();
				if (src.getText().trim().isEmpty()) {
					src.setText("输入聊天内容");
				}//当文本框内容被清空时显示提示信息
			}
		});
	}
	public void initialChess(){
		WHO=2;
		initArray();//初始化数组
		drawChess();
		this.selected.setVisible(false);
		this.terminus.setVisible(false);
	}
	public void drawChess(){
		int i,j;
		for(i=0;i<9;i++){//根据数组将棋子显示并移动到相应的位置
			for(j=0;j<10;j++){
				if(array[i][j]==-1){
					continue;
				}
				play[array[i][j]].setVisible(true);//(1)设置可见
				play[array[i][j]].setBounds(RIGLFT+i*SQUARE,UPDOWN+j*SQUARE, 55, 55);
				if(this.initplay){
					this.add(play[array[i][j]]);//(2)添加棋子到窗口
				}
			}
		}//执行初始化后将(1)设置可见和(2)添加棋子到窗口动作取消
		this.initplay=false;
	}
	public void initArray(){
		int i,j;
		for(i=0;i<9;i++){//初始化数组使每一个值都为-1
			for(j=0;j<10;j++){
				array[i][j]=-1;
			}
		}
		
		//色方
		for(i=0;i<9;i++){//赋值車、马、象、士、帅
			array[i][9]=i;
		}
		array[1][7]=i++;//赋值炮
		//i++;
		array[7][7]=i++;//赋值炮
		//i++;
		for(j=0;i<16;i++){//赋值兵
			array[j][6]=i;j+=2;
		}
		//色方
		for(j=0;i<25;i++){//赋值車、马、象、士、将
			array[j++][0]=i;
		}
		array[1][2]=i++;//赋值炮
		array[7][2]=i++;//赋值炮
		for(j=0;i<32;i++){//赋值卒
			array[j][3]=i;j+=2;
		}
	}
	public void initime(){
		this.time[0].initime();
		this.time[1].initime();
		this.time[0].spTime();
		this.time[1].spTime();
	}
	public void loadp(){
		table=new JLabel(new ImageIcon("image\\Main.GIF"));
		selected=new JLabel(new ImageIcon("image\\SELECTED1.GIF"));
		terminus=new JLabel(new ImageIcon("image\\SELECTED1.GIF"));
		play[0]=new JLabel(new ImageIcon("image\\黑车.GIF"));
		play[1]=new JLabel(new ImageIcon("image\\黑马.GIF"));
		play[2]=new JLabel(new ImageIcon("image\\黑象.GIF"));
		play[3]=new JLabel(new ImageIcon("image\\黑士.GIF"));
		play[4]=new JLabel(new ImageIcon("image\\黑将.GIF"));
		play[5]=new JLabel(new ImageIcon("image\\黑士.GIF"));
		play[6]=new JLabel(new ImageIcon("image\\黑象.GIF"));
		play[7]=new JLabel(new ImageIcon("image\\黑马.GIF"));
		play[8]=new JLabel(new ImageIcon("image\\黑车.GIF"));
		play[9]=new JLabel(new ImageIcon("image\\黑炮.GIF"));
		play[10]=new JLabel(new ImageIcon("image\\黑炮.GIF"));
		for(int p=11;p<16;p++){
			play[p]=new JLabel(new ImageIcon("image\\黑卒.GIF"));
		}
		play[16]=new JLabel(new ImageIcon("image\\红车.GIF"));
		play[17]=new JLabel(new ImageIcon("image\\红马.GIF"));
		play[18]=new JLabel(new ImageIcon("image\\红象.GIF"));
		play[19]=new JLabel(new ImageIcon("image\\红士.GIF"));
		play[20]=new JLabel(new ImageIcon("image\\红将.GIF"));
		play[21]=new JLabel(new ImageIcon("image\\红士.GIF"));
		play[22]=new JLabel(new ImageIcon("image\\红象.GIF"));
		play[23]=new JLabel(new ImageIcon("image\\红马.GIF"));
		play[24]=new JLabel(new ImageIcon("image\\红车.GIF"));
		play[25]=new JLabel(new ImageIcon("image\\红炮.GIF"));
		play[26]=new JLabel(new ImageIcon("image\\红炮.GIF"));
		for(int p=27;p<32;p++){
			play[p]=new JLabel(new ImageIcon("image\\红卒.GIF"));
		}
		timSQUARE1=new JLabel(new ImageIcon("image\\时间矩形.GIF"));
		rules=new Rules(array);
	}
	public void initialFrame(){
		this.setTitle("中国象棋--客户端");
		this.setBounds(300,0,780,680);//设置窗体大小
		this.setVisible(true);//设置可见性
		//this.setDefaultCloseOperation(EXIT_ON_CLOSE);//关闭窗口
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		this.addWindowListener(//为窗体添加监听器
				new WindowAdapter()
				{
					public void windowClosing(WindowEvent e)
					{
						if(cat==null)//客户端代理线程为空,直接退出
						{
							System.exit(0);
							return;
						}
						try
						{
							if(cat.challenger!=null)//正在下棋中
							{
								try
								{
									//发送认输信息
									cat.dout.writeUTF("<#RENSHU#>"+cat.challenger);
								}
								catch(Exception ee)
								{
									ee.printStackTrace();
								}
							}
							cat.dout.writeUTF("<#CLIENT_LEAVE#>");//向服务器发送离开信息
							cat.flag=false;//终止客户端代理线程
							cat=null;
							
						}
						catch(Exception ee)
						{
							ee.printStackTrace();
						}
						System.exit(0);
					}
					
				}
				);
	}
	public void actionPerformed(ActionEvent ae) {//定义按钮的事件响应
		try{
			if(ae.getSource()==item[0]){//帮助信息
				if(!this.helpFLAG){
					helpf=new Help(this);
					this.helpFLAG=true;
				}else{
					helpf.setVisible(false);
					helpf.setVisible(true);
				}
				
			}else if(ae.getSource()==item[1]){//退出
				System.exit(0);
			}else if(ae.getSource()==item[2]){//人人同机
				JOptionPane.showMessageDialog(this, "红旗先行","提示",JOptionPane.INFORMATION_MESSAGE);
				this.initialChess();
				this.ModelFlag=1;
				this.initime();
				this.jtfChat.setEditable(false);//聊天输入框设置为不可用
				this.jtfHost.setEnabled(false);//将用于输入主机名的文本框设为不可用
				this.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
				this.jtfNickName.setEnabled(false);//将用于输入昵称的文本框设为不可用
				this.jbConnect.setEnabled(false);//将"连接"按钮设为不可用
				this.jbDisconnect.setEnabled(false);//将"断开"按钮设为可用
				this.jbChallenge.setEnabled(false);//将"挑战"按钮设为可用
				this.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
				this.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
				this.jbFail.setEnabled(false);//将"认输"按钮设为不可用
			}else if(ae.getSource()==item[3]){//人机博弈
				
				JOptionPane.showMessageDialog(this, "该功能暂未开发","提示",JOptionPane.INFORMATION_MESSAGE);
				return;
			}else if(ae.getSource()==item[4]){//局域网对战
				
				this.initialChess();
				this.ModelFlag=3;
				this.initime();
				
				this.jtfHost.setEnabled(true);//将用于输入主机名的文本框设为不可用
				this.jtfPort.setEnabled(true);//将用于输入端口号的文本框设为不可用
				this.jtfNickName.setEnabled(true);//将用于输入昵称的文本框设为不可用
				this.jbConnect.setEnabled(true);//将"连接"按钮设为不可用
				this.jtfChat.setEditable(false);
				this.jbDisconnect.setEnabled(false);//将"断开"按钮设为可用
				this.jbChallenge.setEnabled(false);//将"挑战"按钮设为可用
				this.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
				this.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
				this.jbFail.setEnabled(false);//将"认输"按钮设为不可用
				if(!this.serFLAG){
					this.serf=new Server(this);
					this.serFLAG=true;
				}else{
					serf.setVisible(false);
					serf.setVisible(true);
				}
				
			}
			if(ae.getSource()==this.jbConnect){
				this.jbConnect_event();
			}else if(ae.getSource()==this.jbChallenge){
				this.jbChallenge_event();
			}else if(ae.getSource()==this.jbChat){
				this.jbChat_event();
			}else if(ae.getSource()==this.jbDisconnect){
				this.jbDisconnect_event();
			}else if(ae.getSource()==this.jbFail){
				this.jbFail_event();
			}else if(ae.getSource()==this.jbNChallenge){
				this.jbNChallenge_event();
			}else if(ae.getSource()==this.jbYChallenge){
				this.jbYChallenge_event();
			}
		}catch(Exception ee){
			ee.printStackTrace();
		}
		
	}
	public void jbChat_event(){
		int itTp;
		Vector v=new Vector();
		chatTp=this.jtfChat.getText().trim();
		if(chatTp.equals("")){
			JOptionPane.showMessageDialog(this,"不能发生空消息","提示",JOptionPane.ERROR_MESSAGE);
			//return;
		}else{
			ListModel myList=this.jlistChat.getModel();//提取JList内容
			for(int i=0;i<myList.getSize();i++){
				v.add(myList.getElementAt(i));//将之前的聊天内容保存在V里
			}
			v.add(chatTp);//添加新的聊天内容
			chatTp="玩家"+this.jtfNickName.getText().trim()+":"+chatTp;
			this.jlistChat.setListData(v);//显示聊天内容
			itTp=this.cat.challenger.length();
			this.jtfChat.setText("");
			this.jlistChat.setListData(v);
			try{
				this.cat.dout.writeUTF("<#CHAT#>"+this.cat.challenger+chatTp+itTp);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	public void jbConnect_event()
	{//对单击"连接"按钮事件的业务处理代码
		int port=0;
		try
		{//获得用户输入的断口号并转化为整型
			port=Integer.parseInt(this.jtfPort.getText().trim());
		}
		catch(Exception ee)
		{//不是整数,给出错误提示
			JOptionPane.showMessageDialog(this,"端口号只能是整数","错误",
			                              JOptionPane.ERROR_MESSAGE);
			return;
		}
		if(port>65535||port<0)
		{//端口号不合法,给出错误提示
			JOptionPane.showMessageDialog(this,"端口号只能是0-65535的整数","错误",
			                              JOptionPane.ERROR_MESSAGE);
			return;
		}
		String name=this.jtfNickName.getText().trim();//获得昵称
		if(name.length()==0)
		{//昵称为空,给出错误提示信息
			JOptionPane.showMessageDialog(this,"玩家姓名不能为空","错误",
			                              JOptionPane.ERROR_MESSAGE);
			return;
		}
		if(name.length()>9)
		{//昵称为空,给出错误提示信息
			JOptionPane.showMessageDialog(this,"玩家姓名不能超过10个字符","错误",
			                              JOptionPane.ERROR_MESSAGE);
			return;
		}
		try
		{
			sc=new Socket(this.jtfHost.getText().trim(),port);//创建Socket对象
			cat=new ClientAgentThread(this);//创建客户端代理线程	
			cat.start();//启动客户端代理线程	
			this.jbChat.setEnabled(true);
			this.jtfHost.setEnabled(false);//将用于输入主机名的文本框设为不可用
			this.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
			this.jtfNickName.setEnabled(false);//将用于输入昵称的文本框设为不可用
			this.jbConnect.setEnabled(false);//将"连接"按钮设为不可用
			this.jbDisconnect.setEnabled(true);//将"断开"按钮设为可用
			this.jbChallenge.setEnabled(true);//将"挑战"按钮设为可用
			this.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
			this.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
			this.jbFail.setEnabled(false);//将"认输"按钮设为不可用
			JOptionPane.showMessageDialog(this,"已连接到服务器","提示",
			            JOptionPane.INFORMATION_MESSAGE);//连接成功,给出提示信息	
		}
		catch(Exception ee)
		{
			JOptionPane.showMessageDialog(this,"连接服务器失败","错误",
			        JOptionPane.ERROR_MESSAGE);//连接失败,给出提示信息
			return;
		}
	}
	public void jbDisconnect_event()
	{//对单击"断开"按钮事件的业务处理代码
		try
		{
			this.cat.dout.writeUTF("<#CLIENT_LEAVE#>");//向服务器发送离开的信息
			this.cat.flag=false;//终止客户端代理线程
			this.cat=null;
			this.jtfHost.setEnabled(true);//将用于输入主机名的文本框设为可用
			this.jtfPort.setEnabled(true);//将用于输入端口号的文本框设为可用
			this.jtfNickName.setEnabled(true);//将用于输入昵称的文本框设为可用
			this.jbConnect.setEnabled(true);//将"连接"按钮设为可用
			this.jbDisconnect.setEnabled(false);//将"断开"按钮设为不可用
			this.jbChallenge.setEnabled(false);//将"挑战"按钮设为不可用
			this.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
			this.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
			this.jbFail.setEnabled(false);//将"认输"按钮设为不可用
		}
		catch(Exception ee)
		{
			ee.printStackTrace();
		}
	}
	public void jbChallenge_event(){
		//获得用户选中的挑战对象
		Object o=this.jcbNickList.getSelectedItem();
		if(o==null||((String)o).equals("")) {
			JOptionPane.showMessageDialog(this,"请选择对方名字","错误",
			JOptionPane.ERROR_MESSAGE);//当未选中挑战对象,给出错误提示信息
		}
		else{
			String name2=(String)this.jcbNickList.getSelectedItem();//获得挑战对象
			try{
				this.jtfHost.setEnabled(false);//将用于输入主机名的文本框设为不可用
				this.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
				this.jtfNickName.setEnabled(false);//将用于输入昵称的文本框设为不可用
				this.jbConnect.setEnabled(false);//将"连接"按钮设为不可用
				this.jbDisconnect.setEnabled(false);//将"断开"按钮设为不可用
				this.jbChallenge.setEnabled(false);//将"挑战"按钮设为不可用
				this.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
				this.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
				this.jbFail.setEnabled(false);//将"认输"按钮设为不可用
				this.cat.challenger=name2;//设置挑战对象
				this.WHO=3;
				this.cat.dout.writeUTF("<#TIAO_ZHAN#>"+name2);//发送挑战信息
				JOptionPane.showMessageDialog(this,"已提出挑战,请回复 ...","提示",
				           JOptionPane.INFORMATION_MESSAGE);//给出信息发出的提示信息
			}
			catch(Exception ee){ee.printStackTrace();}
		}
	}
	public void jbYChallenge_event(){
		try{	//发送同意挑战的信息
			this.cat.dout.writeUTF("<#TONG_YI#>"+this.cat.challenger);
			this.jtfHost.setEnabled(false);//将用于输入主机名的文本框设为不可用
			this.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
			this.jtfNickName.setEnabled(false);//将用于输入昵称的文本框设为不可用
			this.jbConnect.setEnabled(false);//将"连接"按钮设为不可用
			this.jbDisconnect.setEnabled(!true);//将"断开"按钮设为不可用
			this.jbChallenge.setEnabled(!true);//将"挑战"按钮设为不可用
			this.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
			this.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
			this.jbFail.setEnabled(!false);//将"认输"按钮设为可用
			this.jbChat.setEnabled(true);
			this.jtfChat.setEditable(true);
		}
		catch(Exception ee){ee.printStackTrace();}
	}
	public void jbNChallenge_event(){
		try{   //发送拒绝挑战的信息
			this.cat.dout.writeUTF("<#BUTONG_YI#>"+this.cat.challenger);
			this.cat.challenger=null;//将tiaoZhanZhe设为空
			this.jtfHost.setEnabled(false);//将用于输入主机名的文本框设为不可用
			this.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
			this.jtfNickName.setEnabled(false);//将用于输入昵称的文本框设为不可用
			this.jbConnect.setEnabled(false);//将"连接"按钮设为不可用
			this.jbDisconnect.setEnabled(true);//将"断开"按钮设为可用
			this.jbChallenge.setEnabled(true);//将"挑战"按钮设为可用
			this.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
			this.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
			this.jbFail.setEnabled(false);//将"认输"按钮设为不可用
			this.jbChat.setEnabled(false);
		}
		catch(Exception ee){ee.printStackTrace();}
	}
	public void jbFail_event(){
		try{   //发送认输的信息
			this.cat.dout.writeUTF("<#RENSHU#>"+this.cat.challenger);
			this.cat.challenger=null;//将tiaoZhanZhe设为空
			this.initialChess();
			this.time[0].initime();
			this.time[1].initime();
			this.jtfHost.setEnabled(false);//将用于输入主机名的文本框设为不可用
			this.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
			this.jtfNickName.setEnabled(false);//将用于输入昵称的文本框设为不可用
			this.jbConnect.setEnabled(false);//将"连接"按钮设为不可用
			this.jbDisconnect.setEnabled(true);//将"断开"按钮设为可用
			this.jbChallenge.setEnabled(true);//将"挑战"按钮设为可用
			this.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
			this.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
			this.jbFail.setEnabled(false);//将"认输"按钮设为不可用
		}
		catch(Exception ee){ee.printStackTrace();}	
	}
	public void mouseClicked(MouseEvent me){//单击棋子或棋盘
		if(this.ModelFlag!=0){
			if(WHO==1){//黑色
				MouseClicke(me,0,16,16,32);
			}else if(this.WHO==2){//红色
				MouseClicke(me,16,32,0,16);
			}
			
		}else{
			JOptionPane.showMessageDialog(this, "请选择模式","提示",JOptionPane.INFORMATION_MESSAGE);
			return;
		}
	}
	public void MouseClicke(MouseEvent me,int pA,int pB,int pC,int pD){
		int[] tmp=new int[2];
		for(int i=pA;i<pB;i++){
			if(me.getSource().equals(play[i])){
				tmp=getPlayPos(i);
				this.startX=tmp[0];
				this.startY=tmp[1];
				this.terminus.setVisible(false);
				this.selected.setVisible(true);
				this.selected.setBounds(play[i].getX(),play[i].getY(),55,55);
				return;
			}
		}
		if(array[startX][startY]>=pA&&array[startX][startY]<=pB){
			tmp=this.getPos(me);
			endX=tmp[0];endY=tmp[1];
			for(int j=pC;j<pD;j++){
				if(me.getSource().equals(play[j])){
					tmp=getPlayPos(j);
					endX=tmp[0];endY=tmp[1];
					break;
				}
			}
			if(rules.ifMove(startX,startY,endX,endY,array[startX][startY])){
				EndMove(startX,startY,endX,endY);
				if(ModelFlag==1){
					if(WHO==1){
						this.time[0].stTime();
						this.time[1].spTime();
						this.WHO=2;
					}
					else{
						this.time[1].stTime();
						this.time[0].spTime();
						this.WHO=1;
					}
				}else if(ModelFlag==3){
					if(this.WHO==1){
						this.WHO=3;
						this.time[0].stTime();
						this.time[1].spTime();
					}
					else{
						this.WHO=4;
						this.time[1].stTime();
						this.time[0].spTime();
					}
					try{
						this.cat.dout.writeUTF("<#MOVE#>"+this.cat.challenger+startX+startY+endX+endY);
					}catch(Exception ee){ee.printStackTrace();}	
				}
				if(this.FaceToFace()){
					JOptionPane.showMessageDialog(this, "照将","提示",JOptionPane.INFORMATION_MESSAGE);
					if(ModelFlag==1){
						this.initialChess();
						this.initime();
					}else if(ModelFlag==3){
						try{
							this.cat.dout.writeUTF("<#RENSHU#>"+this.cat.challenger);
							this.cat.dout.writeUTF("<#VICTOR#>"+this.jtfNickName.getText().trim());
						}catch(Exception ee){ee.printStackTrace();}	
					}
					
				}
			}
		}
	}
	public int[] getPlayPos(int target){
		int[] pos=new int[2];
		pos[0]=-1;
		pos[1]=-1;
		for(int i=0;i<9;i++){
			for(int j=0;j<10;j++){
				if(array[i][j]==target){
					pos[0]=i;
					pos[1]=j;
					return pos;
				}
			}
		}
		return pos;
	}
	public int[] getPos(MouseEvent e){
		int[] pos=new int[2];
		pos[0]=-1;
		pos[1]=-1;
		Point p=e.getPoint();//获得事件发生的坐标点
		double x=p.getX();
		double y=p.getY();
		if(Math.abs((x-BORDER_LEFT)/1%(SQUARE-1))<=25){//获得对应于数组x下标的位置
			pos[0]=Math.round((float)(x-BORDER_LEFT))/(SQUARE-1);
		}
		else if(Math.abs((x-BORDER_LEFT)/1%(SQUARE-1))>=35){
			pos[0]=Math.round((float)(x-BORDER_LEFT))/(SQUARE-1)+1;
		}
		if(Math.abs((y-BORDER_UP)/1%(SQUARE-1))<=25){//获得对应于数组y下标的位置
			pos[1]=Math.round((float)(y-BORDER_UP))/(SQUARE-1);
		}
		else if(Math.abs((y-BORDER_UP)/1%(SQUARE-1))>=35){
			pos[1]=Math.round((float)(y-BORDER_UP))/(SQUARE-1)+1;
		}
		return pos;
	}
	public void EndMove(int startX,int startY,int endX, int endY){
		//存在的显示不存在的让它消失
		Pdisappear=array[endX][endY];
		array[endX][endY]=array[startX][startY];
		array[startX][startY]=-1;
		this.drawChess();
		if(Pdisappear!=-1){
			play[Pdisappear].setVisible(false);
		}
		this.terminus.setVisible(true);//显示终点选中框
		this.selected.setVisible(true);//显示起点选中框
		this.selected.setBounds(RIGLFT+startX*SQUARE,UPDOWN+startY*SQUARE, 55, 55);
		this.terminus.setBounds(RIGLFT+endX*SQUARE,UPDOWN+endY*SQUARE, 55, 55);
		
	}
	public boolean FaceToFace(){
		boolean FLAG=false;
		int B_K_X=0,B_K_Y=0,R_K_X=0,R_K_Y=0;
		int[] tmp=new int[2];
		tmp=getPlayPos(4);
		B_K_X=tmp[0];B_K_Y=tmp[1];
		tmp=getPlayPos(20);
		R_K_X=tmp[0];R_K_Y=tmp[1];
		if(B_K_X==R_K_X){
			FLAG=true;
			for(int i=R_K_Y+1;i<B_K_Y;i++){
				if(array[B_K_X][i]!=-1){
					FLAG=false;
					break;
				}
			}
		}
		return FLAG;
	}
	public void mousePressed(MouseEvent me){}
	public void mouseReleased(MouseEvent me){}
	public void mouseEntered(MouseEvent me){}
	public void mouseExited(MouseEvent me){}	
	public static void main(String args[]){
		new Chess();
	}
}
ClientAgentThread.java
package chessc;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.ListModel;

public class ClientAgentThread extends Thread{
	Chess father;
	boolean flag=true;//控制线程的标志位
	DataInputStream din;//声明数据输入输出流的引用 
	DataOutputStream dout;
	String challenger=null;//用于记录正在挑战的对手
	public ClientAgentThread(Chess p1){
		this.father=p1;
		try
		{
			din=new DataInputStream(father.sc.getInputStream());//创建数据输入输出流
			dout=new DataOutputStream(father.sc.getOutputStream());
			
			String name=father.jtfNickName.getText().trim();//获得昵称
			dout.writeUTF("<#NICK_NAME#>"+name);//发送昵称到服务器
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	public void run(){
		while(flag){
			try{
				String msg=din.readUTF().trim();//获得服务器发来的信息
				if(msg.startsWith("<#NAME_CHONGMING#>")){//收到重名的信息
					this.name_chongming();
				}
				else if(msg.startsWith("<#NICK_LIST#>")){//收到昵称列表
					this.nick_list(msg);
				}
				else if(msg.startsWith("<#SERVER_DOWN#>")){//当收到服务器离开的信息
					this.server_down();
				}
				else if(msg.startsWith("<#TIAO_ZHAN#>")){//当收到挑战的信息
					this.tiao_zhan(msg);
				}
				else if(msg.startsWith("<#TONG_YI#>")){
					this.tong_yi();//当该用户收到对方接受挑战的信息时	
				}
				else if(msg.startsWith("<#BUTONG_YI#>")){
					this.butong_yi();//当该用户收到对方拒绝挑战的信息时
				}
				else if(msg.startsWith("<#BUSY#>")){//当收到对方忙的信息时
					this.busy();
				}
				else if(msg.startsWith("<#MOVE#>")){//当收到走棋的信息时
					this.move(msg);
				}
				else if(msg.startsWith("<#RENSHU#>")){//当收到认输的信息时
					this.renshu();
				}else if(msg.startsWith("<#CHAT#>")){//接收到聊天消息时
					this.chat(msg);
				}else if(msg.startsWith("<#VICTOR#>")){//接收到胜利消息时给对方发消息
					this.victory();
				}
			}
			catch(Exception e){e.printStackTrace();}
		}
	}
	public void chat(String msg){
		Vector v=new Vector();
		ListModel myList=this.father.jlistChat.getModel();
		for(int i=0;i<myList.getSize();i++){
			v.add(myList.getElementAt(i));
		}
		v.add(msg.substring(8));
		this.father.jlistChat.setListData(v);
	}
	public void name_chongming(){
		try{
			JOptionPane.showMessageDialog(this.father,"该玩家名称已经被占用,请重新填写!",
			            "错误",JOptionPane.ERROR_MESSAGE);//给出重名的提示信息
			din.close();//关闭数据输入流
			dout.close();//关闭数据输出流
			this.father.jtfHost.setEnabled(true);//将用于输入主机名的文本框设为可用
			this.father.jtfPort.setEnabled(true);//将用于输入端口号的文本框设为可用
			this.father.jtfNickName.setEnabled(true);//将用于输入昵称的文本框设为可用
			this.father.jbConnect.setEnabled(true);//将"连接"按钮设为可用
			this.father.jbDisconnect.setEnabled(false);//将"断开"按钮设为不可用
			this.father.jbChallenge.setEnabled(false);//将"挑战"按钮设为不可用
			this.father.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
			this.father.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
			this.father.jbFail.setEnabled(false);//将"认输"按钮设为不可用
			father.sc.close();//关闭Socket
			father.sc=null;
			father.cat=null;
			flag=false;//终止该客户端代理线程
		}
		catch(IOException e){e.printStackTrace();}
	}
	public void nick_list(String msg){
		String s=msg.substring(13);//分解并得到有用信息
		String[] na=s.split("\\|");
		Vector v=new Vector();//创建Vector对象
		for(int i=0;i<na.length;i++){
			if(na[i].trim().length()!=0&&(!na[i].trim().equals(father.jtfNickName.getText().trim()))){
				v.add(na[i]);//将昵称全部添加到Vector中
			}
		}
		father.jcbNickList.setModel(new DefaultComboBoxModel(v));//设置下拉列表的值
	}
	public void server_down(){
		this.father.jtfHost.setEnabled(!false);//将用于输入主机名的文本框设为可用
		this.father.jtfPort.setEnabled(!false);;//将用于输入端口号的文本框设为可用
		this.father.jtfNickName.setEnabled(!false);//将用于输入昵称的文本框设为可用
		this.father.jbConnect.setEnabled(!false);//将"连接"按钮设为可用
		this.father.jbDisconnect.setEnabled(!true);//将"断开"按钮设为不可用
		this.father.jbChallenge.setEnabled(!true);//将"挑战"按钮设为不可用
		this.father.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
		this.father.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
		this.father.jbFail.setEnabled(false);//将"认输"按钮设为不可用
		this.flag=false;//终止该客户端代理线程
		father.cat=null;
		JOptionPane.showMessageDialog(this.father,"服务器停止!!!","提示",
		           JOptionPane.INFORMATION_MESSAGE);//给出服务器离开的提示信息
	}
	public void tiao_zhan(String msg){
		try{
			String name=msg.substring(13);//获得挑战者的昵称
			if(this.challenger==null){//如果玩家空闲
				challenger=msg.substring(13);//将challenger的值赋为挑战者的昵称
				this.father.jtfHost.setEnabled(false);//将用于输入主机名的文本框设为不可用
				this.father.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
				this.father.jtfNickName.setEnabled(false);//将用于输入昵称的文本框设为不可用
				this.father.jbConnect.setEnabled(false);//将"连接"按钮设为不可用
				this.father.jbDisconnect.setEnabled(false);//将"断开"按钮设为不可用
				this.father.jbChallenge.setEnabled(false);//将"挑战"按钮设为不可用
				this.father.jbYChallenge.setEnabled(true);//将"接受挑战"按钮设为可用
				this.father.jbNChallenge.setEnabled(true);//将"拒绝挑战"按钮设为可用
				this.father.jbFail.setEnabled(false);//将"认输"按钮设为不可用
				JOptionPane.showMessageDialog(this.father,challenger+"向你挑战!!!",
				           "提示",JOptionPane.INFORMATION_MESSAGE);//给出挑战信息
			}
			else{//如果该玩家忙碌中 ,则返回一个<#BUSY#>开头的信息
				this.dout.writeUTF("<#BUSY#>"+name);
			}
		}
		catch(IOException e){e.printStackTrace();}
	}
	public void tong_yi(){
		this.father.jtfHost.setEnabled(false);//将用于输入主机名的文本框设为不可用
		this.father.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
		this.father.jtfNickName.setEnabled(false);//将用于输入昵称的文本框设为不可用
		this.father.jbConnect.setEnabled(false);//将"连接"按钮设为不可用
		this.father.jbDisconnect.setEnabled(!true);//将"断开"按钮设为不可用
		this.father.jbChallenge.setEnabled(!true);//将"挑战"按钮设为不可用
		this.father.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
		this.father.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
		this.father.jbFail.setEnabled(!false);//将"认输"按钮设为不可用
		this.father.jbChat.setEnabled(true);
		this.father.jtfChat.setEditable(true);
		JOptionPane.showMessageDialog(this.father,"对方接受您的挑战!对方先走棋(红棋)",
		                           "提示",JOptionPane.INFORMATION_MESSAGE);
	}
	public void butong_yi(){
		this.father.jtfHost.setEnabled(false);//将用于输入主机名的文本框设为不可用
		this.father.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
		this.father.jtfNickName.setEnabled(false);//将用于输入昵称的文本框设为不可用
		this.father.jbConnect.setEnabled(false);//将"连接"按钮设为不可用
		this.father.jbDisconnect.setEnabled(true);//将"断开"按钮设为可用
		this.father.jbChallenge.setEnabled(true);//将"挑战"按钮设为可用
		this.father.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
		this.father.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
		this.father.jbFail.setEnabled(false);//将"认输"按钮设为不可用
		this.father.jbChat.setEnabled(false);
		this.father.WHO=3;
		JOptionPane.showMessageDialog(this.father,"对方拒绝您的挑战!","提示",
		            JOptionPane.INFORMATION_MESSAGE);//给出对方拒绝挑战的提示信息
		this.challenger=null;
	}
	public void busy(){
		this.father.jtfHost.setEnabled(false);//将用于输入主机名的文本框设为不可用
		this.father.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
		this.father.jtfNickName.setEnabled(false);//将用于输入昵称的文本框设为不可用
		this.father.jbConnect.setEnabled(false);//将"连接"按钮设为不可用
		this.father.jbDisconnect.setEnabled(true);//将"断开"按钮设为可用
		this.father.jbChallenge.setEnabled(true);//将"挑战"按钮设为可用
		this.father.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
		this.father.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
		this.father.jbFail.setEnabled(false);//将"认输"按钮设为不可用
		JOptionPane.showMessageDialog(this.father,"对方忙碌中!!!","提示",
		            JOptionPane.INFORMATION_MESSAGE);//给出对方忙碌的提示信息
		this.challenger=null;
	}
	public void move(String msg){
		int length=msg.length();
		int startI=Integer.parseInt(msg.substring(length-4,length-3));//获得棋子的原始位置
		int startJ=Integer.parseInt(msg.substring(length-3,length-2));
		int endI=Integer.parseInt(msg.substring(length-2,length-1));//获得走后的位置
		int endJ=Integer.parseInt(msg.substring(length-1));
		this.father.EndMove(startI, startJ, endI, endJ);
		if(this.father.WHO==3){
			this.father.WHO=1;
			this.father.time[0].spTime();
			this.father.time[1].stTime();
		}else if(this.father.WHO==4){
			this.father.WHO=2;
			this.father.time[1].spTime();
			this.father.time[0].stTime();
		}
	}
	public void renshu(){
		JOptionPane.showMessageDialog(this.father,"恭喜你,你获胜,对方认输","提示",
		             JOptionPane.INFORMATION_MESSAGE);//给出获胜信息
		this.challenger=null;//将挑战者设为空
		pcNext();
	}
	public void victory(){
		JOptionPane.showMessageDialog(this.father,"不好意思您输了","提示",
	             JOptionPane.INFORMATION_MESSAGE);//给出获胜信息
		pcNext();
	}
	public void pcNext(){
		this.father.initialChess();
		this.father.time[0].initime();
		this.father.time[1].initime();
		this.father.jtfHost.setEnabled(false);//将用于输入主机名的文本框设为不可用
		this.father.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
		this.father.jtfNickName.setEnabled(false);//将用于输入昵称的文本框设为不可用
		this.father.jbConnect.setEnabled(false);//将"连接"按钮设为不可用
		this.father.jbDisconnect.setEnabled(true);//将"断开"按钮设为可用
		this.father.jbChallenge.setEnabled(true);//将"挑战"按钮设为可用
		this.father.jbYChallenge.setEnabled(false);//将"接受挑战"按钮设为不可用
		this.father.jbNChallenge.setEnabled(false);//将"拒绝挑战"按钮设为不可用
		this.father.jbFail.setEnabled(false);//将"认输"按钮设为不可用
	}
}
Help.java
package chessc;

import java.awt.CardLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;

public class Help extends JFrame{
	//顶级
	DefaultMutableTreeNode helpRoot = new DefaultMutableTreeNode(new myNode("Caeser--中国象棋","0"));
	//一级
	DefaultMutableTreeNode helpt1 = new DefaultMutableTreeNode(new myNode("中国象棋简介","1"));
	DefaultMutableTreeNode helpt2 = new DefaultMutableTreeNode(new myNode("人人同机","2"));
	DefaultMutableTreeNode helpt3 = new DefaultMutableTreeNode(new myNode("人机博弈","3"));
	DefaultMutableTreeNode helpt4 = new DefaultMutableTreeNode(new myNode("局域网对战","4"));
	//二级
	DefaultMutableTreeNode helpt2_1 = new DefaultMutableTreeNode(new myNode("棋局初始化","5"));
	DefaultMutableTreeNode helpt2_2 = new DefaultMutableTreeNode(new myNode("鼠标点击事件","6"));
	DefaultMutableTreeNode helpt4_1 = new DefaultMutableTreeNode(new myNode("服务器","7"));
	DefaultMutableTreeNode helpt4_2 = new DefaultMutableTreeNode(new myNode("客户端","8"));
	//三级
	DefaultMutableTreeNode helpt2_1_1 = new DefaultMutableTreeNode(new myNode("加载图片","9"));
	DefaultMutableTreeNode helpt2_1_2 = new DefaultMutableTreeNode(new myNode("初始化二维数组","10"));
	DefaultMutableTreeNode helpt2_1_3 = new DefaultMutableTreeNode(new myNode("初始化时间面板","11"));
	//构建树
	JTree helpt=new JTree(helpRoot);
	JLabel jlarray[]={new JLabel("Caeser--中国象棋"),new JLabel("起源介绍"),new JLabel("人人同机"),new JLabel("人机博弈"),new JLabel("局域网对战"),new JLabel("初始化"),new JLabel("行棋"),new JLabel("服务器"),new JLabel("客户端"),new JLabel("图片"),new JLabel("2维数组"),new JLabel("倒计时")};
	JTextArea jtarray[]={new JTextArea("语言:Java\n开发工具:Eclipse MARS.1\n参考书:[亮剑Java项目开发案例导航].王寅乐\n代码级别:2500\n本次开发主要是为了学习多线程以及Socket相关知识,开发用时5天,修改代码花了两天,对一些不是很严谨的代码结构,做出调整,介绍一下,本象棋如何使用,点击菜单栏里的局域网对战,就会弹出服务器窗口,选择好端口号,启动服务器,其他人选择好IP地址和相应端口进行连接,人机博弈,思索了很久,觉得将棋局转换成算法还是有一定难度的,所以就不打算开发了,之前也看到了两份成型的算分都有些复杂,我不是很理解。\n\n\t\tCaeser\t2016/2/22"),new JTextArea("中国象棋是起源于中国的一种棋戏,属于二人对抗性游戏的一种,在中国有着悠久的历史。由于用具简单,趣味性强,成为流行极为广泛的棋艺活动。\n中国象棋中华民族的文化瑰宝,它源远流长,趣味浓厚,基本规则简明易懂,千百年来长盛不衰。中国象棋是模拟的古代战争、直线战争、陆地战争、平面战争。在中国古代,象棋被列为士大夫们的修身之艺。现在,则被视为是怡神益智的一种有益身心的活动。象棋集文化、科学、艺术、竞技于一身,不但可以开发智力,启迪思维,锻炼辨证分析能力和培养顽强的意志,而且可以修心养性,陶冶情操,丰富文化生活,深受广大群众的喜爱。古今中外男女老少皆宜,由于用具简单,趣味性强,大街小巷常常可见纹枰对弈的象棋爱好者。\n 象棋使用方形格状棋盘及红黑二色圆形棋子进行对弈,棋盘上有十条横线、九条竖线共分成90个交叉点;象棋的棋子共有32个,每种颜色16个棋子,分为7个兵种,摆放和活动在交叉点上。双方交替行棋,先把对方的将(帅)“将死”的一方获胜。在中国,已有几千年历史、充满东方智慧的象棋在中国的群众基础远远超过围棋,一直是普及最广的棋类项目。"),new JTextArea("人人同机则是在一台电脑上,由两个人轮流下棋,这个符合在校老师给出的实训题目,只不过我使用了Java语言,老师当时要求是使用C++完成的,我当时也是用C++完成,写有规则,即马走日,象走田,兵卒只能向前不能后退,过河后可以左右走,炮需要隔子吃,走法和車一样直线任意格,士只能斜着走,将和帅只能在九宫格里"),new JTextArea("人机博弈,是将现有数组转换成PEN串,再根据置换表判断,走哪一步值得,其中对算法的思考很有帮助,但是我并没有做出来,我得到人机博弈算法是从一个叫“蒋鹏”的人写的代码看到的,但是我并没有看懂所以,这里的人机博弈仅仅是空项目。"),new JTextArea("局域网对战,是本次写代码的核心,Socket稍微懂了一点,还有多线程的使用也会了一点,但对局域网的通信方式还不是很明确,对Java的Thread,runnable有了一定的认识,会使用多线程配合套接字完成局域网象棋,知道文字是如何传递和接收,那么文件也是同理的。"),new JTextArea("定义有10*9的二维数组,初始化的时候,将棋子摆放正确,0-15为黑色方,16-31为红色方,如下所示:\n[0]    [1]    [2]    [3]    [4]    [5]    [6]    [7]    [8]\n[-1]    [9]    [-1]  [-1]  [-1]  [-1]  [-1]  [10]  [-1]\n[11]  [-1]  [12]  [-1]  [13]  [-1]  [14]  [-1]  [15]\n[-1]   [-1]   [-1]   [-1]   [-1]   [-1]   [-1]   [-1]   [-1]\n[-1]   [-1]   [-1]   [-1]   [-1]   [-1]   [-1]   [-1]   [-1]\n[27]  [-1]  [28]  [-1]  [29]  [-1]  [30]  [-1]  [31]\n[-1]  [25]  [-1]    [-1]  [-1]  [-1]  [-1]  [26]  [-1]\n[16] [17] [18]  [19]  [20]  [21] [22] [23] [24]"),new JTextArea("对鼠标点击事件我分为两种情况考虑:\n第一种:黑色方行棋\n设置FLAG对WHO为1进行判断\n(1)点击自己棋子后才可以解锁行棋部分代码,解锁的意思就是将变量std1赋值为true。(2)只有解锁后才可以执行(2),点击棋盘,行棋或者点击对方棋子,找到对方棋子让棋子消失\n第二种情况与第一种情况类似"),new JTextArea("服务器只启动端口,然后等待客户端连接,一旦连接上就会产生阻塞,然后传递消息,刷新服务器列表"),new JTextArea("客户端就是连接服务器,然后等待信息传递"),new JTextArea("初始化的时候先给JLabel添加图片,除了32张棋子图片,还有棋盘和两个选中标志,棋子的移动就是图片的坐标发生改变,吃子就是让被吃的子消失"),new JTextArea("我采用的二维数组是9*10的二维数组且与人们的横纵坐标轴一致,我使用的规则判断与实际相反,需要注意转换,使用二维数组之后,行棋和规则判断就全凭借这个数组,问题就得到简化"),new JTextArea("时间面板定义了另一个类,那个类里有一个返回值为JPanel的函数,使用了Timer这个包,倒计时1800秒,一旦时间少于2秒就判断失败")};
	JPanel jplarray[]={new JPanel(),new JPanel(),new JPanel(),new JPanel(),new JPanel(),new JPanel(),new JPanel(),new JPanel(),new JPanel(),new JPanel(),new JPanel(),new JPanel()};
	JPanel jplTree=new JPanel();
	JPanel jplCard=new JPanel();
	CardLayout card=new CardLayout();
	JScrollPane jspx=new JScrollPane(jplCard);
	JSplitPane jspz=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,jplTree,jspx);//创建JSplitPane对象
	Chess father;
	public Help(Chess p1){
		father=p1;
		initTree();
		initComponent();
		addListener();
		initFrame();
	}
	public void initComponent(){//添加、初始化控件
		jplCard.setLayout(card);
		jspz.setDividerLocation(200);
		jspz.setDividerSize(4);//设置分割线的位置和宽度
		this.add(jspz);
		jplTree.setLayout(null);
		helpt.setBounds(0, 0, 200, 500);
		helpt.setToggleClickCount(1);//鼠标单击次数为1
		jplTree.add(helpt);
		initArea();
	}
	public void initTree(){
		this.helpt2_1.add(helpt2_1_1);
		this.helpt2_1.add(helpt2_1_2);
		this.helpt2_1.add(helpt2_1_3);
		this.helpt2.add(helpt2_1);
		this.helpt2.add(helpt2_2);
		this.helpt4.add(helpt4_1);
		this.helpt4.add(helpt4_2);
		this.helpRoot.add(helpt1);
		this.helpRoot.add(helpt2);
		this.helpRoot.add(helpt3);
		this.helpRoot.add(helpt4);
	}
	public void initArea(){
		for(int i=0;i<12;i++){
			jplarray[i].setLayout(null);
			jlarray[i].setBounds(10, 0, 200, 50);
			jtarray[i].setBounds(10, 60, 400, 380);
			jtarray[i].setEditable(false);
			jtarray[i].setLineWrap(true);
			jtarray[i].setWrapStyleWord(true);
			jplarray[i].add(jlarray[i]);
			jplarray[i].add(jtarray[i]);
			jplCard.add(jplarray[i],""+i);
		}
	}
	public void initFrame(){//初始化窗口
		this.setTitle("中国象棋--帮助");
		this.setBounds(700,0,650,500);//设置窗体大小
		this.setVisible(true);//设置可见性
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
	}
	public void addListener(){
		helpt.addMouseListener(
				new MouseAdapter(){
					public void mouseClicked(MouseEvent e){
						
						DefaultMutableTreeNode htemp=(DefaultMutableTreeNode)helpt.getLastSelectedPathComponent();
						myNode node=(myNode)htemp.getUserObject();
						String id=node.getId();
						if(id.equals("0")){
							card.show(jplCard, "0");
						}else if(id.equals("1")){
							card.show(jplCard, "1");
						}else if(id.equals("2")){
							card.show(jplCard, "2");
						}else if(id.equals("3")){
							card.show(jplCard, "3");
						}else if(id.equals("4")){
							card.show(jplCard, "4");
						}else if(id.equals("5")){
							card.show(jplCard, "5");
						}else if(id.equals("6")){
							card.show(jplCard, "6");
						}else if(id.equals("7")){
							card.show(jplCard, "7");
						}else if(id.equals("8")){
							card.show(jplCard, "8");
						}else if(id.equals("9")){
							card.show(jplCard, "9");
						}else if(id.equals("10")){
							card.show(jplCard, "10");
						}else if(id.equals("11")){
							card.show(jplCard, "11");
						}
					}
				}
	);}
	public class myNode{
		String values,id;
		public myNode(String p1,String p2){
			values=p1;
			id=p2;
		}
		public String toString(){return values;}
		public String getId(){return id;}
	}
	/*public static void main(String args[]){
		new Help();
	}*/
}
Rules.java
package chessc;

public class Rules {
	int array[][];
	boolean ifMove = true;
	boolean can = true;
	int maxI;// 定义一些辅助变量
	int minI;
	int maxJ;
	int minJ;
	int i;
	int j;

	public Rules(int p[][]) {
		array = p;
	}

	public boolean ifMove(int startI, int startJ, int endI, int endJ, int name) {
		ifMove = true;
		if (startI >= endI)// 确定其实坐标的大小关系
		{
			maxI = startI;
			minI = endI;
		} else// 确定maxI和minI
		{
			maxI = endI;
			minI = startI;
		}
		if (startJ >= endJ)// 确定endJ和startJ
		{
			maxJ = startJ;
			minJ = endJ;
		} else {
			maxJ = endJ;
			minJ = startJ;
		}
		if (name == 0 || name == 8 || name == 16 || name == 24) {// 車
			car(maxI, minI, maxJ, minJ);
		} else if (name == 1 || name == 7 || name == 17 || name == 23) {// 马
			horse(maxI, minI, maxJ, minJ, startI, startJ, endI, endJ);
		} else if (name == 18 || name == 22) {// 红象1
			elephant1(maxI, minI, maxJ, minJ, startI, startJ, endI, endJ);
		} else if (name == 3 || name == 5 || name == 19 || name == 21) {// 士
			guard(maxI, minI, maxJ, minJ, startI, startJ, endI, endJ);
		} else if (name == 4 || name == 20) {// 将或帅
			king(maxI, minI, maxJ, minJ, startI, startJ, endI, endJ);
		} else if (name > 10 && name < 16) {// 卒2
			soldier2(maxI, minI, maxJ, minJ, startI, startJ, endI, endJ);
		} else if (name == 25 || name == 26 || name == 9 || name == 10) {// 炮
			cannon(maxI, minI, maxJ, minJ, startI, startJ, endI, endJ);
		} else if (name == 2 || name == 6) {// 黑象2
			elephant2(maxI, minI, maxJ, minJ, startI, startJ, endI, endJ);
		} else if (name > 26 && name < 32) {// 兵1
			soldier1(maxI, minI, maxJ, minJ, startI, startJ, endI, endJ);
		}

		return ifMove;
	}

	public void car(int maxI, int minI, int maxJ, int minJ) {
		// 对"車"的处理方法
		if (maxI == minI)// 如果在一条横线上
		{
			for (j = minJ + 1; j < maxJ; j++) {
				if (array[maxI][j] != -1)// 如果中间有棋子
				{
					ifMove = false;// 不可以走棋
					break;
				}
			}
		} else if (maxJ == minJ)// 如果在一条竖线上
		{
			for (i = minJ + 1; i < maxJ; i++) {
				if (array[i][maxJ] != -1)// 如果中间有棋子
				{
					ifMove = false;// 不可以走棋
					break;
				}
			}
		} else if (maxI != minI && maxJ != minJ)// 如果不在同一条线上
		{
			ifMove = false;// 不可以走棋
		}
	}

	public void horse(int maxI, int minI, int maxJ, int minJ, int startI, int startJ, int endI, int endJ) {
		// 对"馬"的处理方法
		int a = maxI - minI;
		int b = maxJ - minJ;// 获得两坐标点之间的差
		if (a == 1 && b == 2)// 如果是竖着的"日"字
		{
			if (startJ > endJ)// 如果是从下向上走
			{
				if (array[startI][startJ - 1] != -1)// 如果马腿处有棋子
				{
					ifMove = false;// 不可以走
				}
			} else {// 如果是从上往下走
				if (array[startI][startJ + 1] != -1)// 如果马腿处有棋子
				{
					ifMove = false;// 不可以走
				}
			}
		} else if (a == 2 && b == 1)// 如果是横着的"日"
		{
			if (startI > endI)// 如果是从右往左走
			{
				if (array[startI - 1][startJ] != -1)// 如果马腿处有棋子
				{
					ifMove = false;// 不可以走
				}
			} else {// 如果是从左往右走
				if (array[startI + 1][startJ] != -1)// 如果马腿处有棋子
				{
					ifMove = false;// 不可以走
				}
			}
		} else if (!((a == 2 && b == 1) || (a == 1 && b == 2)))// 如果不时"日"字
		{
			ifMove = false;// 不可以走
		}
	}

	public void elephant1(int maxI, int minI, int maxJ, int minJ, int startI, int startJ, int endI, int endJ) {
		// 对"相"的处理
		int a = maxI - minI;
		int b = maxJ - minJ;// 获得X,Y坐标的差
		if (a == 2 && b == 2)// 如果是"田"字
		{
			if (endJ > 4)// 如果过河了
			{
				ifMove = false;// 不可以走
			}
			if (array[(maxI + minI) / 2][(maxJ + minJ) / 2] != -1)// 如果"田"字中间有棋子
			{
				ifMove = false;// 不可以走
			}
		} else {
			ifMove = false;// 如果不是"田"字,不可以走
		}
	}

	public void elephant2(int maxI, int minI, int maxJ, int minJ, int startI, int startJ, int endI, int endJ) {
		// 对"象"的处理
		int a = maxI - minI;
		int b = maxJ - minJ;// 获得X,Y坐标的差
		if (a == 2 && b == 2)// 如果是"田"字
		{
			if (endJ < 5)// 如果过河了
			{
				ifMove = false;// 不可以走
			}
			if (array[(maxI + minI) / 2][(maxJ + minJ) / 2] != -1)// 如果"田"字中间有棋子
			{
				ifMove = false;// 不可以走
			}
		} else {
			ifMove = false;// 如果不是"田"字,不可以走
		}
	}

	public void guard(int maxI, int minI, int maxJ, int minJ, int startI, int startJ, int endI, int endJ) {
		int a = maxI - minI;
		int b = maxJ - minJ;// 获得X,Y坐标的差
		if (a == 1 && b == 1)// 如果是小斜线
		{
			if (startJ > 4)// 如果是下方的士
			{
				if (endJ < 7) {
					ifMove = false;// 如果下方的士越界,不可以走
				}
			} else {// 如果是上方的仕
				if (endJ > 2) {
					ifMove = false;// 如果上方的仕越界,不可以走
				}
			}
			if (endI > 5 || endI < 3)// 如果左右越界,则不可以走
			{
				ifMove = false;
			}
		} else {// 如果不时小斜线
			ifMove = false;// 不可以走
		}
	}

	public void king(int maxI, int minI, int maxJ, int minJ, int startI, int startJ, int endI, int endJ) {
		// 对"帥"、"將"的处理
		int a = maxI - minI;
		int b = maxJ - minJ;// 获得X,Y坐标的差
		if ((a == 1 && b == 0) || (a == 0 && b == 1)) {// 如果走的是一小格
			if (startJ > 4)// 如果是下方的将
			{
				if (endJ < 7)// 如果越界
				{
					ifMove = false;// 不可以走
				}
			} else {// 如果是上方的将
				if (endJ > 2)// 如果越界
				{
					ifMove = false;// 不可以走
				}
			}
			if (endI > 5 || endI < 3)// 如果左右越界,不可以走
			{
				ifMove = false;
			}
		} else {// 如果走的不是一格,不可以走
			ifMove = false;
		}
	}

	public void soldier1(int maxI, int minI, int maxJ, int minJ, int startI, int startJ, int endI, int endJ) {
		// 对"兵"的处理
		if (startJ < 5)// 如果还没有过河
		{
			if (startI != endI)// 如果不是向前走
			{
				ifMove = false;// 不可以走
			}
			if (endJ - startJ != 1)// 如果走的不是一格
			{
				ifMove = false;// 不可以走
			}
		} else {// 如果已经过河
			if (startI == endI) {// 如果走的是竖线
				if (endJ - startJ != 1)// 如果走的不是一格
				{
					ifMove = false;// 不可以走
				}
			} else if (startJ == endJ) {// 如果走的是横线
				if (maxI - minI != 1) {// 如果走的不是一格
					ifMove = false;// 不可以走
				}
			} else if (startI != endI && startJ != endJ) {// 如果走的既不是竖线,也不是横线,则不可以走
				ifMove = false;
			}
		}
	}

	public void soldier2(int maxI, int minI, int maxJ, int minJ, int startI, int startJ, int endI, int endJ) {
		// 对"卒"的处理
		if (startJ > 4) {// 如果还没有过河
			if (startI != endI) {// 如果不是向前走
				ifMove = false;// 不可以走
			}
			if (endJ - startJ != -1)// 如果走的不是一格
			{
				ifMove = false;
			}
		} else {// 如果已经过河
			if (startI == endI) {// 如果走的是竖线
				if (endJ - startJ != -1) {// 如果走的不是一格
					ifMove = false;// 不可以走
				}
			} else if (startJ == endJ) {// 如果走的是横线
				if (maxI - minI != 1) {// 如果走的不是一格
					ifMove = false;// 不可以走
				}
			} else if (startI != endI && startJ != endJ) {// 如果走的既不是竖线,也不是横线,则不可以走
				ifMove = false;
			}
		}
	}

	public void cannon(int maxI, int minI, int maxJ, int minJ, int startI, int startJ, int endI, int endJ) {
		// 对"炮"、"砲"的处理
		if (maxI == minI)// 如果走的竖线
		{
			if (array[endI][endJ] != -1)// 如果终点有棋子
			{
				int count = 0;
				for (j = minJ + 1; j < maxJ; j++) {
					if (array[minI][j] != -1)// 判断起点与终点之间有几个棋子
					{
						count++;
					}
				}
				if (count != 1) {// 如果不是一个棋子
					ifMove = false;// 不可以走
				}
			} else if (array[endI][endJ] == -1)// 如果终点没有棋子
			{
				for (j = minJ + 1; j < maxJ; j++) {
					if (array[minI][j] != -1)// 如果起止点之间有棋子
					{
						ifMove = false;// 不可以走
						break;
					}
				}
			}
		} else if (maxJ == minJ)// 如果走的是横线
		{
			if (array[endI][endJ] != -1)// 如果终点有棋子
			{
				int count = 0;
				for (i = minI + 1; i < maxI; i++) {
					if (array[i][minJ] != -1)// 判断起点与终点之间有几个棋子
					{
						count++;
					}
				}
				if (count != 1)// 如果不是一个棋子
				{
					ifMove = false;// 不可以走
				}
			} else if (array[endI][endJ] == -1)// 如果终点没有棋子
			{
				for (i = minI + 1; i < maxI; i++) {
					if (array[i][minJ] != -1)// 如果起止点之间有棋子
					{
						ifMove = false;// 不可以走
						break;
					}
				}
			}
		} else if (maxJ != minJ && maxI != minI) {// 如果走的既不是竖线,也不是横线,则不可以走
			ifMove = false;
		}
	}
}

Sercer.java
package chessc;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

import java.net.*;
import java.io.*;
public class Server extends JFrame implements ActionListener
{
	JLabel jlPort=new JLabel("端 口 号");//创建提示输入端口号标签
	JTextField jtfPort=new JTextField("9999");//用于输入端口号的文本框
	JButton jbStart=new JButton("启动");//创建"启动"按钮
	JButton jbStop=new JButton("关闭");//创建"关闭"按钮
	JPanel jps=new JPanel();//创建一个JPanel对象
	JList jlUserOnline=new JList();//创建用于显示当前用户的JList
	JScrollPane jspx=new JScrollPane(jlUserOnline);//将显示当前用户的JList放在JScrollPane中
	JSplitPane jspz=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,jspx,jps);//创建JSplitPane对象
	ServerSocket ss;//声明ServerSocket引用
	ServerThread st;//声明ServerThread引用
	Vector onlineList=new Vector();//创建存放当前在线用户的Vector对象
	Chess father;
	public Server(Chess p1)
	{
		father=p1;
		this.initialComponent();//初始化控件
		this.addListener();//为相应的控件注册事件监听器
		this.initialFrame();//初始化窗体
	}
	public void initialComponent()
	{
		jps.setLayout(null);//设为空布局
		jlPort.setBounds(20,20,50,20);
		jps.add(jlPort);//添加用于提示输入端口号的标签
		this.jtfPort.setBounds(85,20,60,20);
		jps.add(this.jtfPort);//添加用于输入端口号的文本框
		this.jbStart.setBounds(18,50,60,20);
		jps.add(this.jbStart);//添加"开始"按钮
		this.jbStop.setBounds(85,50,60,20);
		jps.add(this.jbStop);//添加"关闭"按钮
		this.jbStop.setEnabled(false);//将"关闭"按钮设为不可用
	}
	public void addListener()
	{
		this.jbStart.addActionListener(this);//为"开始"按钮注册事件监听器
		this.jbStop.addActionListener(this);//为"关闭"按钮注册事件监听器
	}
	public void initialFrame()
	{
		this.setTitle("象棋--服务器端");//设置窗体标题
		this.add(jspz);//将JSplitPane添加到窗体中
		jspz.setDividerLocation(250);
		jspz.setDividerSize(4);//设置分割线的位置和宽度
		this.setBounds(20,20,420,320);
		this.setVisible(true);//设置可见性
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		this.addWindowListener(//为窗体关闭事件注册监听器
			new WindowAdapter()
			{
				public void windowClosing(WindowEvent e)
				{
					if(st==null)//当服务器线程为空时直接退出
					{
						return;
					}
					try
					{
						Vector v=onlineList;
						int size=v.size();
						for(int i=0;i<size;i++)
						{
							//当不为空时,向在线用户发送离线信息
							ServerAgentThread tempSat=(ServerAgentThread)v.get(i);
							tempSat.dout.writeUTF("<#SERVER_DOWN#>");
							tempSat.flag=false;//终止服务器代理线程
						}
						st.flag=false;//终止服务器线程
						st=null;
						ss.close();//关闭ServerSocket
						v.clear();//将在线用户列表清空
						refreshList();//刷新列表	
					}
					catch(Exception ee)
					{
						ee.printStackTrace();
					}
				}
			}
			);
	}
	public void actionPerformed(ActionEvent e)
	{
		if(e.getSource()==this.jbStart)
		{//当单击"启动"按钮时
			this.jbStart_event();
		}
		else if(e.getSource()==this.jbStop)
		{//单击"关闭"按钮后
			this.jbStop_event();
		}
	}
	public void jbStart_event()
	{
		//单击"启动"按钮的业务处理代码
		int port=0;
		try
		{
			//获得用户输入的端口号,并转化为整型
			port=Integer.parseInt(this.jtfPort.getText().trim());
		}
		catch(Exception ee)
		{//端口号不是整数,给出提示信息
			JOptionPane.showMessageDialog(this,"端口号只能是整数","错误",
			                               JOptionPane.ERROR_MESSAGE);
			return;
		}
		if(port>65535||port<0)
		{//断口号不合法,给出提示信息
			JOptionPane.showMessageDialog(this,"端口号只能是0-65535的整数","错误",
			                               JOptionPane.ERROR_MESSAGE);
			return;
		}
		try
		{
			this.jbStart.setEnabled(false);//将开始按钮设为不可用
			this.jtfPort.setEnabled(false);//将用于输入端口号的文本框设为不可用
			this.jbStop.setEnabled(true);//将停止按钮设为可用
			ss=new ServerSocket(port);//创建ServerSocket对象
			st=new ServerThread(this);//创建服务器线程
			st.start();//启动服务器线程
			//给出服务器启动成功的提示信息
			JOptionPane.showMessageDialog(this,"服务器启动成功","提示",
			                               JOptionPane.INFORMATION_MESSAGE);
		}
		catch(Exception ee)
		{
			//给出服务器启动失败的提示信息
			JOptionPane.showMessageDialog(this,"服务器启动失败","错误",
			                               JOptionPane.ERROR_MESSAGE);
			this.jbStart.setEnabled(true);//将开始按钮设为可用
			this.jtfPort.setEnabled(true);//将用于输入端口号的文本框设为可用
			this.jbStop.setEnabled(false);//将停止按钮设为不可用
		}
	}
	public void jbStop_event()
	{
		//单击"关闭"按钮的业务处理代码
		try
		{
			Vector v=onlineList;
			int size=v.size();
			for(int i=0;i<size;i++)
			{//向在线用户发送离线信息
				ServerAgentThread tempSat=(ServerAgentThread)v.get(i);
				tempSat.dout.writeUTF("<#SERVER_DOWN#>");
				tempSat.flag=false;//关闭服务器代理线程
			}
			st.flag=false;//关闭服务器线程
			st=null;
			ss.close();//关闭ServerSocket
			v.clear();//将在线用户列表清空
			refreshList();//刷新列表	
			this.jbStart.setEnabled(true);//将开始按钮设为可用
	    	this.jtfPort.setEnabled(true);//将用于输入端口号的文本框设为可用
		    this.jbStop.setEnabled(false);//将停止按钮设为不可用
		}
		catch(Exception ee)
		{
			ee.printStackTrace();
		}
	}
	public void refreshList()
	{
		//更新在线用户列表的业务处理代码
		Vector v=new Vector();
		int size=this.onlineList.size();
		for(int i=0;i<size;i++)
		{//遍历在线列表
			ServerAgentThread tempSat=(ServerAgentThread)this.onlineList.get(i);
			String temps=tempSat.sc.getInetAddress().toString();
			temps=temps+"|"+tempSat.getName();//获得所需信息
			v.add(temps);//添加到Vector中
		}
		this.jlUserOnline.setListData(v);//更新列表数据
	}
	
}
ServerAgentThread.java
package chessc;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

import java.net.*;
import java.io.*;

public class ServerAgentThread extends Thread
{
	Server father;//声明Server的引用
	Socket sc;//声明Socket的引用
	DataInputStream din;//声明数据输入流与输出流的引用
	DataOutputStream dout;
	boolean flag=true;//控制线程的标志位
	public ServerAgentThread(Server father,Socket sc)
	{
		this.father=father;
		this.sc=sc;
		try
		{
			din=new DataInputStream(sc.getInputStream());//创建数据输入流
			dout=new DataOutputStream(sc.getOutputStream());//创建数据输出流
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	public void run()
	{
		while(flag)
		{
			try
			{
				String msg=din.readUTF().trim();//接收客户端传来的信息
				if(msg.startsWith("<#NICK_NAME#>"))//收到新用户的信息
				{
					this.nick_name(msg);
				}
				else if(msg.startsWith("<#CLIENT_LEAVE#>")){//收到用户离开的信息
					this.client_leave(msg);
				}
				else if(msg.startsWith("<#TIAO_ZHAN#>")){//收到用户发出的挑战信息
					this.tiao_zhan(msg);
				}
				else if(msg.startsWith("<#TONG_YI#>")){//受到接受挑战的信息
					this.tong_yi(msg);
				}
				else if(msg.startsWith("<#BUTONG_YI#>")){//受到拒绝挑战的信息
					this.butong_yi(msg);
				}
				else if(msg.startsWith("<#BUSY#>")){//收到被挑战者忙的信息
					this.busy(msg);
				}
				else if(msg.startsWith("<#MOVE#>")){//收到走棋的信息
					this.move(msg);
				}
				else if(msg.startsWith("<#RENSHU#>")){//收到某用户认输的信息
					this.renshu(msg);
				}else if(msg.startsWith("<#CHAT#>")){//收到某用户认输的信息
					this.chat(msg);
				}else if(msg.startsWith("<#VICTOR#>")){//接收到胜利消息,给对方发送信息
					this.renshu(msg);
				}
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}
	public void nick_name(String msg)
	{
		try
		{
			String name=msg.substring(13);//获得用户的昵称
			this.setName(name);//用该昵称给该线程取名
			Vector v=father.onlineList;//获得在线用户列表
			boolean isChongMing=false;
			int size=v.size();//获得用户列表的大小
			for(int i=0;i<size;i++)
			{//遍历列表,查看是否已经有该用户名
				ServerAgentThread tempSat=(ServerAgentThread)v.get(i);
				if(tempSat.getName().equals(name))
				{
					isChongMing=true;//有重名,将标志位设为true
					break;
				}
			}
			if(isChongMing==true)//如果重名
			{
				dout.writeUTF("<#NAME_CHONGMING#>");//将重名信息发送给客户端
				din.close();//关闭数据输入流
				dout.close();//关闭数据输出流
				sc.close();//关闭Socket
				flag=false;//终止该服务器代理线程
			}
			else//如果不重名
			{
				v.add(this);//将该线程添加到在线列表
				father.refreshList();//刷新服务器在线信息列表
				String nickListMsg="";
				size=v.size();//获得在线列表大小
				for(int i=0;i<size;i++)
				{
					ServerAgentThread tempSat=(ServerAgentThread)v.get(i);
					nickListMsg=nickListMsg+"|"+tempSat.getName();
				}//将在线列表内容住组织成字符串
				nickListMsg="<#NICK_LIST#>"+nickListMsg;
				Vector tempv=father.onlineList;
				size=tempv.size();
				for(int i=0;i<size;i++)
				{//遍历在线列表
					ServerAgentThread satTemp=(ServerAgentThread)tempv.get(i);
					satTemp.dout.writeUTF(nickListMsg);//将最新的列表信息发送到各个客户端
					if(satTemp!=this)
					{//给其他客户端发送新用户上线的信息
						satTemp.dout.writeUTF("<#MSG#>"+this.getName()+"上线了...");
					}
				}
			}
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
		
	}
	public void tiao_zhan(String msg)
	{
		try
		{
			String name1=this.getName();//获得发出挑战信息用户的名字
			String name2=msg.substring(13);//获得被挑战的用户名字
			Vector v=father.onlineList;//获得在线用户列表
			int size=v.size();//获得在线用户列表的大小
			for(int i=0;i<size;i++)
			{//遍历列表,搜索被挑战的用户
				ServerAgentThread satTemp=(ServerAgentThread)v.get(i);
				if(satTemp.getName().equals(name2))
				{//向该用户发送挑战信息,附带提出挑战用户的名字
					satTemp.dout.writeUTF("<#TIAO_ZHAN#>"+name1);
					break;
				}
			}
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
	}
	public void move(String msg){
		try{
			String name=msg.substring(8,msg.length()-4);//获得接收方的名字
			Vector v=father.onlineList;//获得在线用户列表
			int size=v.size();//获得在线用户列表的大小
			for(int i=0;i<size;i++){//遍历列表,搜索接收方
				ServerAgentThread satTemp=(ServerAgentThread)v.get(i);
				if(satTemp.getName().equals(name)){//将该信息转发给接收方
					satTemp.dout.writeUTF(msg);
					break;
				}
			}
		}
		catch(IOException e){e.printStackTrace();}
	}
	public void chat(String msg){
		try{
			
			//String msgTp=msg;
			int length=msg.length();
			int chat=Integer.parseInt(msg.substring(length-1));
			//msgTp=msgTp.substring(0,length-1);
			msg=msg.substring(0,length-1);
			length--;
			//System.out.println(msg);
			//System.out.println(msgTp);
			String name=msg.substring(8, 8+chat);
			msg="<#CHAT#>"+msg.substring(8+chat);
			Vector v=father.onlineList;//获得在线用户列表
			int size=v.size();//获得在线用户列表的大小
			for(int i=0;i<size;i++){//遍历列表,搜索接收方
				ServerAgentThread satTemp=(ServerAgentThread)v.get(i);
				if(satTemp.getName().equals(name)){//将该信息转发给接收方
					satTemp.dout.writeUTF(msg);
					break;
				}
			}
		}catch(IOException e){e.printStackTrace();}
	}
	public void tong_yi(String msg){
		try{
			String name=msg.substring(11);//获得提出挑战的用户的名字
			Vector v=father.onlineList;//获得在线用户列表
			int size=v.size();//获得在线用户列表的大小
			for(int i=0;i<size;i++){//遍历列表,搜索提出挑战的用户
				ServerAgentThread satTemp=(ServerAgentThread)v.get(i);
				if(satTemp.getName().equals(name)){//向该用户发送对方接受挑战的信息
					satTemp.dout.writeUTF("<#TONG_YI#>");
					break;
				}
			}
		}
		catch(Exception e){e.printStackTrace();}
	}
	public void renshu(String msg){
		try{
			String name=msg.substring(10);//获得接收方的名字
			Vector v=father.onlineList;//获得在线用户列表
			int size=v.size();//获得在线用户列表的大小
			for(int i=0;i<size;i++){//遍历列表,搜索接收方
				ServerAgentThread satTemp=(ServerAgentThread)v.get(i);
				if(satTemp.getName().equals(name)){//将该信息转发给接收方
					satTemp.dout.writeUTF(msg);
					break;
				}
			}
		}
		catch(IOException e){e.printStackTrace();}
	}
	public void busy(String msg){
		try{
			String name=msg.substring(8);//获得提出挑战的用户的名字
			Vector v=father.onlineList;//获得在线用户列表
			int size=v.size();//获得在线用户列表的大小
			for(int i=0;i<size;i++){//遍历列表,搜索提出挑战的用户
				ServerAgentThread satTemp=(ServerAgentThread)v.get(i);
				if(satTemp.getName().equals(name)){//向该用户发送对方正在忙的信息
					satTemp.dout.writeUTF("<#BUSY#>");
					break;
				}
			}
		}
		catch(IOException e){e.printStackTrace();}
	}
	public void butong_yi(String msg){
		try{
			String name=msg.substring(13);//获得提出挑战的用户的名字
			Vector v=father.onlineList;//获得在线用户列表
			int size=v.size();//获得在线用户列表的大小
			for(int i=0;i<size;i++)
			{//遍历列表,搜索提出挑战的用户
				ServerAgentThread satTemp=(ServerAgentThread)v.get(i);
				if(satTemp.getName().equals(name)){//向该用户发送对方拒绝挑战的信息
					satTemp.dout.writeUTF("<#BUTONG_YI#>");
					break;
				}
			}
		}
		catch(IOException e){e.printStackTrace();}
	}
	public void client_leave(String msg){
		try{
			Vector tempv=father.onlineList;//获得在线列表
			tempv.remove(this);//移除该用户
			int size=tempv.size();
			String nl="<#NICK_LIST#>";
			for(int i=0;i<size;i++){//遍历在线列表
				ServerAgentThread satTemp=(ServerAgentThread)tempv.get(i);
				//向各个客户端发送用户离线信息
				satTemp.dout.writeUTF("<#MSG#>"+this.getName()+"离线了...");
				//组织信息的在线用户列表
				nl=nl+"|"+satTemp.getName();
			}
			for(int i=0;i<size;i++){//将最新的列表信息发送到各个客户端
				ServerAgentThread satTemp=(ServerAgentThread)tempv.get(i);
				satTemp.dout.writeUTF(nl);
			}
			this.flag=false;//终止该服务器代理线程
			father.refreshList();//更新服务器在线用户列表
		}
		catch(IOException e){e.printStackTrace();}
	}
	
}
ServerThread.java
package chessc;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.net.*;
import java.io.*;
public class ServerThread extends Thread
{
	Server father; //声明Server的引用
	ServerSocket ss;//声明ServerSocket的引用
	boolean flag=true;
	public ServerThread(Server father)
	{//构造器
		this.father=father;
		ss=father.ss;
	}
	public void run()
	{
		while(flag)
		{
			try
			{
				Socket sc=ss.accept();//等待客户端连接
				ServerAgentThread sat=new ServerAgentThread(father,sc);
				sat.start();//创建并启动服务器代理线程
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}
}
TimeController.java
package chessc;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class TimeController  implements ActionListener {

	int tp=0;
	boolean flag=true;
    Timer tmr;
	JLabel jlTime;
	JPanel panel = new JPanel();
	public TimeController() {
		initComponents();
		this.tmr = new Timer(1000, this);
	}

	private void initComponents() {
		jlTime = new JLabel("1800");
		jlTime.setBounds(0, 0, 30, 10);
		panel.setLayout(null);
		panel.add(jlTime);
		panel.setBounds(0, 0, 200, 100);
	}
	public JPanel getPane(){
		return panel;
	}
	public void stTime(){
		if(tp==0){
			jlTime.setText("1800");
		}
		tmr.start();
	}
	public void spTime(){
		tmr.stop();
	}
	public void initime(){
		jlTime.setText("1800");
		tmr.stop();
	}
	public int getTime(){
		int tmp;
		tmp=Integer.parseInt(jlTime.getText());
		return tmp;
	}
	public void actionPerformed(ActionEvent ae) {
		
			tp = Integer.parseInt(jlTime.getText());
			tp--;
			jlTime.setText("" + tp);
			if (tp <= 0) {
				tmr.stop();
			}
	}

	/*public static void main(String[] args) {

		TimeController timeController = new TimeController();
		timeController.stTime();
	}*/

}


以上为全部代码





猜你喜欢

转载自blog.csdn.net/Caeser110/article/details/50748805