java聊天室(实训项目)

这里是我们实训的一个关于java聊天室的项目,有需要的同学可以看看,私聊功能未完善。

话不多说,直接上代码。

服务器:

package ChatRoom;

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JSplitPane;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import javax.swing.JScrollPane;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.JComboBox;
import javax.swing.JToolBar;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JLayeredPane;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JInternalFrame;
import javax.swing.JDesktopPane;
import javax.swing.border.LineBorder;
import javax.swing.UIManager;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.awt.event.ActionEvent;

public class fw {

	private JFrame frame;
	private JTextArea bt;
	private JList inline;
	private JTextField writeSth;
	private JTextField people;
	private JTextField serverDk;
	private JTextArea message2;
	private JButton clossButton;
	private JButton startButton;
	private JButton tiButton;
	private JButton setButton;
	private int max;
	private int dk;
	private boolean isStart=false;
	private ServerSocket ServerCocket;
	private JList userList;  
	private DefaultListModel listModel;
	private List userlist=new ArrayList();
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					fw window = new fw();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public fw() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setTitle("服务器");
		frame.setBounds(100, 100, 1105, 577);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(null);
		
		JLabel label = new JLabel("人数上限:");
		label.setBounds(0, 25, 90, 21);
		frame.getContentPane().add(label);
		
		JLabel label_2 = new JLabel("端口:");
		label_2.setBounds(290, 25, 54, 21);
		frame.getContentPane().add(label_2);
		
		startButton = new JButton("启动");
		startButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String maxTemp =people.getText();
				String Duanko =serverDk.getText();
				if(maxTemp.equals("")){
					JOptionPane.showMessageDialog(frame,"人数为空","警告",JOptionPane.WARNING_MESSAGE);
					return;
				}
				try{
					max=Integer.parseInt(maxTemp);
				}catch(NumberFormatException e1){
					JOptionPane.showMessageDialog(frame,"人数必须为数字","警告",JOptionPane.WARNING_MESSAGE);
				}
				if(max<=0){
					JOptionPane.showMessageDialog(frame,"人数要大于0","警告",JOptionPane.WARNING_MESSAGE);
					return;
				}
				if(max>1000){
					JOptionPane.showMessageDialog(frame,"人数已满","警告",JOptionPane.WARNING_MESSAGE);
					return;
				}
//				***************************************
				if(Duanko.equals("")){
					JOptionPane.showMessageDialog(frame,"端口为空","警告",JOptionPane.WARNING_MESSAGE);
					return;
				}
				try{
					dk=Integer.parseInt(Duanko);
				}catch(NumberFormatException e1){
					JOptionPane.showMessageDialog(frame,"端口必须为数字","警告",JOptionPane.WARNING_MESSAGE);
				}
				if(dk<=0){
					JOptionPane.showMessageDialog(frame,"端口要大于0","警告",JOptionPane.WARNING_MESSAGE);
					return;
				}
				//启动服务器
				try{
					dk=Integer.parseInt(Duanko);
					ServerCocket = new ServerSocket(dk);
					isStart=true;
				}catch(IOException e1){
					JOptionPane.showMessageDialog(frame,"启动","警告",JOptionPane.WARNING_MESSAGE);
					e1.printStackTrace();
				}
				
				OnlineThread onlineThread = new OnlineThread();
				onlineThread.start();
				
				startButton.setEnabled(false);
				clossButton.setEnabled(true);
				setButton.setEnabled(true);
				people.setEditable(false);
				serverDk.setEditable(false);
			}
		});
		startButton.setBounds(483, 21, 118, 29);
		frame.getContentPane().add(startButton);
//	关闭按钮	
		clossButton = new JButton("关闭");
		clossButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				for(User u:userlist){
					u.getWriter().println("CLOSE");
					u.getWriter().flush();
					
					try {
						u.getReader().close();
						u.getIn().close();
						u.getWriter();
						u.getOut().close();
						u.getSocket().close();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				clossButton.setEnabled(false);
				startButton.setEnabled(true);
				setButton.setEnabled(false);
				people.setEditable(true);
				serverDk.setEditable(true);
			}
		});
		clossButton.setBounds(599, 21, 118, 29);
		clossButton.setEnabled(false);
		frame.getContentPane().add(clossButton);
		
		JLabel label_4 = new JLabel("被踢用户:");
		label_4.setBounds(782, 61, 90, 21);
		frame.getContentPane().add(label_4);
		
		bt = new JTextArea();
		bt.setBounds(874, 58, 96, 27);
		frame.getContentPane().add(bt);
		bt.setColumns(10);
		
		tiButton = new JButton("踢");
		tiButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String outName = bt.getText();
				if(!outName.equals("")) {
					listModel.removeElement(outName);//从在线列表中踢出
					OutputStream out;
					PrintWriter write;										
					try {
						for(User users:userlist) {//列遍每一个用户找到被踢用户,提出集合					
							if(users.getName().equals(outName)) {						
								String info_send = "ti@"+users.getName();		
								out =users.getSocket().getOutputStream();
								write = new PrintWriter(out);
								write.println(info_send);将信息写进字符缓冲区
								write.flush();//刷新该流的缓冲
//								bt.removeAll();
								users.interrupt();	
								for(User u:userlist) {//转发当前踢出消息到其他用户
									u.getWriter().println("out@"+outName);
									u.getWriter().flush();
								}
								message2.append("服务器:"+outName+"已被踢出聊天室\n");
								JOptionPane.showMessageDialog(null,outName+"已被踢出群聊", "服务器", JOptionPane.INFORMATION_MESSAGE);																
							}else {
								String info_send = "OFFLINE@"+outName;	
								out = users.getSocket().getOutputStream();
								write = new PrintWriter(out);
								write.println(info_send);将信息写进字符缓冲区
								write.flush();//刷新该流的缓冲
							}
						}
					} catch (IOException e1) {
								// TODO 自动生成的 catch 块
								e1.printStackTrace();
							}//返回此套接字的输出流。
					
				}else {
					JOptionPane.showMessageDialog(null,"请选择被踢用户", "服务器", JOptionPane.INFORMATION_MESSAGE);
				}
			}
		});
		tiButton.setBounds(978, 57, 51, 29);
		frame.getContentPane().add(tiButton);
		
		JLabel label_5 = new JLabel("未完待续……");
		label_5.setBounds(862, 230, 128, 21);
		frame.getContentPane().add(label_5);
		
		listModel = new DefaultListModel();  
		inline = new JList(listModel);
		inline.setBounds(20, 91, 179, 300);
		frame.getContentPane().add(inline);
		
		
		JPanel panel_4 = new JPanel();
		panel_4.setBorder(new TitledBorder(null, "在线用户", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_4.setBounds(10, 69, 197, 335);
		frame.getContentPane().add(panel_4);
		
		writeSth = new JTextField();
		writeSth.setBounds(20, 444, 568, 43);
		writeSth.setText(null);
		frame.getContentPane().add(writeSth);
		writeSth.setColumns(10);
		
		setButton = new JButton("发送");
		setButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String message = writeSth.getText();
				for(User u:userlist){
					u.getWriter().println("ALL@SERVER@"+message);
					u.getWriter().flush();
				}
				message2.append("客服:"+message+"\n");
				writeSth.setText(null);
				setButton.setEnabled(true);
			}
		});
		setButton.setBounds(594, 444, 123, 43);
		setButton.setEnabled(false);
		frame.getContentPane().add(setButton);
		
		people = new JTextField();
		people.setText("2");
		people.setBounds(84, 22, 96, 27);
		frame.getContentPane().add(people);
		people.setColumns(10);
		
		serverDk = new JTextField();
		serverDk.setText("6666");
		serverDk.setBounds(335, 22, 96, 27);
		frame.getContentPane().add(serverDk);
		serverDk.setColumns(10);
		
		message2 = new JTextArea();
		message2.getText();
		message2.setBounds(268, 99, 433, 284);
		frame.getContentPane().add(message2);
		message2.setEditable(false);
		message2.setColumns(10);
		
		JPanel panel_1 = new JPanel();
		panel_1.setBorder(new TitledBorder(null, "消息显示框", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_1.setBounds(249, 69, 468, 322);
		frame.getContentPane().add(panel_1);
		
		JPanel panel = new JPanel();
		panel.setBorder(new TitledBorder(null, "服务器功能操作", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel.setBounds(762, 25, 306, 481);
		frame.getContentPane().add(panel);
		
		JPanel panel_2 = new JPanel();
		panel_2.setBorder(new TitledBorder(null, "写消息", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_2.setBounds(0, 419, 740, 76);
		frame.getContentPane().add(panel_2);
	}
	//建立线程处理客户端上线请求
	public class OnlineThread extends Thread{
		public void run(){
			System.out.println("---------处理客户端上线请求----------");
			while(isStart){
			try{
				System.out.println("---------1----------");
				Socket socket=ServerCocket.accept();
				InputStream in = socket.getInputStream();
				BufferedReader reader = new BufferedReader(new InputStreamReader(in));
				OutputStream out = socket.getOutputStream();
				PrintWriter write = new PrintWriter(out);
				System.out.println("---------2----------");
				if(userlist.size()==max){
					System.out.println("---------3----------");
					write.println("MAX@在线人数已满");
					write.flush();
					write.close();
					out.close();
					reader.close();
					in.close();
					socket.close();
				}else{
					System.out.println("---------4----------");
					write.println("SUCCESS@连接成功@");
					write.flush();
					String info = reader.readLine();
					StringTokenizer st = new StringTokenizer(info,"@");
					String ip = st.nextToken();
					String name = st.nextToken();
					message2.append(info+"@上线\n");
					listModel.addElement(name);
					System.out.println("---------5----------"+info);
					//客户端接受线程
					
					User user = new User();
					user.setName(name);
					user.setIp(ip);
					user.setIn(in);
					user.setOut(out);
					user.setReader(reader);
					user.setWriter(write);
					user.setSocket(socket);
					ReceleThred receleThred = new ReceleThred(reader);
					receleThred.start();
					user.setReceiveThread(receleThred);
					
					userlist.add(user);
					//循环集合
					for(User users:userlist){
						if(users.getName().equals(name)){
							continue;
						}
						users.getWriter().println("ADD@"+name);
						System.out.println(name);
						users.getWriter().flush();
					}
					String onlist = "USERLIST@"+userlist.size();
					for(User us:userlist){
						onlist = onlist+"@"+us.getName();
					}
					//将信息发送给客户端
					write.println(onlist);
					write.flush();
				}
			}catch(IOException e){
				JOptionPane.showMessageDialog(frame,"上线失败","警告",JOptionPane.WARNING_MESSAGE);
				e.printStackTrace();
			}
		}
	  }
	}
	public class ReceleThred extends Thread{
		
		private BufferedReader reader;
		private PrintWriter write;
		public ReceleThred(BufferedReader reader){
			this.reader=reader;
		}
		public ReceleThred(BufferedReader reader,PrintWriter write){
			this.reader=reader;
			this.write=write;
		}
		 public void run(){
			 boolean flag = true;
			 while(flag){
				try {
				  String info=reader.readLine();
				  System.out.println("info:"+info);
//				  message2.append(name+"\n");
//				  message2.append(info+"\n");
				  StringTokenizer st = new StringTokenizer(info,"@");
				  String type = st.nextToken();
				  if(type.equals("ALL")){
					  //转发群聊
					  for(User u:userlist){
							u.getWriter().println(info);
							u.getWriter().flush();
							System.out.println(info);
						}
					  message2.append(st.nextToken()+"说:"+st.nextToken()+"\n");
				  }else if(type.equals("DELETE")){
					  //DELETE操作
					  for(User u:userlist){
							u.getWriter().println(info);
							u.getWriter().flush();
						}
					  //释放资源
					  String name = st.nextToken();
					  for(User u:userlist){
							if(u.getName().equals(name)){
								u.getReader().close();
								u.getIn().close();
								u.getWriter();
								u.getOut().close();
								u.getSocket().close();
								userlist.remove(u);
								break;
							}
						}
					  flag = false;
					  listModel.removeElement(name);
//					  listModel.removeAllElements();
					  listModel.addElement(name);
					  message2.append(name+"下线\n");
					  write.println("DELETE@"+info);
					  write.flush();
				  }
//				  for(User u1:userlist){
//						if(u1.getName().equals(info)){
//							continue;
//						}
//						u1.getWriter().println("ADD@"+info);
//						System.out.println(info);
//						u1.getWriter().flush();
//					}
			} catch (IOException e) {
				JOptionPane.showMessageDialog(frame,"发送失败","警告",JOptionPane.WARNING_MESSAGE);
				e.printStackTrace();
			} 
		 }
		}
	}
}

客户端:

package ChatRoom;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.JProgressBar;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JLayeredPane;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.rmi.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.awt.event.ActionEvent;

public class kh {

	private JFrame frame;
	private JTextField WriteQ;
	private JTextArea names;
	private JTextField serverIp;
	private JTextField duanKo;
	private JPanel panel;
	private JList inline;
	private JTextArea viewQ;
	private JPanel panel_1;
	private JPanel panel_2;
	private JButton liveButton;
	private JButton linkButton;
	private JButton setButton;
	private int dk2;
	private boolean isConn=false;
	private Socket socket;
	private OutputStream out ;
	private PrintWriter writer;
	private String name;
	private boolean flag=true;
	private BufferedReader reader;
	private InputStream in;
	private JList userList;  
	private DefaultListModel listModel;
	private List userlist=new ArrayList();

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					kh window = new kh();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public kh() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setTitle("客户端");
		frame.setBounds(100, 100, 1105, 569);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(null);
		
		JLabel label = new JLabel("姓名:");
		label.setBounds(15, 25, 81, 21);
		frame.getContentPane().add(label);
		
		JLabel lblip = new JLabel("服务器IP:");
		lblip.setBounds(237, 25, 99, 21);
		frame.getContentPane().add(lblip);
		
		JLabel label_1 = new JLabel("端口:");
		label_1.setBounds(507, 25, 81, 21);
		frame.getContentPane().add(label_1);
		
	    linkButton = new JButton("连接");
		linkButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.out.println("---------上线按钮点击----------");
				name =names.getText();
				String fuwuqi =serverIp.getText();
				String Duanko =duanKo.getText();
				String ip=fuwuqi;
				int port=Integer.parseInt(Duanko);
				try {
					 socket =new Socket(ip,port);
					 out =socket.getOutputStream();
					 writer=new PrintWriter(out);
					 in = socket.getInputStream();
					 reader = new BufferedReader(new InputStreamReader(in));
					//3.告诉服务器我是谁
					 writer.println(socket.getInetAddress().getHostAddress()+"@"+name);
					 writer.flush();
					
					//接受服务器消息
					ReceleThred receleThred = new ReceleThred(reader);
					receleThred.start();
					
//					User user = new User();
//					for(User u:userlist){
//						
//					}
					//4.按钮处理
				}catch(UnknownHostException e1){
					e1.printStackTrace();
				} catch (IOException e1) {
					// TODO: handle exception
					e1.printStackTrace();
				}
				if(name.equals("")){
					JOptionPane.showMessageDialog(frame,"姓名不能为空","警告",JOptionPane.WARNING_MESSAGE);
					return;
				}
//				****************************
				if(fuwuqi.equals("")){
					JOptionPane.showMessageDialog(frame,"服务器输入不能为空","警告",JOptionPane.WARNING_MESSAGE);
					return;
				}
//				****************************
				if(Duanko.equals("")){
					JOptionPane.showMessageDialog(frame,"端口为空","警告",JOptionPane.WARNING_MESSAGE);
					return;
				}
				try{
					dk2=Integer.parseInt(Duanko);
				}catch(NumberFormatException e2){
					JOptionPane.showMessageDialog(frame,"端口必须为数字","警告",JOptionPane.WARNING_MESSAGE);
				}
				if(dk2<=0){
					JOptionPane.showMessageDialog(frame,"端口要大于0","警告",JOptionPane.WARNING_MESSAGE);
					return;
				}
				
				linkButton.setEnabled(false);
				liveButton.setEnabled(true);
				setButton.setEnabled(true);
				names.setEditable(false);
				serverIp.setEditable(false);
				duanKo.setEditable(false);
				
			}
		});
		linkButton.setBounds(727, 21, 123, 29);
		frame.getContentPane().add(linkButton);
		
	    liveButton = new JButton("断开");
	    liveButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				//告诉服务器下线
				writer.println("DELETE@"+name);
				writer.flush();
				try{
					  writer.close();
					  out.close();
					  reader.close();
					  in.close();
					  socket.close();
					  //线程循环标志设置
					  flag=false;
					  listModel.removeAllElements();
				}catch(IOException e1){
					e1.printStackTrace();
				}
				liveButton.setEnabled(false);
				linkButton.setEnabled(true);
				setButton.setEnabled(false);
				names.setEditable(true);
				serverIp.setEditable(true);
				duanKo.setEditable(true);
			}
		});
		liveButton.setBounds(865, 21, 123, 29);
		liveButton.setEnabled(false);
		frame.getContentPane().add(liveButton);
		
		WriteQ = new JTextField();
		WriteQ.setBounds(15, 439, 776, 44);
		frame.getContentPane().add(WriteQ);
		WriteQ.setColumns(10);
		
		setButton = new JButton("发送");
		setButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				//取
				String info = WriteQ.getText();
				//写
				writer.println("ALL@"+name+"@"+info);
				writer.flush();
//				viewQ.append(name+":"+info+"\n");
				WriteQ.setText(null);
			}
		});
		setButton.setBounds(803, 439, 123, 44);
		setButton.setEnabled(false);
		frame.getContentPane().add(setButton);
		
		names = new JTextArea();
		names.setBounds(74, 23, 96, 27);
		frame.getContentPane().add(names);
		names.setColumns(10);
		
		serverIp = new JTextField();
		serverIp.setText("127.0.0.1");
		serverIp.setBounds(320, 22, 96, 27);
		frame.getContentPane().add(serverIp);
		serverIp.setColumns(10);
		
		duanKo = new JTextField();
		duanKo.setText("6666");
		duanKo.setBounds(552, 22, 96, 27);
		frame.getContentPane().add(duanKo);
		duanKo.setColumns(10);
		
		panel = new JPanel();
		panel.setBorder(new TitledBorder(null, "写消息", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel.setBounds(0, 407, 946, 91);
		frame.getContentPane().add(panel);
		
		listModel = new DefaultListModel();  
		inline = new JList(listModel);
		inline.setBounds(26, 105, 183, 279);
		frame.getContentPane().add(inline);
		
		
		viewQ = new JTextArea();
		viewQ.getText();
		viewQ.setBounds(272, 105, 736, 279);
		frame.getContentPane().add(viewQ);
		viewQ.setEditable(false);
		viewQ.setColumns(10);
		
		panel_1 = new JPanel();
		panel_1.setBorder(new TitledBorder(null, "在线用户", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_1.setBounds(0, 77, 230, 317);
		frame.getContentPane().add(panel_1);
		
		
		
		panel_2 = new JPanel();
		panel_2.setBorder(new TitledBorder(null, "消息显示区", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_2.setBounds(255, 77, 776, 317);
		frame.getContentPane().add(panel_2);
	}
	//接受服务端信息
	public class ReceleThred extends Thread{
		private BufferedReader reader;
		public ReceleThred(BufferedReader reader){
			this.reader=reader;
		}
		 public void run(){
//			 flag = true;
			 while(flag){
				try {
				  String info=reader.readLine();
//				  System.out.println("info:"+info);
//				  viewQ.append(info+"\n");
//				  listModel.addElement(name);
				  StringTokenizer st = new StringTokenizer(info,"@");
				  String type = st.nextToken();
				  if(type.equals("ALL")){
					  viewQ.append(st.nextToken()+"说:"+st.nextToken()+"\n");
				  }else if(type.equals("USERLIST")){
					  int no = Integer.parseInt(st.nextToken());
					  for(int i=0;i

 结果展示:

java聊天室(实训项目)_第1张图片

在布局时,建议大家在eclipse使用WindowBuilder插件,更快更简洁。

(注:代码可做参考,可能有许多不规范的地方,还请见谅)

你可能感兴趣的:(eclipse)