Java小程序之简易网络画板


Java小程序之简易网络画板

一、前言:
Java是一门网络编程语言,强大的网络可以让数据进行传送;今天,我们就小试牛刀,看看Java是如何进行网络传输数据的;

二、项目分析:
1、功能需求:
我们前面做个一个小项目--Java画板;现在,假设需要实现这样一个功能,打开两个画板界面,当在一个画板上画东西时,另一个画板能够显示该画板的所画的东西;即网络画板;
2、功能实现:
那么该功能如何实现呢?首先,我们得分析下,如何让我们绘制的图形信息传递到另一个画板上;假设我们绘制的图形是一条直线,绘制这条直线的信息是直线的两端点坐标(两点就可以确定一条直线),我们只需要记录该条直线的连个坐标值,把坐标值的信息发送给服务器,再让服务器转发该信息,在另一个客户端接收到这条信息后,用这条信息绘制一条直线;当然,这里只考虑了直线这一种图形;如果有正方形等其他图形该如何区分呢?这里我们可以自己定义一种协议,协议如下:
图形类型信息+图形信息
1代表直线+直线坐标
2代表正方形+正方形的坐标
......
这样,当客户端接收信息后,先可以判断图形类型,在根据图形类型绘制不同的图形

三、项目实现思路:
1、服务器搭建
2、实现服务器的数据传递
3、画板界面实现
4、画板鼠标监听
5、客户端接收数据后绘制下对应的图形

四、项目源代码:(服务器端和客户端时两个不同的人工程,类似文件压缩有解压缩)

工程结构图:

                      
服务器端:
package Server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Myserver {
	
	public ServerSocket server;
	
	public static ArrayList<ServerThread> list = new ArrayList<ServerThread>();
	
	public void startServer() {
		
		try {
			server = new ServerSocket(9090);
			System.out.println("服务器已经建立......");
			while(true){
				Socket socket =server.accept();
				System.out.println("有客户端连接进来了......");
				ServerThread st = new ServerThread(socket);
				st.start();
//				System.out.println("线程启动......");
				list.add(st);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}


package Server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;

import javax.swing.JOptionPane;

public class ServerThread extends Thread{
	
	public Socket socket;
	public DataInputStream dis ;
	public DataOutputStream dos;
	
	public ServerThread(Socket socket) {
		this.socket=socket;
	}

	public void run() {
		try {
			//获取输入输出流
			InputStream ins =socket.getInputStream();
			OutputStream ous = socket.getOutputStream();
			//将字节流包装成数据流
			dis=new DataInputStream(ins);
			dos=new DataOutputStream(ous);
			while(true){
				int value=dis.read();
//				System.out.println(value);
				//服务器转发消息
				for (int i = 0; i <Myserver.list.size(); i++) {
					ServerThread st =Myserver.list.get(i);
					if(st!=this){
						st.dos.write(value);
						st.dos.flush();
					}
					
				}
//				System.out.println("服务器已经发送消息");
			}
		}catch (SocketException e) {
			try {
				Myserver.list.remove(this);
				this.socket.close();
				System.out.println("客户端已经退出......");
//				JOptionPane.showMessageDialog(null, "客户端退出!");
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
//			e.printStackTrace();
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
	}
}

服务器端主函数
package Server;

public class ServerTest {

	public static void main(String[] args) {
		Myserver ms = new Myserver();
		ms.startServer();
	}

}

客户端

package com.huaxin.view;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JFrame;

import com.huaxin.controller.ClientControl;
public class DrawUI extends JFrame{
	
	public Socket socket;
	public Graphics2D g;
	public ClientControl control;
	
	//界面初始化的socket
	public DrawUI() {
		try {
			socket = new Socket("localhost",9090);
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	public void initFrame() {
		//设置窗体属性
		this.setTitle("网络画板");
		this.setSize(600, 500);
		this.setDefaultCloseOperation(3);
		this.setLocationRelativeTo(null);
		this.setVisible(true);
		//拿到窗体的画笔
		g = (Graphics2D)this.getGraphics();
		g.setColor(Color.RED);
		//控制器初始化
		control = new ClientControl(g,socket);
		//添加鼠标监听
		DrawListener listener = new DrawListener(control);
		this.addMouseListener(listener);
		this.addMouseMotionListener(listener);
		//控制器接收数据并处理数据
		control.receiveData();
	}

}

package com.huaxin.view;

import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import com.huaxin.controller.ClientControl;

public class DrawListener extends MouseAdapter {
	
	public int x1,y1,x2,y2,x4,y4;
	public ClientControl control;
	
	//构造函数接受控制器对象
	public DrawListener(ClientControl control) {
		this.control=control;
	}

	//监听鼠标按下事件
	public void mousePressed(MouseEvent e) {
		//获取鼠标按下的坐标值
		x1=e.getX();
		y1=e.getY();
		x4=x1;
		y4=y1;
	}
	
	//获取鼠标释放的坐标值
//	public void mouseReleased(MouseEvent e) {
//		x2=e.getX();
//		y2=e.getY();
//		//当鼠标释放的时候在该画板上绘制一条直线
//		control.g.drawLine(x4, y4, x2, y2);
//		//第一个1代表图形类型,第二个1代表画笔 粗细
//		//将直线信息通过控制器发送给服务器端
//		control.sendData(1,x4, y4, x2, y2,1);
//	}
	
	//监听鼠标拖动事件(铅笔功能)
	public void mouseDragged(MouseEvent e) {
		int x3=e.getX();
		int y3=e.getY();
		control.g.drawLine(x1, y1, x3, y3);
		control.sendData(1,x1, y1, x3, y3,1);
		x1=x3;
		y1=y3;
	}
}

package com.huaxin.controller;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ClientControl {
	
	private Socket socket;
	public int x1,y1,x2,y2,color;
	public byte type,strock;

	public Graphics2D g;
	
	public ClientControl(Graphics2D g,Socket socket) {
		this.g=g;
		this.socket=socket;
	}

	//不断接受服务器发送过来的信息
	public void receiveData(){
		new Thread(){
			public void run() {
				try {
				while(true){
						//获取输入输出流
						InputStream ins = socket.getInputStream();
						OutputStream ous=socket.getOutputStream();
						//将字节流包装成数据流
						DataInputStream dis=new DataInputStream(ins);
						DataOutputStream dos= new DataOutputStream(ous);
//						System.out.println("kehuduan kaishi dushuju。。。。。。");
						//读图形类型
						type=dis.readByte();
						
						//读坐标
						x1=dis.readInt();
						y1=dis.readInt();
						x2=dis.readInt();
						y2=dis.readInt();
						//读粗细
						strock=dis.readByte();
						//读颜色
						color=dis.readInt();
						//读完数据之后画图形
//						System.out.print("客户端接受数据:");
//						System.out.println("type:"+type+"x1:"+x1+"y1:"+y1+"x2:"+y2+"strock:"+strock+"Color:"+type);
						drawGra();
				}
				} catch (Exception e) {
//					System.out.println("kehuudan tuichu。。。。。");
					e.printStackTrace();
				}
			};
		}.start();
	}
	
	//发送图形数据给服务器
	public void sendData(int type,int x1,int y1,int x2,int y2,int strock){
		try {
			//获取输入输出流
			InputStream ins = socket.getInputStream();
			OutputStream ous=socket.getOutputStream();
			//将字节流包装成数据流
			DataInputStream	dis=new DataInputStream(ins);
			DataOutputStream dos= new DataOutputStream(ous);
			//写图形类型
			dos.writeByte(type);
			//写坐标
			dos.writeInt(x1);
			dos.writeInt(y1);
			dos.writeInt(x2);
			dos.writeInt(y2);
			//写粗细
			dos.writeByte(strock);
			//写颜色
			dos.writeInt(g.getColor().getRGB());
			dos.flush();
//			System.out.println("type:"+type+"x1:"+x1+"y1:"+y1+"x2:"+y2+"strock:"+strock+"Color:"+type);
//			System.out.println("客户端已经发送数据......");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//绘制图形
	public void drawGra() {
		g.setColor(new Color(color));
		g.setStroke(new BasicStroke(strock));
		if(type==1){
			g.drawLine(x1, y1, x2, y2);
//			System.out.println("hutu 。。。。。");
		}
	}

}


package com.huaxin.view;

public class ClientTest {
	
	public static void main(String[] args) {
		DrawUI ui = new DrawUI();
		ui.initFrame();
	}
}

五、运行结果:



六、项目总结:
1、知道了网络中的数据是如何传送和接收的;
2、对Java是一种网络编程语言有了更深的了解;
3、对Java通信等知识有了更深的认知;

我们已经领略了Java作为一门网络编程语言如何编写程序,我们可以用今天学到的知识,看看很多的游戏,可以慢慢了解其中的原理,比如网络五子棋,网络版的你画我猜等;下篇将给大家带来简易版的你画我猜小项目;敬请期待!

  • 9
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值