使用java swing和socket编程实现简单的多人聊天室

完成效果如下

客户端:


服务器端:


客户端功能:

输入服务器对应的端口,IP号,用户名(昵称),可以互相发送消息

服务器端功能:

输入端口号,启动,可以向所有客户端发送消息,IP地址自动获取。

下面是客户端界面:

package Test;
import UI.ChatRoomClientFrame;

public class ChatRoomClient {
	
	public static void main(String[] args) {
		new ChatRoomClientFrame().setVisible(true);
	}
}
客户端实现:

package UI;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Properties;

import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
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.border.TitledBorder;

public class ChatRoomClientFrame extends JFrame{
	/**
	 * 
	 */
	private static final long serialVersionUID = 7909370607161820239L;
	
	private JPanel panel;
	private JPanel northPanel;
	private JPanel southPanel;
	private JTextField port;
	private JTextField IP;
	private JTextField userName;
	private JTextArea userlist;
	private JTextArea chatRecords;
	private JScrollPane leftPanel;
	private JScrollPane rightPanel;
	private JSplitPane  centerPanel;
	private JTextField message;
	private JButton link;
	private JButton discon;
	private JButton send;
	private JPanel Jpanel;
	private JMenuBar bar;
	private JMenu file;
	private JMenuItem save;
	private JMenu format;
	private JMenuItem font;
	private JMenuItem foreGround;
	private JMenuItem backGround;
	private Font myfont;
	
	private boolean isConnect = false;
	private Socket socket;
	private DataInputStream dis;
	private DataOutputStream dos;
	private ClientThread ct;
	//private ArrayList<String> users = new ArrayList<String>();
	private String[] userstr;
	private int usersLength = 0;


	public ChatRoomClientFrame(){
		
		initServer();
		
		link.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				if(userName.getText().trim().equals("")){
					JOptionPane.showMessageDialog(null, "用户名不能为空","错误",JOptionPane.ERROR_MESSAGE);
				}else{
				
					try {
						socket = new Socket(IP.getText(),Integer.parseInt(port.getText()));
						dos = new DataOutputStream(socket.getOutputStream());
						dis = new DataInputStream(socket.getInputStream());
						
						if(socket!=null){
							port.setEditable(false);
							IP.setEditable(false);
							userName.setEditable(false);
							link.setEnabled(false);
							discon.setEnabled(true);
							
							ct = new ClientThread();
							ct.start();
							
							if(isConnect==false){
								dos.writeUTF(userName.getText()+" 进入了聊天室");
								isConnect=true;
							}
						}	
					} catch (NumberFormatException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					} catch (UnknownHostException e1) {
						e1.printStackTrace();
					} catch (IOException e1) {
						JOptionPane.showMessageDialog(null, "服务器未开启","错误",JOptionPane.ERROR_MESSAGE);
						e1.printStackTrace();
					} 
					
				}
			}
		});
		
		discon.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					if(isConnect==true){
					isConnect=false;
					dos.writeUTF(userName.getText()+" 离开了聊天室");
					userlist.setText("");
					userstr=null;
					usersLength=0;
					dos.close();
					dis.close();
					socket.close();
					chatRecords.append("\n");
					chatRecords.append("你离开了聊天室");
					chatRecords.setCaretPosition(chatRecords.getDocument().getLength());
					port.setEditable(true);
					IP.setEditable(true);
					userName.setEditable(true);
					link.setEnabled(true);
					discon.setEnabled(false);
					ct.stop();
					}
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		
		send.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				send();
			}
		});
		
		message.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				send();
			}
		});
		
		font.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				MyFontChooser mf = new MyFontChooser(chatRecords.getFont());
				 int returnValue = mf.showFontDialog(ChatRoomClientFrame.this);  
	                // 如果按下的是确定按钮  
                if (returnValue == MyFontChooser.APPROVE_OPTION) {  
                    // 获取选择的字体  
                    Font font = mf.getSelectFont();  
                    // 将字体设置到JTextArea中  
                    chatRecords.setFont(font);  
                }
			}
		});
		
		save.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				FileDialog saveFile = new FileDialog(ChatRoomClientFrame.this, "保存文件...", FileDialog.SAVE);
				saveFile.setVisible(true);
				String filePath = saveFile.getDirectory() + saveFile.getFile();
			
				try {
					FileOutputStream fos = new FileOutputStream(filePath);
					fos.write(chatRecords.getText().getBytes());
					fos.close();
					
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		
		backGround.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				Color bc = JColorChooser.showDialog(ChatRoomClientFrame.this, "选择颜色", Color.BLACK);
				chatRecords.setBackground(bc);
			}
		});
		
		foreGround.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				Color fc = JColorChooser.showDialog(ChatRoomClientFrame.this, "选择颜色", Color.BLACK);
				chatRecords.setForeground(fc);
			}
		});

		initFrame();
	}
	
	private void initServer() {
		Jpanel = new JPanel();
		Jpanel.setLayout(new BorderLayout());
		panel = new JPanel();
		panel.setLayout(new BorderLayout());
		northPanel = new JPanel();
		northPanel.setBorder(new TitledBorder("连接信息"));
		
		bar = new JMenuBar();
		file = new JMenu("记录");
		save = new JMenuItem("保存");
		format = new JMenu("格式");
		font = new JMenuItem("字体");
		foreGround = new JMenuItem("前景色");
		backGround = new JMenuItem("背景色");
		file.add(save);
		format.add(font);
		format.add(foreGround);
		format.add(backGround);
		bar.add(file);
		bar.add(format);
		Jpanel.add(bar,BorderLayout.NORTH);
		
		port = new JTextField(8);
		port.setText("8088");
		IP = new JTextField(8);
		IP.setText("192.168.24.8");
		userName = new JTextField(8);
		link= new JButton("启动");
		discon= new JButton("停止");
		discon.setEnabled(false);
		northPanel.add(new JLabel("端口号"));
		northPanel.add(port);
		northPanel.add(new JLabel("服务器IP"));
		northPanel.add(IP);
		northPanel.add(new JLabel("用户名"));
		northPanel.add(userName);
		northPanel.add(link);
		northPanel.add(discon);
		panel.add(northPanel,BorderLayout.NORTH);
		
		userlist = new JTextArea();
		userlist.setLineWrap(true);
		userlist.setEditable(false);
		leftPanel =new JScrollPane(userlist);
		leftPanel.setBorder(new TitledBorder("在线用户"));
		panel.add(leftPanel,BorderLayout.EAST);
		
		chatRecords = new JTextArea();
		chatRecords.setLineWrap(true);
		chatRecords.setEditable(false);
		rightPanel =new JScrollPane(chatRecords);
		rightPanel.setBorder(new TitledBorder("聊天信息"));
		centerPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);  
		centerPanel.setDividerLocation(100);  
		panel.add(centerPanel,BorderLayout.CENTER);
		
		southPanel = new JPanel();
		southPanel.setBorder(new TitledBorder("写消息"));
		message = new JTextField(50);
		send = new JButton("发送");
		southPanel.add(message);
		southPanel.add(send);
		panel.add(southPanel, BorderLayout.SOUTH);
		Jpanel.add(panel,BorderLayout.CENTER);
		this.add(Jpanel);
	}

	private void initFrame(){
		this.setTitle("聊天室-客户端");
		this.setSize(640,480);
		this.setLocationRelativeTo(null);
		Toolkit kit = Toolkit.getDefaultToolkit();
		Image img = kit.getImage("img/logo.jpg");
		this.setIconImage(img);
		this.setResizable(false);
		opening();
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		closing();
	}

	public class ClientThread extends Thread{

		@Override
		public void run() {
			String message=null;
			while(true){
				try {
					message = dis.readUTF();				
					if(message.contains("@在线用户列表@")){
						userstr = message.split(" ");
						if(userstr.length!=usersLength){
							userlist.setText("");
							for(int i=0;i<userstr.length-1;i++){
							   userlist.append(userstr[i]);
							   userlist.append("\n");
							}
							usersLength = userstr.length;
						}
						
					}else{
						chatRecords.append("\n");
						chatRecords.append(message);
						chatRecords.setCaretPosition(chatRecords.getDocument().getLength());
					}
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					if(isConnect==true)
						JOptionPane.showMessageDialog(null, "服务器断开连接","错误",JOptionPane.ERROR_MESSAGE);
					link.setEnabled(true);
					discon.setEnabled(false);
					isConnect = false;
					port.setEditable(true);
					IP.setEditable(true);
					userName.setEditable(true);
					userlist.setText("");
					userstr=null;
					usersLength=0;
					try {
						dis.close();
						dos.close();
						socket.close();
						ct.stop();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					e.printStackTrace();
				}
			}
		}
	}

	public void send(){
		if(isConnect==false){
			JOptionPane.showMessageDialog(null, "未连接服务器,无法发送消息","错误",JOptionPane.ERROR_MESSAGE);
			return;
		}
		if(message.getText().trim().equals("")){
			JOptionPane.showMessageDialog(null, "消息不能为空","错误",JOptionPane.ERROR_MESSAGE);
			return;
		}
		String str = message.getText();	
		sendMessage(str);	
	}

	public void sendMessage(String str){
		try {
			dos.writeUTF(userName.getText()+": "+str);
		} catch (IOException e) {
			e.printStackTrace();
		}
		message.setText("");
	}

	public void opening(){
		Properties p = new Properties();

		try {
			if(new File("src/FontClient.properties").exists()){
				p.load(new FileReader("src/FontClient.properties"));
				myfont = new Font(p.getProperty("FontName"),Integer.parseInt(p.getProperty("FontStyle")),Integer.parseInt(p.getProperty("FontSize")));
				chatRecords.setFont(myfont);
				chatRecords.setForeground(new Color(Integer.parseInt(p.getProperty("foreColor"))));
				chatRecords.setBackground(new Color(Integer.parseInt(p.getProperty("backColor"))));
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void closing(){
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				if(isConnect == true){
					try {
						dos.writeUTF(userName.getText()+" 离开了聊天室");
						dis.close();
						dos.close();
						socket.close();
						ct.stop();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				Properties size = new Properties();
				size.setProperty("FontName", ChatRoomClientFrame.this.chatRecords.getFont().getFamily());
				size.setProperty("FontStyle", ChatRoomClientFrame.this.chatRecords.getFont().getStyle()+"");
				size.setProperty("FontSize", ChatRoomClientFrame.this.chatRecords.getFont().getSize()+"");
				size.setProperty("foreColor", ChatRoomClientFrame.this.chatRecords.getForeground().getRGB()+"");
				size.setProperty("backColor", ChatRoomClientFrame.this.chatRecords.getBackground().getRGB()+"");
				try {
					FileWriter fr = new FileWriter("src/FontClient.properties");
					size.store(fr, "FontClient Info");
					fr.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
	}

}
服务器端界面:

package Test;
import UI.ChatRoomServerFrame;

public class ChatRoomServer {
	
	public static void main(String[] args) {
		new ChatRoomServerFrame().setVisible(true);
	}
}
服务器端实现:

package UI;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.TrayIcon.MessageType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
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.border.TitledBorder;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;


public class ChatRoomServerFrame extends JFrame{
	/**
	 * 
	 */
	private static final long serialVersionUID = -6582389471265865971L;
	
	private JPanel panel;
	private JPanel northPanel;
	private JPanel southPanel;
	private JTextField IP;
	private JTextField port;
	private JTextArea userlist;
	private JTextArea chatRecords;
	private JScrollPane leftPanel;
	private JScrollPane rightPanel;
	private JSplitPane  centerPanel;
	private JTextField message;
	private JButton start;
	private JButton stop;
	private JButton send;
	private JPanel Jpanel;
	private JMenuBar bar;
	private JMenu file;
	private JMenuItem save;
	private JMenu format;
	private JMenuItem font;
	private JMenuItem foreGround;
	private JMenuItem backGround;
	private Font myfont;
	private Vector<Socket> lists=new Vector<Socket>(); 
	
	private ServerSocket serverSocket;
	private ServerThread st;
	private DataOutputStream dos;
	private DataInputStream dis;
	private ArrayList<String> users = new ArrayList<String>();
	private int usersLength = 0;
	private UserList ul;
	private String usermessage=null;
	
	private boolean isStart = false;

	public ChatRoomServerFrame(){
	
		initServer();
		
		start.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				
					try {
						if(port.getText().trim().equals("")){
							JOptionPane.showMessageDialog(null, "端口号不能为空","错误",JOptionPane.ERROR_MESSAGE);
							return;
						}
						if(isStart==false){
							serverSocket = new ServerSocket(Integer.parseInt(port.getText()));
							chatRecords.append("\n");
							chatRecords.append("服务器已开启");
							st = new ServerThread(serverSocket);
							st.start();
							port.setEditable(false);
							start.setEnabled(false);
							stop.setEnabled(true);
							isStart = true;
							ul = new UserList();
							ul.start();
						}
					} catch (NumberFormatException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
			}
		});

		stop.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					chatRecords.append("\n");
					chatRecords.append("服务器已断开");
					chatRecords.setCaretPosition(chatRecords.getDocument().getLength());
					if(dis != null){
						dis.close();
					}
					if(dos != null){
						dos.close();
					}
					users.removeAll(users);
					userlist.setText("");
					usersLength=0;
					serverSocket.close();
					port.setEditable(true);
					start.setEnabled(true);
					stop.setEnabled(false);
					isStart = false;
					ul.stop();
					st.stop();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		
		send.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				
				if(lists.size()==0){
					JOptionPane.showMessageDialog(null, "当前没有用户在线","错误",JOptionPane.ERROR_MESSAGE);
					return;
				}
				
				if(message.getText().trim().equals("")){
					JOptionPane.showMessageDialog(null, "消息不能为空","错误",JOptionPane.ERROR_MESSAGE);
					return;
				}
				String line="服务器:"+message.getText();
				sendMessage(line);
				
				message.setText("");	
			}
		});
		
		message.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				if(lists.size()==0){
					JOptionPane.showMessageDialog(null, "当前没有用户在线","错误",JOptionPane.ERROR_MESSAGE);
					return;
				}
				
				if(message.getText().trim().equals("")){
					JOptionPane.showMessageDialog(null, "消息不能为空","错误",JOptionPane.ERROR_MESSAGE);
					return;
				}
				String line="服务器:"+message.getText();
				sendMessage(line);
				
				message.setText("");	
				
			}
		});
		
		font.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				MyFontChooser mf = new MyFontChooser(chatRecords.getFont());
				 int returnValue = mf.showFontDialog(ChatRoomServerFrame.this);  
	                // 如果按下的是确定按钮  
                if (returnValue == MyFontChooser.APPROVE_OPTION) {  
                    // 获取选择的字体  
                    Font font = mf.getSelectFont();  
                    // 将字体设置到JTextArea中  
                    chatRecords.setFont(font);  
                }
			}
		});
		
		save.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				FileDialog saveFile = new FileDialog(ChatRoomServerFrame.this, "保存文件...", FileDialog.SAVE);
				saveFile.setVisible(true);
				String filePath = saveFile.getDirectory() + saveFile.getFile();
			
				try {
					FileOutputStream fos = new FileOutputStream(filePath);
					fos.write(chatRecords.getText().getBytes());
					fos.close();
					
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		
		backGround.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				Color bc = JColorChooser.showDialog(ChatRoomServerFrame.this, "选择颜色", Color.BLACK);
				chatRecords.setBackground(bc);
			}
		});
		
		foreGround.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				Color fc = JColorChooser.showDialog(ChatRoomServerFrame.this, "选择颜色", Color.BLACK);
				chatRecords.setForeground(fc);
			}
		});

		initFrame();
	}
	
	private void initServer() {
		Jpanel = new JPanel();
		Jpanel.setLayout(new BorderLayout());
		panel = new JPanel();
		panel.setLayout(new BorderLayout());
		northPanel = new JPanel();
		northPanel.setBorder(new TitledBorder("配置信息"));
		IP = new JTextField(15);
		String ipAddress = null;
		try {
			ipAddress = InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		IP.setText(ipAddress);
		IP.setEditable(false);
		port = new JTextField(15);
		port.setText("8088");
		start = new JButton("启动");
		stop = new JButton("停止");
		stop.setEnabled(false);
		northPanel.add(new JLabel("本地地址"));
		northPanel.add(IP);
		northPanel.add(new JLabel("端口号"));
		northPanel.add(port);
		northPanel.add(start);
		northPanel.add(stop);
		
		bar = new JMenuBar();
		file = new JMenu("记录");
		save = new JMenuItem("保存");
		format = new JMenu("格式");
		font = new JMenuItem("字体");
		foreGround = new JMenuItem("前景色");
		backGround = new JMenuItem("背景色");
		file.add(save);
		format.add(font);
		format.add(foreGround);
		format.add(backGround);
		bar.add(file);
		bar.add(format);
		Jpanel.add(bar,BorderLayout.NORTH);
		panel.add(northPanel,BorderLayout.NORTH);
		
		userlist = new JTextArea();
		userlist.setEditable(false);
		leftPanel =new JScrollPane(userlist);
		leftPanel.setBorder(new TitledBorder("在线用户"));
		panel.add(leftPanel,BorderLayout.EAST);
		
		chatRecords = new JTextArea();
		chatRecords.setEditable(false);
		rightPanel =new JScrollPane(chatRecords);
		rightPanel.setBorder(new TitledBorder("聊天信息"));
		centerPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);  
		centerPanel.setDividerLocation(100);  
		panel.add(centerPanel,BorderLayout.CENTER);
		
		southPanel = new JPanel();
		southPanel.setBorder(new TitledBorder("写消息"));
		message = new JTextField(50);
		send = new JButton("发送");
		southPanel.add(message);
		southPanel.add(send);
		panel.add(southPanel, BorderLayout.SOUTH);
		Jpanel.add(panel, BorderLayout.CENTER);
		this.add(Jpanel);
	}

	private void initFrame(){
		
		this.setTitle("聊天室-服务器");
		this.setSize(640,480);
		this.setLocationRelativeTo(null);
		Toolkit kit = Toolkit.getDefaultToolkit();
		Image img = kit.getImage("img/logo.jpg");
		this.setIconImage(img);
		this.setResizable(false);
		opening();
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		closing();
	}
	
	private class MSThread implements Runnable{
		
		private Socket socket;
		private DataInputStream dis ;
		
		public MSThread(Socket socket) {
			
			try {
				this.socket = socket;
				dis = new DataInputStream(socket.getInputStream());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		@Override
		public void run() {
			
			String message=null;
			try {
				while(true){
					message = dis.readUTF();
					if(message.contains("进入了聊天室")&&!message.contains(":"))
						users.add(message.split(" ")[0]);
					if(message.contains("离开了聊天室")&&!message.contains(":")){
						users.remove(message.split(" ")[0]);
						sendMessage(message);
						dis.close();
						socket.close();
						lists.remove(socket);
					}else{
						sendMessage(message);
					}
				}
			} catch (IOException e) {
				lists.remove(socket);
				e.printStackTrace();
			}
		}
	}

	public void sendMessage(String str){
		try {
			for(int i=0;i<lists.size();i++){
				dos = new DataOutputStream(lists.get(i).getOutputStream());
				dos.writeUTF(str);
			} 
		}catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(str);
		chatRecords.append("\n");
		chatRecords.append(str);
		chatRecords.setCaretPosition(chatRecords.getDocument().getLength());
	}
	
	public void sendUserMessage(String str){
		try {
			for(int i=0;i<lists.size();i++){
				dos = new DataOutputStream(lists.get(i).getOutputStream());
				dos.writeUTF(str);
			} 
		}catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}	
	
	private class ServerThread extends Thread{
		private ServerSocket serverSocket;
		
		public ServerThread(ServerSocket serverSocket){
			this.serverSocket = serverSocket;
		}
		
		@Override
		public void run() {
			while(true)
			{
				Socket soket=null;
				try {
					soket=serverSocket.accept();
					new Thread(new MSThread(soket)).start();
					lists.add(soket);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void opening(){
		Properties p = new Properties();

		try {
			if(new File("src/FontServer.properties").exists()){
				p.load(new FileReader("src/FontServer.properties"));
				myfont = new Font(p.getProperty("FontName"),Integer.parseInt(p.getProperty("FontStyle")),Integer.parseInt(p.getProperty("FontSize")));
				chatRecords.setFont(myfont);
				chatRecords.setForeground(new Color(Integer.parseInt(p.getProperty("foreColor"))));
				chatRecords.setBackground(new Color(Integer.parseInt(p.getProperty("backColor"))));
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void closing(){
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				Properties size = new Properties();
				size.setProperty("FontName", ChatRoomServerFrame.this.chatRecords.getFont().getFamily());
				size.setProperty("FontStyle", ChatRoomServerFrame.this.chatRecords.getFont().getStyle()+"");
				size.setProperty("FontSize", ChatRoomServerFrame.this.chatRecords.getFont().getSize()+"");
				size.setProperty("foreColor", ChatRoomServerFrame.this.chatRecords.getForeground().getRGB()+"");
				size.setProperty("backColor", ChatRoomServerFrame.this.chatRecords.getBackground().getRGB()+"");
				try {
					FileWriter fr = new FileWriter("src/FontServer.properties");
					size.store(fr, "FontServer Info");
					fr.close();
					if(isStart == true){
						if(dis != null){
							dis.close();
						}
						if(dos != null){
						 dos.close();
						}
						serverSocket.close();
						ul.stop();
						st.stop();
					}
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
	}

	public class UserList extends Thread{

		@Override
		public void run() {
			while(true){
				if(users.size()!=usersLength){
					userlist.setText("");
					usermessage="";
					for(String s : users){
					   userlist.append(s);
					   userlist.append("\n");
					   usermessage=usermessage+s+" ";
					}
					usersLength = users.size();
					sendUserMessage(usermessage+"@在线用户列表@");
				}
			}
		}
		
	}
}
字体选择器:

package UI;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;

public class MyFontChooser extends JDialog {

	/**
	 * 
	 */
	private static final long serialVersionUID = 7329415273324558584L;
	
	/**  
     * 选择取消按钮的返回值  
     */  
    public static final int CANCEL_OPTION = 0;  
    /**  
     * 选择确定按钮的返回值  
     */  
    public static final int APPROVE_OPTION = 1;  
    /**  
     * 中文预览的字符串  
     */  
    private static final String CHINA_STRING = "神马都是浮云!";  
    /**  
     * 英文预览的字符串  
     */  
    private static final String ENGLISH_STRING = "Hello Kitty!";  
    /**  
     * 数字预览的字符串  
     */  
    private static final String NUMBER_STRING = "0123456789";  
    // 预设字体,也是将来要返回的字体  
    private Font font = null;  
    // 字体选择器组件容器  
    private Box box = null;  
    // 字体文本框  
    private JTextField fontText = null;  
    // 样式文本框  
    private JTextField styleText = null;  
    // 文字大小文本框  
    private JTextField sizeText = null;  
    // 预览文本框  
    private JTextField previewText = null;  
    // 中文预览  
    private JRadioButton chinaButton = null;  
    // 英文预览  
    private JRadioButton englishButton = null;  
    // 数字预览  
    private JRadioButton numberButton = null;  
    // 字体选择框  
    private JList fontList = null;  
    // 样式选择器  
    private JList styleList = null;  
    // 文字大小选择器  
    private JList sizeList = null;  
    // 确定按钮  
    private JButton approveButton = null;  
    // 取消按钮  
    private JButton cancelButton = null;  
    // 所有字体  
    private String [] fontArray = null;  
    // 所有样式  
    private String [] styleArray = {"常规", "粗体", "斜体", "粗斜体"};  
    // 所有预设字体大小  
    private String [] sizeArray = {"8", "9", "10", "11", "12", "14", "16", "18", "20", "22", "24", "26", "28", "36", "48", "初号", "小初", "一号", "小一", "二号", "小二", "三号", "小三", "四号", "小四", "五号", "小五", "六号", "小六", "七号", "八号"};  
    // 上面数组中对应的字体大小  
    private int [] sizeIntArray = {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 42, 36, 26, 24, 22, 18, 16, 15, 14, 12, 10, 9, 8, 7, 6, 5};  
    // 返回的数值,默认取消  
    private int returnValue = CANCEL_OPTION;  
    /**  
     * 体构造一个字体选择器  
     */  
	public MyFontChooser(Font font){
		setTitle("字体选择器");  
        this.font = font;  
        // 初始化UI组件  
        init();  
        // 添加监听器  
        addListener();  
        // 按照预设字体显示  
        setup();  
        // 基本设置  
        setModal(true);  
        setResizable(false);  
        // 自适应大小  
        pack();  
	}
	
	 /**  
     * 初始化组件  
     */  
    private void init(){  
        // 获得系统字体  
        GraphicsEnvironment eq = GraphicsEnvironment.getLocalGraphicsEnvironment();  
        fontArray = eq.getAvailableFontFamilyNames();  
        // 主容器  
        box = Box.createVerticalBox();  
        box.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));  
        fontText = new JTextField();  
        fontText.setEditable(false);  
        fontText.setBackground(Color.WHITE); 
        styleText = new JTextField();  
        styleText.setEditable(false);  
        styleText.setBackground(Color.WHITE);  
        sizeText = new JTextField("12"); 
        // 给文字大小文本框使用的Document文档,制定了一些输入字符的规则  
        Document doc = new PlainDocument(){  
            public void insertString(int offs, String str, AttributeSet a)  
                    throws BadLocationException {  
                if (str == null) {  
                    return;  
                }  
                if (getLength() >= 3) {  
                    return;  
                }  
                if (!str.matches("[0-9]+") && !str.equals("初号") && !str.equals("小初") && !str.equals("一号") && !str.equals("小一") && !str.equals("二号") && !str.equals("小二") && !str.equals("三号") && !str.equals("小三") && !str.equals("四号") && !str.equals("小四") && !str.equals("五号") && !str.equals("小五") && !str.equals("六号") && !str.equals("小六") && !str.equals("七号") && !str.equals("八号")) {  
                    return;  
                }  
                super.insertString(offs, str, a);  
                sizeList.setSelectedValue(sizeText.getText(), true);  
            }  
        };  
        sizeText.setDocument(doc);  
        previewText = new JTextField(20);  
        previewText.setHorizontalAlignment(JTextField.CENTER);  
        previewText.setEditable(false);  
        previewText.setBackground(Color.WHITE);  
        chinaButton = new JRadioButton("中文预览", true);  
        englishButton = new JRadioButton("英文预览");  
        numberButton = new JRadioButton("数字预览");  
        ButtonGroup bg = new ButtonGroup();  
        bg.add(chinaButton);  
        bg.add(englishButton);  
        bg.add(numberButton);  
        fontList = new JList(fontArray);  
        styleList = new JList(styleArray);  
        sizeList = new JList(sizeArray);  
        approveButton = new JButton("确定");  
        cancelButton = new JButton("取消");  
        Box box1 = Box.createHorizontalBox();  
        JLabel l1 = new JLabel("字体:");  
        JLabel l2 = new JLabel("字形:");  
        JLabel l3 = new JLabel("大小:");  
        l1.setPreferredSize(new Dimension(165, 14));  
        l1.setMaximumSize(new Dimension(165, 14));  
        l1.setMinimumSize(new Dimension(165, 14));  
        l2.setPreferredSize(new Dimension(95, 14));  
        l2.setMaximumSize(new Dimension(95, 14));  
        l2.setMinimumSize(new Dimension(95, 14));  
        l3.setPreferredSize(new Dimension(80, 14));  
        l3.setMaximumSize(new Dimension(80, 14));  
        l3.setMinimumSize(new Dimension(80, 14));  
        box1.add(l1);  
        box1.add(l2);  
        box1.add(l3);  
        Box box2 = Box.createHorizontalBox();  
        fontText.setPreferredSize(new Dimension(160, 25));  
        fontText.setMaximumSize(new Dimension(160, 25));  
        fontText.setMinimumSize(new Dimension(160, 25));  
        box2.add(fontText);  
        box2.add(Box.createHorizontalStrut(5));  
        styleText.setPreferredSize(new Dimension(90, 25));  
        styleText.setMaximumSize(new Dimension(90, 25));  
        styleText.setMinimumSize(new Dimension(90, 25));  
        box2.add(styleText);  
        box2.add(Box.createHorizontalStrut(5));  
        sizeText.setPreferredSize(new Dimension(80, 25));  
        sizeText.setMaximumSize(new Dimension(80, 25));  
        sizeText.setMinimumSize(new Dimension(80, 25));  
        box2.add(sizeText);  
        Box box3 = Box.createHorizontalBox();  
        JScrollPane sp1 = new JScrollPane(fontList);  
        sp1.setPreferredSize(new Dimension(160, 100));  
        sp1.setMaximumSize(new Dimension(160, 100));  
        sp1.setMaximumSize(new Dimension(160, 100));  
        box3.add(sp1);  
        box3.add(Box.createHorizontalStrut(5));  
        JScrollPane sp2 = new JScrollPane(styleList);  
        sp2.setPreferredSize(new Dimension(90, 100));  
        sp2.setMaximumSize(new Dimension(90, 100));  
        sp2.setMinimumSize(new Dimension(90, 100));  
        box3.add(sp2);  
        box3.add(Box.createHorizontalStrut(5));  
        JScrollPane sp3 = new JScrollPane(sizeList);  
        sp3.setPreferredSize(new Dimension(80, 100));  
        sp3.setMaximumSize(new Dimension(80, 100));  
        sp3.setMinimumSize(new Dimension(80, 100));  
        box3.add(sp3);  
        Box box4 = Box.createHorizontalBox();  
        Box box5 = Box.createVerticalBox();  
        JPanel box6 = new JPanel(new BorderLayout());  
        box5.setBorder(BorderFactory.createTitledBorder("字符集"));  
        box6.setBorder(BorderFactory.createTitledBorder("示例"));  
        box5.add(chinaButton);  
        box5.add(englishButton);  
        box5.add(numberButton);  
        box5.setPreferredSize(new Dimension(90, 95));  
        box5.setMaximumSize(new Dimension(90, 95));  
        box5.setMinimumSize(new Dimension(90, 95));  
        box6.add(previewText);  
        box6.setPreferredSize(new Dimension(250, 95));  
        box6.setMaximumSize(new Dimension(250, 95));  
        box6.setMinimumSize(new Dimension(250, 95));  
        box4.add(box5);  
        box4.add(Box.createHorizontalStrut(4));  
        box4.add(box6);  
        Box box7 = Box.createHorizontalBox();  
        box7.add(Box.createHorizontalGlue());  
        box7.add(approveButton);  
        box7.add(Box.createHorizontalStrut(5));  
        box7.add(cancelButton);  
        box.add(box1);  
        box.add(box2);  
        box.add(box3);  
        box.add(Box.createVerticalStrut(5));  
        box.add(box4);  
        box.add(Box.createVerticalStrut(5));  
        box.add(box7);  
        getContentPane().add(box);  
    }  
    /**  
     * 按照预设字体显示  
     */  
    private void setup() {  
        String fontName = font.getFamily();  
        int fontStyle = font.getStyle();  
        int fontSize = font.getSize();  
        /*  
         * 如果预设的文字大小在选择列表中,则通过选择该列表中的某项进行设值,否则直接将预设文字大小写入文本框  
         */  
        boolean b = false;  
        for (int i = 0; i < sizeArray.length; i++) {  
            if (sizeArray[i].equals(String.valueOf(fontSize))) {  
                b = true;  
                break;  
            }  
        }  
        if(b){  
            // 选择文字大小列表中的某项  
            sizeList.setSelectedValue(String.valueOf(fontSize), true);  
        }else{  
            sizeText.setText(String.valueOf(fontSize));  
        }  
        // 选择字体列表中的某项  
        fontList.setSelectedValue(fontName, true);  
        // 选择样式列表中的某项  
        styleList.setSelectedIndex(fontStyle);  
        // 预览默认显示中文字符  
        chinaButton.doClick();  
        // 显示预览  
        setPreview();  
    }  
    /**  
     * 添加所需的事件监听器  
     */  
    private void addListener() {  
        sizeText.addFocusListener(new FocusListener() {  
            public void focusLost(FocusEvent e) {  
                setPreview();  
            }  
            public void focusGained(FocusEvent e) {  
                sizeText.selectAll();  
            }  
        });  
        // 字体列表发生选择事件的监听器  
        fontList.addListSelectionListener(new ListSelectionListener() {  
            public void valueChanged(ListSelectionEvent e) {  
                if (!e.getValueIsAdjusting()) {  
                    fontText.setText(String.valueOf(fontList.getSelectedValue()));  
                    // 设置预览  
                    setPreview();  
                }  
            }  
        });  
        styleList.addListSelectionListener(new ListSelectionListener() {  
            public void valueChanged(ListSelectionEvent e) {  
                if (!e.getValueIsAdjusting()) {  
                    styleText.setText(String.valueOf(styleList.getSelectedValue()));  
                    // 设置预览  
                    setPreview();  
                }  
            }  
        });  
        sizeList.addListSelectionListener(new ListSelectionListener() {  
            public void valueChanged(ListSelectionEvent e) {  
                if (!e.getValueIsAdjusting()) {  
                    if(!sizeText.isFocusOwner()){  
                        sizeText.setText(String.valueOf(sizeList.getSelectedValue()));  
                    }  
                    // 设置预览  
                    setPreview();  
                }  
            }  
        });  
        // 编码监听器  
        EncodeAction ea = new EncodeAction();  
        chinaButton.addActionListener(ea);  
        englishButton.addActionListener(ea);  
        numberButton.addActionListener(ea);  
        // 确定按钮的事件监听  
        approveButton.addActionListener(new ActionListener() {  
            public void actionPerformed(ActionEvent e) {  
                // 组合字体  
                font = groupFont();  
                // 设置返回值  
                returnValue = APPROVE_OPTION;  
                // 关闭窗口  
                disposeDialog();  
            }  
        });  
        // 取消按钮事件监听  
        cancelButton.addActionListener(new ActionListener() {  
            public void actionPerformed(ActionEvent e) {  
                disposeDialog();  
            }  
        });  
    }  
    /**  
     * 显示字体选择器  
     * @param owner 上层所有者  
     * @return 该整形返回值表示用户点击了字体选择器的确定按钮或取消按钮,参考本类常量字段APPROVE_OPTION和CANCEL_OPTION  
     */  
    public final int showFontDialog(JFrame owner) {  
        setLocationRelativeTo(owner);  
        setVisible(true);  
        return returnValue;  
    }  
    /**  
     * 返回选择的字体对象  
     * @return 字体对象  
     */  
    public final Font getSelectFont() {  
        return font;  
    }  
    /**  
     * 关闭窗口  
     */  
    private void disposeDialog() {  
        MyFontChooser.this.removeAll();  
        MyFontChooser.this.dispose();  
    }  
      
    /**  
     * 显示错误消息  
     * @param errorMessage 错误消息  
     */  
    private void showErrorDialog(String errorMessage) {  
        JOptionPane.showMessageDialog(this, errorMessage, "错误", JOptionPane.ERROR_MESSAGE);  
    }  
    /**  
     * 设置预览  
     */  
    private void setPreview() {  
        Font f = groupFont();  
        previewText.setFont(f);  
    }  
    /**  
     * 按照选择组合字体  
     * @return 字体  
     */  
    private Font groupFont() {  
        String fontName = fontText.getText();  
        int fontStyle = styleList.getSelectedIndex();  
        String sizeStr = sizeText.getText().trim();  
        // 如果没有输入  
        if(sizeStr.length() == 0) {  
            showErrorDialog("字体(大小)必须是有效“数值!");  
            return null;  
        }  
        int fontSize = 0;  
        // 通过循环对比文字大小输入是否在现有列表内  
        for (int i = 0; i < sizeArray.length; i++) {  
            if(sizeStr.equals(sizeArray[i])){  
                fontSize = sizeIntArray[i];  
                break;  
            }  
        }  
        // 没有在列表内  
        if (fontSize == 0) {  
            try{  
                fontSize = Integer.parseInt(sizeStr);  
                if(fontSize < 1){  
                    showErrorDialog("字体(大小)必须是有效“数值”!");  
                    return null;  
                }  
            }catch (NumberFormatException nfe) {  
                showErrorDialog("字体(大小)必须是有效“数值”!");  
                return null;  
            }  
        }  
        return new Font(fontName, fontStyle, fontSize);  
    }  
      
    /**  
     * 编码选择事件的监听动作  
     * @author 米强  
     *  
     */  
    class EncodeAction implements ActionListener {  
        public void actionPerformed(ActionEvent e) {  
            if (e.getSource().equals(chinaButton)) {  
                previewText.setText(CHINA_STRING);  
            } else if (e.getSource().equals(englishButton)) {  
                previewText.setText(ENGLISH_STRING);  
            } else {  
                previewText.setText(NUMBER_STRING);  
            }  
        }  
    }  

}







  • 8
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值