首页>代码>java swing聊天室客户端+nodejs服务器实现简单的聊天系统>/chat/client/src/main/java/cn/jsxwsl/chat/client/ChatRoomUI.java
/**
 * 
 */
package cn.jsxwsl.chat.client;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;

import net.sf.json.JSONObject;

public class ChatRoomUI extends JFrame {

	private static final long serialVersionUID = 1L;

	private final int WIDTH = 980;
	private final int HEIGHT = 680;
	private final int LEFT = -5;
	private final int TOP = 20; 
	private final int ROW_SPAN = 10; 
	private final int COL_SPAN = 10; 
	private final int LINE_HEIGHT = 24;
	private final int BUTTON_WINDTH = 60;
	private final int LABEL_WIDTH = 80;

	private boolean connected = false;

	private Net net = null;
//	private User bindUser = null;
//	private List<User> roomUserList = new LinkedList<>();
//	private Vector<String> chatOnlineUserNames = new Vector<>(); // 在线用户列表数据

	// 窗体控件
	private Container container = null;// 窗体容器
	private JLabel hostLB = null;
	private JTextField hostTF = null; 
	private JLabel portLB = null;
	private JTextField portTF = null;
	private JLabel userIDLB = null;
	private JTextField userIDTF = null;
	private JLabel userPDLB = null;
	private JPasswordField userPDTF = null;

	private JTextArea showBox = null;// 消息显示框
	private JPanel chatBoard = null; // 聊天消息面板
	private JScrollPane showScroll = null;// 显示框的滚动条
	private JComboBox<String> fontNameBox = null; // 字体颜色下拉框
	private JComboBox<Integer> fontSizeBox = null; // 大小
	private JComboBox<String> fontColorBox = null; // 颜色
	private JTextArea editBox = null;// 消息编辑框
	private JButton sendBt = null;// 发送按钮
	private JButton picBt = null;// 图片按钮
	private JButton loginBt = null; // 登陆
	private JButton logoutBt = null; // 注销
	private JButton clearBt = null;
	private JList<String> userJList = null; // 在线列表
	private JScrollPane usersPane = null;
	private JFileChooser picChooser = null; // 图片选择对话框
	private JButton testBt = null;
	private JPanel toolBar = null;

	private LinkedHashMap<String, Color> colorMap = new LinkedHashMap<String, Color>(); // 颜色键值对

	public ChatRoomUI() {
		this.initWindow();
	}
	
	public void setNet(Net net) {
		this.net = net;
	}

	/*
	 * 初始化窗口
	 */
	private void initWindow() {
		super.setTitle("chat");
		super.setSize(WIDTH, HEIGHT);
		Toolkit tk = Toolkit.getDefaultToolkit();// 窗口实用工具
		int screenWidth = tk.getScreenSize().width;// 屏幕宽度
		int screenHidth = tk.getScreenSize().height;// 屏幕高度
		int left = (screenWidth - WIDTH) / 2; // 计算自适应水平居中位置
		int top = (screenHidth - HEIGHT) / 2;
		super.setLocation(left, top);// 窗体的左上角距离左边界和上边界的距离
		super.setResizable(false);// 设置窗体不可改变大小

		/*
		 * 布局窗体的控件
		 */
		container = super.getContentPane();// 窗体容器
		container.setLayout(null);

		hostLB = new JLabel("服务器IP:", JLabel.RIGHT);
		hostLB.setBounds(LEFT, TOP, 100, LINE_HEIGHT);
		container.add(hostLB);

		hostTF = new JTextField("127.0.0.1");
		hostTF.setBounds(hostLB.getX() + hostLB.getWidth() + COL_SPAN, hostLB.getY(), LABEL_WIDTH, LINE_HEIGHT);
		container.add(hostTF);

		portLB = new JLabel("端口号:", JLabel.RIGHT);
		portLB.setBounds(hostTF.getX() + hostTF.getWidth() + COL_SPAN, hostTF.getY(), LABEL_WIDTH, LINE_HEIGHT);
		container.add(portLB);

		portTF = new JTextField("10101");
		portTF.setBounds(portLB.getX() + portLB.getWidth(), portLB.getY(), LABEL_WIDTH, LINE_HEIGHT);
		container.add(portTF);

		userIDLB = new JLabel("账号:", JLabel.RIGHT);
		userIDLB.setBounds(portTF.getX() + portTF.getWidth(), portTF.getY(), LABEL_WIDTH, LINE_HEIGHT);
		// hostLB.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		container.add(userIDLB);

		userIDTF = new JTextField("a");
		userIDTF.setBounds(userIDLB.getX() + userIDLB.getWidth(), userIDLB.getY(), LABEL_WIDTH, LINE_HEIGHT);
		container.add(userIDTF);

		userPDLB = new JLabel("密码:", JLabel.RIGHT);
		userPDLB.setBounds(userIDTF.getX() + userIDTF.getWidth(), userIDTF.getY(), LABEL_WIDTH, LINE_HEIGHT);
		container.add(userPDLB);

		userPDTF = new JPasswordField("8888");
		userPDTF.setBounds(userPDLB.getX() + userPDLB.getWidth(), userPDLB.getY(), LABEL_WIDTH, LINE_HEIGHT);
		container.add(userPDTF);

		loginBt = new JButton("登录");
		loginBt.setBounds(userPDTF.getX() + userPDTF.getWidth() + COL_SPAN, userPDLB.getY(), BUTTON_WINDTH,
				LINE_HEIGHT);
		container.add(loginBt);

		logoutBt = new JButton("注销");
		logoutBt.setBounds(loginBt.getX() + userPDTF.getWidth(), loginBt.getY(), BUTTON_WINDTH, LINE_HEIGHT);
		container.add(logoutBt);
		logoutBt.setEnabled(connected);

		showBox = new JTextArea("");
		showBox.setSize(685, 400);
		showBox.setEditable(false);
		showBox.setBackground(Color.GRAY);// 背景颜色
		showBox.setForeground(Color.WHITE);// 前景色
		showBox.setFont(new Font("黑体", Font.PLAIN, 15));
		showBox.setLineWrap(true);
		chatBoard = new JPanel();
		chatBoard.setSize(685, 350);
		chatBoard.setLayout(new BoxLayout(chatBoard, BoxLayout.Y_AXIS));
		chatBoard.setBackground(Color.WHITE);// 背景颜色
		chatBoard.setForeground(Color.WHITE);// 前景色
		chatBoard.setFont(new Font("黑体", Font.PLAIN, 15));

		showScroll = new JScrollPane(chatBoard);// 实例化滚动区,并将消息面板放入其中
		showScroll.setBounds(LEFT + ROW_SPAN * 5, hostLB.getY() + hostLB.getHeight() + ROW_SPAN, showBox.getWidth(),
				showBox.getHeight()); // -->
		showScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);// 垂直滚动条不出现
		showScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);// 水平的滚动条自动出现
		container.add(showScroll);

		userJList = new JList<String>();
		userJList.setSize(200, showScroll.getHeight());
		userJList.setBorder(BorderFactory.createTitledBorder("在线成员"));
		usersPane = new JScrollPane(userJList);
		usersPane.setBounds(showScroll.getX() + showScroll.getWidth() + COL_SPAN, showScroll.getY(),
				userJList.getWidth(), userJList.getHeight());
		container.add(usersPane);

		// ImageIcon ii = new ImageIcon("temp/model_458X600.jpg");
		// pictureLab = new JLabel(ii);
		// pictureLab.setBounds(usersPane.getX(), usersPane.getY() +
		// usersPane.getHeight() + ROW_SPAN, userList.getWidth(),
		// userList.getWidth()*3/4);
		// pictureLab.setBorder(BorderFactory.createLineBorder(Color.red));
		// container.add(pictureLab);

		toolBar = new JPanel(new FlowLayout(FlowLayout.LEFT));
		toolBar.setBounds(showScroll.getX(), showScroll.getY() + showScroll.getHeight() + ROW_SPAN,
				showScroll.getWidth(), 40);
		toolBar.setBorder(BorderFactory.createRaisedSoftBevelBorder());
		toolBar.setBackground(Color.LIGHT_GRAY);
		container.add(toolBar);

		GraphicsEnvironment gEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
		fontNameBox = new JComboBox<String>(gEnv.getAvailableFontFamilyNames());
		fontNameBox.setSize(50, LINE_HEIGHT);
		fontNameBox.setSelectedIndex(1);
		toolBar.add(fontNameBox);

		fontSizeBox = new JComboBox<Integer>(new Integer[] { 12, 16, 20, 24, 28, 32, 36, 40, 96, 128 });
		fontSizeBox.setSize(100, LINE_HEIGHT);
		toolBar.add(fontSizeBox);

		colorMap.put("红色", new Color(0xff0000));
		colorMap.put("白色", new Color(0xffffff));
		colorMap.put("绿色", new Color(0x00ff00));
		colorMap.put("蓝色", new Color(0x0000ff));
		colorMap.put("黄色", new Color(0xffff00));
		colorMap.put("青铜色", new Color(0x8c7853));
		colorMap.put("金色", new Color(0xcd7f32));
		colorMap.put("暗灰色", new Color(0x696969));
		colorMap.put("米色", new Color(0xf5f5dc));
		colorMap.put("黑色", new Color(0x000000));

		String[] colorNames = colorMap.keySet().toArray(new String[colorMap.size()]);

		fontColorBox = new JComboBox<String>(colorNames);
		fontColorBox.setSize(100, LINE_HEIGHT);
		fontColorBox.setSelectedIndex(colorNames.length - 1);
		toolBar.add(fontColorBox);

		editBox = new JTextArea();
		editBox.setBounds(toolBar.getX(), toolBar.getY() + toolBar.getHeight() + ROW_SPAN, 530, 70);
		editBox.setForeground(colorMap.get((String) fontColorBox.getSelectedItem()));
		editBox.setLineWrap(true);
		editBox.setWrapStyleWord(true);
		editBox.setBorder(BorderFactory.createLoweredSoftBevelBorder());

		container.add(editBox);

		sendBt = new JButton("发送");
		sendBt.setBounds(editBox.getX() + editBox.getWidth() + COL_SPAN, editBox.getY() + 7, BUTTON_WINDTH,
				LINE_HEIGHT);
		editBox.setLineWrap(true);
		sendBt.setEnabled(false);
		container.add(sendBt);

		picBt = new JButton("选图");
		picBt.setBounds(sendBt.getWidth() + sendBt.getX() + COL_SPAN, sendBt.getY(), BUTTON_WINDTH, LINE_HEIGHT);
//		container.add(picBt);

		picChooser = new JFileChooser("./");
		picChooser.setDialogTitle("please chose a picture");

		clearBt = new JButton("清屏");
		clearBt.setBounds(sendBt.getX(), sendBt.getY() + sendBt.getHeight() + ROW_SPAN, BUTTON_WINDTH, LINE_HEIGHT);
//		container.add(clearBt);

		testBt = new JButton("test");
		testBt.setBounds(clearBt.getX() + sendBt.getWidth() + COL_SPAN, sendBt.getY() + clearBt.getHeight() + ROW_SPAN,
				BUTTON_WINDTH, LINE_HEIGHT); // -->
//		container.add(testBt);

		loginBt.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				try {
					System.out.println("login");
					login();

				} catch (Exception ex) {
					ex.printStackTrace();
					return;
				}
			}
		});

		// 发送按钮
		sendBt.addActionListener(new SendListener());

		// 文件对话框的文件型过滤
		picChooser.setFileFilter(new FileFilter() {

			// 文件类型描述
			public String getDescription() {
				return "*.jpg,*.png,*.png";
			}

			// 文件类型过滤
			public boolean accept(File file) {
				if (file.isDirectory()) {
					return true;
				} else {
					String fileName = file.getName();
					String upCase = fileName.toUpperCase();
					if (upCase.endsWith(".JPG") || upCase.endsWith(".GIF") || upCase.endsWith(".JPEG")|| upCase.endsWith(".PNG")) {
						return true;
					} else {
						return false;
					}
				}
			}
		});

		// 注销按钮
		logoutBt.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent ev) {
				closeConneting();
			}
		});

		// 关闭按钮
		clearBt.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent ev) {
				showBox.setText("");
				chatBoard.setVisible(false);
				chatBoard.removeAll();
				chatBoard.setVisible(true);
			}
		});

		// 编辑框快捷键
		editBox.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent arg0) {
				if ((arg0.getKeyCode() == KeyEvent.VK_ENTER) /* ctrl + 回车 */ 
						|| (arg0.getKeyCode() == KeyEvent.VK_S) && (arg0.isAltDown()) /* ctrl + s */) {

					String text = editBox.getText();
					send(text, 1);
					editBox.setText("");
				} else if ((arg0.getKeyCode() == KeyEvent.VK_C) && (arg0.isAltDown())) {
					System.exit(0); /* Alt + c 关闭窗口 */
				}
			}
		});

		// 添加颜色框的选中改变事件,同步刷新编辑框的文本颜色
		fontColorBox.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent ev) {
				String key = (String) fontColorBox.getSelectedItem();
				Color value = colorMap.get(key);
				editBox.setForeground(value);
			}
		});

		// 窗口关闭事件
		super.addWindowListener(new closeListener());

		this.setLoginWindow(true);
		this.setChatWindow(false);

	}

	public void setLoginWindow(boolean visible) {
		this.hostLB.setVisible(visible);
		this.hostTF.setVisible(visible);
		this.portLB.setVisible(visible);
		this.portTF.setVisible(visible);
		this.userIDLB.setVisible(visible);
		this.userIDTF.setVisible(visible);
		this.userPDLB.setVisible(visible);
		this.userPDTF.setVisible(visible);
		this.loginBt.setVisible(visible);
		this.logoutBt.setVisible(visible);
	}

	public void setChatWindow(boolean visible) {
		this.showBox.setVisible(visible);
		this.chatBoard.setVisible(visible);
		this.showScroll.setVisible(visible);
		this.fontNameBox.setVisible(visible);
		this.fontSizeBox.setVisible(visible);
		this.fontColorBox.setVisible(visible);
		this.editBox.setVisible(visible);
		this.sendBt.setEnabled(visible);
		this.sendBt.setVisible(visible);
		this.picBt.setVisible(visible);
		this.clearBt.setVisible(visible);
		this.userJList.setVisible(visible);
		this.usersPane.setVisible(visible);
		this.picChooser.setVisible(visible);
		this.testBt.setVisible(visible);
		this.toolBar.setVisible(visible);

	}

	
	
	private void connect() {
		if (!this.connected) {
			String host = this.hostTF.getText();
			String port = this.portTF.getText();
			// net应该跟随程序开启, 这里为了方便输入ip, 放在这了
			this.net.connect(host, port);
			this.net.startNetListner();
			this.connected = true;
		}
	}
	
	@SuppressWarnings("deprecation")
	public void login() {
		try {
			this.connect();
			JSONObject jobj = new JSONObject();
			jobj.put("userName", this.userIDTF.getText());
			jobj.put("password", this.userPDTF.getText());
			this.net.getSocket().emit("login", jobj.toString());

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	

	
	private void send(String text, int type) {
		if (text == null || text.trim().equals("")) {
			return;
		}

		try {
			JSONObject jobj = new JSONObject();
			jobj.put("userId", this.net.getBindUser().getId());
			jobj.put("nickname", this.net.getBindUser().getNickname());
			jobj.put("text", text);
			jobj.put("type", type);
			this.net.getSocket().emit("send", jobj.toString());

		} catch (Exception e) {
			alert("发送消息失败");
		}
	}

	


	public void closeConneting() {
		alert("连接已经断开");
		showBox.setText("");
		chatBoard.setVisible(false);
		chatBoard.removeAll();
		chatBoard.setVisible(true);
		setLoginWindow(true);
		setChatWindow(false);
//		bindUser = null;
//		roomUserList = new LinkedList<>();
//		chatOnlineUserNames = new Vector<>();
//		userJList.setListData(chatOnlineUserNames);
	}
	
	 public void updateOnlineNames(Vector<String> chatOnlineUserNames) {
		 userJList.setListData(chatOnlineUserNames);
	 }
	
	
	public void alert(String text) {
		JOptionPane.showMessageDialog(this, text, "萨瓦迪卡", JOptionPane.PLAIN_MESSAGE);
	}

	
	public void createChatComponent(String nickname, String text, long time, int type) {
		System.out.println("" + nickname + "," + text+ "," + time+ "," + type);
		//将文本内容做成为文本块,添加到面板上
	
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:MM:ss");
		String timeStr = sdf.format(new Date(time)).toString();
		String str = "TIME NICKNAME:".replace("TIME", timeStr).replace("NICKNAME", nickname);
		JTextArea nameArea = new JTextArea(str);
		nameArea.setBackground(null);
		nameArea.setEditable(false);
		nameArea.setLineWrap(true);
		nameArea.setWrapStyleWord(true);
		nameArea.setFont(new Font("微软雅黑", Font.PLAIN, 15));
		addToChatboard(nameArea);

		JTextArea textArea = new JTextArea(text);
		textArea.setBackground(null);
		textArea.setEditable(false);
		textArea.setLineWrap(true);
		textArea.setWrapStyleWord(true);
		textArea.setFont(new Font("微软雅黑", Font.PLAIN, 22));
		
		addToChatboard(textArea);
		
	}
	
	private void addToChatboard(Component comp) {
		if (comp == null)
			return;
		chatBoard.setVisible(false);
		chatBoard.add(comp);
		chatBoard.setVisible(true);
		try {
			Thread.sleep(20);
		} catch (InterruptedException e) {
		}
		chatBoard.setVisible(false);
		// 为了隔开每个人的聊天内容,此处追加一个空标签
		JLabel empty = new JLabel();
		chatBoard.add(empty);
		chatBoard.setVisible(true);
		// 将滚动条定位到最底端
		JScrollBar vsb = showScroll.getVerticalScrollBar();// 纵向滚动条
		vsb.setValue(vsb.getMaximum());// 定义到最大值
	}

	private class SendListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			String text = editBox.getText();
			send(text, 1);
			editBox.setText("");
		}
	}

	private class closeListener implements WindowListener {
		public void windowOpened(WindowEvent e) {
		}

		public void windowClosing(WindowEvent e) {
			System.exit(0);
			net.getSocket().disconnect();
		}

		public void windowClosed(WindowEvent e) {
		}

		public void windowIconified(WindowEvent e) {
		}

		public void windowDeiconified(WindowEvent e) {
		}

		public void windowActivated(WindowEvent e) {
		}

		public void windowDeactivated(WindowEvent e) {
		}

	}

//	public static void main(String[] args) {
//		ChatRoomUI cm = new ChatRoomUI();
//		cm.setVisible(true);
//	}
}
最近下载更多
qazzaq123  LV20 2021年2月8日
jaden12  LV3 2019年10月6日
black-shuai  LV6 2019年5月23日
略略略1555  LV1 2019年4月22日
你好看  LV1 2019年1月7日
xiaoxiongmao  LV2 2018年11月20日
shaogongzi  LV1 2018年10月10日
jarlove  LV7 2018年8月2日
我怕怕  LV3 2018年7月12日
Peter_  LV6 2018年7月4日
最近浏览更多
暂无贡献等级
belike 2023年5月26日
暂无贡献等级
wzy5432  LV1 2023年4月18日
win1991  LV6 2023年3月27日
hhdbzz  LV1 2022年12月29日
13133117021  LV4 2022年12月24日
wwfl02  LV3 2022年12月16日
12cq345  LV6 2022年10月13日
 LV7 2022年7月5日
小冷依诺  LV6 2022年6月22日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友