【Betty】聊天室 —— 客户端

shadowLogo

首先,本人来设计下 pojo层

pojo层:

本人还是先来展示用于封装用户信息pojo层对象

用户信息的封装 —— UserInfo类:

package edu.youzg.chat_room.client.pojo;

public class UserInfo {
	private String id;
	private String nick;
	private String password;
	private String netId;

	public UserInfo() {
	}

	public String getNetId() {
		return netId;
	}

	public void setNetId(String netId) {
		this.netId = netId;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getNick() {
		return nick;
	}

	public void setNick(String nick) {
		this.nick = nick;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		UserInfo other = (UserInfo) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return nick;
	}

}

由于我们想要设计的 聊天室页面,有 好友列表
因此,在这里,还需要设计一个 好友列表池 —— FriendPool类

好友列表池 —— FriendPool类:

package edu.youzg.chat_room.client.pojo;

import java.util.HashMap;
import java.util.Map;

public class FriendPool {
	private Map<String, UserInfo> userPool;
	
	public FriendPool() {
		this.userPool = new HashMap<>();
	}

	public void addFriend(UserInfo user) {
		userPool.put(user.getId(), user);
	}
	
	public void removeFriend(UserInfo user) {
		userPool.remove(user.getId());
	}
	
	public UserInfo getUserById(String userId) {
		return userPool.get(userId);
	}
	
}

现在,我们来实现下 用于与服务器进行数据传输protocol层

protocol层:

首先,是 组成App层通信协议枚举 —— EAppCommand枚举

App层通信协议 枚举 —— EAppCommand枚举:

package edu.youzg.chat_room.client.protocol;

public enum EAppCommand {
	I_AM_COMMING,
	I_AM_HERE,
	I_AM_GONE,
	
	TO_ONE,
	TO_OTHER,
}

现在,本人再来编写 App层通信协议 的消息封装实体 —— ChatMessage类

App层通信协议 的消息封装实体 —— ChatMessage类:

package edu.youzg.chat_room.client.protocol;

public class ChatMessage {
	private EAppCommand command;
	private String message;

	public ChatMessage() {
	}

	public EAppCommand getCommand() {
		return command;
	}

	public void setCommand(EAppCommand command) {
		this.command = command;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

}

接下来,本人就来编写下客户端界面view层

view层:

首先是 客户端连接服务器的界面 —— ConnectToServerView 类

连接服务器的界面 —— ConnectToServerView 类:

package edu.youzg.chat_room.client.view.connect;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.UnknownHostException;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import edu.youzg.betty.core.Client;
import edu.youzg.betty.core.ClientActionAdapter;
import edu.youzg.betty.exception.ClientActionNotSetException;
import edu.youzg.chat_room.client.view.login.LoginView;
import edu.youzg.util.ISwingHelper;
import edu.youzg.util.PromptBoxTool;
import edu.youzg.util.exceptions.FrameIsNullException;

public class ConnectToServerView implements ISwingHelper {
	private JFrame jfrmConnectView;
	private JLabel jlblMessage;	
	private int count;
	
	private Client client;
	
	public ConnectToServerView() {
		this.count = 1;
	}

	public void initClient() throws UnknownHostException {
		this.client = new Client();
		this.client.initClient("/client.cfg.properties");
		this.client.setClientAction(new ConnectAction());
	}
	
	@Override
	public void init() {
		jfrmConnectView = new JFrame("连接服务器");
		jfrmConnectView.setLayout(new BorderLayout());
		jfrmConnectView.setMinimumSize(new Dimension(300, 150));
		jfrmConnectView.setLocationRelativeTo(null);
		jfrmConnectView.setResizable(false);
		jfrmConnectView.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		
		JLabel jlblTopic = new JLabel("连接服务器", 0);
		jlblTopic.setFont(topicFont);
		jlblTopic.setForeground(topicColor);
		jfrmConnectView.add(jlblTopic, BorderLayout.NORTH);
		
		jlblMessage = new JLabel("", 0);
		jlblMessage.setFont(normalFont);
		jfrmConnectView.add(jlblMessage);
	}

	public void startConnect() {
		jlblMessage.setText("正在进行第" + count++ + "次连接……");
		try {
			while (!client.connectToServer()) {
				int choice = PromptBoxTool.getChoice(jfrmConnectView, "连接服务器失败,是否继续尝试连接?",
						JOptionPane.YES_NO_OPTION);
				if (choice != JOptionPane.YES_OPTION) {
					exitView();
					return;
				}
				jlblMessage.setText("正在进行第" + count++ + "次连接……");
			}
		} catch (ClientActionNotSetException e) {
			e.printStackTrace();
		} catch (FrameIsNullException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void reinit() {}

	@Override
	public void dealEvent() {
		jfrmConnectView.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				try {
					exitView();
				} catch (FrameIsNullException e1) {
					e1.printStackTrace();
				}
			}
		});
	}

	@Override
	public JFrame getFrame() {
		return jfrmConnectView;
	}

	class ConnectAction extends ClientActionAdapter {
		
		public ConnectAction() {
		}

		@Override
		public void afterConnectToServer() {
			// 连接成功,开始“登录”界面
			LoginView loginView = new LoginView(client);
			loginView.initView();
			try {
				loginView.showView();
			} catch (FrameIsNullException e) {
				e.printStackTrace();
			}
			try {
				exitView();
			} catch (FrameIsNullException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void serverAbnormalDrop() {
			PromptBoxTool.showMessage(jfrmConnectView, "服务器拒绝连接,请稍后尝试……");
			try {
				exitView();
			} catch (FrameIsNullException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void serverOutOfRoom() {
			PromptBoxTool.showMessage(jfrmConnectView, "服务器已满,请稍后尝试连接……");
			try {
				exitView();
			} catch (FrameIsNullException e) {
				e.printStackTrace();
			}
		}
		
	}
	
}

然后是用户登陆界面 —— LoginView 类

用户登陆界面 —— LoginView 类:

package edu.youzg.chat_room.client.view.login;

import edu.youzg.betty.action.ActionBeanFactory;
import edu.youzg.betty.action.Actioner;
import edu.youzg.betty.action.Mapping;
import edu.youzg.betty.core.Client;
import edu.youzg.betty.core.ClientActionAdapter;
import edu.youzg.chat_room.client.pojo.UserInfo;
import edu.youzg.chat_room.client.view.chat.ChatRoomView;
import edu.youzg.util.ArgumentMaker;
import edu.youzg.util.ISwingHelper;
import edu.youzg.util.PromptBoxTool;
import edu.youzg.util.exceptions.FrameIsNullException;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

@Actioner
public class LoginView implements ISwingHelper {
	private Client client;
	
	private JFrame jfrmLogin;
	private JLabel jlblRegistry;
	private JButton jbtnLogin;
	private JTextField jtxtUserName;
	private JPasswordField jpswPassword;

	public LoginView() {
	}
	
	public LoginView(Client client) {
		this.client = client;
		this.client.setClientAction(new LoginAction());
	}

	private void offline() {
		client.offline();
	}
	
	@Override
	public void dealEvent() {
		jfrmLogin.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				offline();
			}
		});
		
		jpswPassword.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				jpswPassword.setText("");
			}
		});
		
		jtxtUserName.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				jtxtUserName.selectAll();
			}
		});
		
		jtxtUserName.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				jpswPassword.requestFocus();
			}
		});
		
		jpswPassword.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				jbtnLogin.requestFocus();
			}
		});
		
		jbtnLogin.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				dealUserLogin();
			}
		});
		
		jbtnLogin.addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {
				dealUserLogin();
			}
		});
	}
	
	private void dealUserLogin() {
		String id = jtxtUserName.getText();
		String password = new String(jpswPassword.getPassword());
		password = String.valueOf(password.hashCode());

		ActionBeanFactory.setObject("afterLogin", this);
		client.sendRequest("userLogin", "afterLogin", new ArgumentMaker()
				.add("id", id)
				.add("password", password)
				.toString());
	}

	@Mapping("afterLogin")
	public void afterLogin(UserInfo user) {
		if (user.getId().equals("ERROR")) {
			PromptBoxTool.showWarnning(jfrmLogin, "账号或密码错误!");
			jpswPassword.setText("");
			jtxtUserName.selectAll();
			jtxtUserName.requestFocus();
			return;
		}
		user.setNetId(client.getId());
		client.sendMessageToServer("用户[" + user + "]进入聊天室!");
		ChatRoomView chatRoomView = new ChatRoomView(client, user);
		chatRoomView.initView();
		try {
			chatRoomView.showView();
			exitView();
		} catch (FrameIsNullException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void init() {
		jfrmLogin = new JFrame("用户登录");
		jfrmLogin.setLayout(new BorderLayout());
		jfrmLogin.setSize(300, 200);
		jfrmLogin.setLocationRelativeTo(null);
		jfrmLogin.setResizable(false);
		jfrmLogin.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		
		JLabel jlblTopic = new JLabel("用户登录", 0);
		jlblTopic.setFont(topicFont);
		jlblTopic.setForeground(topicColor);
		jfrmLogin.add(jlblTopic, BorderLayout.NORTH);
		
		JPanel jpnlContxt = new JPanel();
		jpnlContxt.setLayout(null);
		jfrmLogin.add(jpnlContxt, BorderLayout.CENTER);
		
		int normalSize = normalFont.getSize();
		int left = 8*PADDING;
		int top = 5*PADDING;
		int lblWidth = 2 * normalSize;
		int lblHeight = normalSize + 2;
		JLabel jlblUserName = new JLabel("账号");
		jlblUserName.setFont(normalFont);
		jlblUserName.setBounds(left, top, lblWidth, lblHeight);
		jpnlContxt.add(jlblUserName);
		
		jtxtUserName = new JTextField();
		jtxtUserName.setFont(normalFont);
		jtxtUserName.setBounds(left + lblWidth + PADDING, top, 11*normalSize, lblHeight+4);
		jpnlContxt.add(jtxtUserName);
		
		top += lblHeight + 3*PADDING;
		JLabel jlblPassword = new JLabel("密码");
		jlblPassword.setFont(normalFont);
		jlblPassword.setBounds(left, top, lblWidth, lblHeight);
		jpnlContxt.add(jlblPassword);
		
		jpswPassword = new JPasswordField();
		jpswPassword.setFont(normalFont);
		jpswPassword.setBounds(left + lblWidth + PADDING, top, 11*normalSize, lblHeight + 4);
		jpnlContxt.add(jpswPassword);
		
		JPanel jpnlButton = new JPanel();
		jpnlButton.setLayout(new FlowLayout());
		jfrmLogin.add(jpnlButton, BorderLayout.SOUTH);
		
		jlblRegistry = new JLabel("注册");
		jlblRegistry.setFont(new Font("微软雅黑", Font.BOLD, 16));
		jlblRegistry.setForeground(new Color(5,98,44));
		jlblRegistry.setCursor(handCursor);
		jpnlButton.add(jlblRegistry);
		
		JLabel jlblBlank = new JLabel("      ");
		jlblBlank.setFont(normalFont);
		jpnlButton.add(jlblBlank);
		
		jbtnLogin = new JButton("登录");
		jbtnLogin.setFont(smallFont);
		jpnlButton.add(jbtnLogin);
	}

	@Override
	public void reinit() {}

	@Override
	public JFrame getFrame() {
		return jfrmLogin;
	}

	class LoginAction extends ClientActionAdapter {
		
		public LoginAction() {
		}

		@Override
		public boolean confirmOffline() {
			int choice = PromptBoxTool.getChoice(jfrmLogin, "是否下线?", JOptionPane.YES_NO_OPTION);
			
			return choice == JOptionPane.YES_OPTION;
		}

		@Override
		public void afterOffline() {
			try {
				exitView();
			} catch (FrameIsNullException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void serverAbnormalDrop() {
			PromptBoxTool.showError(jfrmLogin, "服务器异常宕机,服务停止!");
			try {
				exitView();
			} catch (FrameIsNullException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void serverForcedown() {
			PromptBoxTool.showMessage(jfrmLogin, "服务器强制宕机,服务停止!");
			try {
				exitView();
			} catch (FrameIsNullException e) {
				e.printStackTrace();
			}
		}
		
	}
	
}

最后是 客户端的聊天室界面 —— ChatRoomView 类

聊天室界面 —— ChatRoomView 类:

package edu.youzg.chat_room.client.view.chat;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.google.gson.Gson;
import edu.youzg.betty.core.Client;
import edu.youzg.betty.core.ClientActionAdapter;
import edu.youzg.chat_room.client.pojo.FriendPool;
import edu.youzg.chat_room.client.pojo.UserInfo;
import edu.youzg.chat_room.client.protocol.ChatMessage;
import edu.youzg.chat_room.client.protocol.EAppCommand;
import edu.youzg.util.ArgumentMaker;
import edu.youzg.util.ISwingHelper;
import edu.youzg.util.PromptBoxTool;
import edu.youzg.util.exceptions.FrameIsNullException;

public class ChatRoomView implements ISwingHelper {
	private Client client;
	
	private JFrame jfrmChatRoomView;
	private JTextArea jtatSystemMessage;
	private JTextArea jtatChat;
	private DefaultListModel<UserInfo> dlmFriendList;
	private JList<UserInfo> jlstFriendList;
	private JLabel jlblCurrentFriend;
	private JTextField jtxtSpeakContext;
	private JButton jbtnSend;
	
	private UserInfo me;
	private UserInfo all;
	
	private FriendPool friendPool;
	private Gson gson;
	
	private static final String allId = "00000000";

	public ChatRoomView(Client client,  UserInfo me) {
		this.gson = ArgumentMaker.gson;
		this.friendPool = new FriendPool();
		
		this.all = new UserInfo();
		this.all.setId(allId);
		this.all.setNick("所有人");
		
		this.client = client;
		this.client.setClientAction(new ChatRoomAction());
		this.me = me;
	}

	@Override
	public void reinit() {
		dlmFriendList.addElement(all);
		jlstFriendList.setSelectedIndex(0);
		jlblCurrentFriend.setText(all.getNick());
		// 向其他聊天室好友发送“我来了”的消息
		Gson gson = ArgumentMaker.gson;
		
		ChatMessage chatMessage = new ChatMessage();
		chatMessage.setCommand(EAppCommand.I_AM_COMMING);
		chatMessage.setMessage(gson.toJson(me));
		client.toOther(gson.toJson(chatMessage));
	}

	private void showSystemMessage(String message) {
		jtatSystemMessage.append(message + "\n");
		jtatSystemMessage.setCaretPosition(jtatSystemMessage.getText().length());
	}
	
	private void showChatMessage(String message) {
		jtatChat.append(message + "\n");
		jtatChat.setCaretPosition(jtatChat.getText().length());
	}

	@Override
	public void dealEvent() {
		jfrmChatRoomView.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				client.offline();
			}
		});
		
		jlstFriendList.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				if (e.getValueIsAdjusting() == false) {
					UserInfo curFriend = jlstFriendList.getSelectedValue();
					if (curFriend == null) {
						jlstFriendList.setSelectedIndex(0);
						curFriend = jlstFriendList.getSelectedValue();
					}
					jlblCurrentFriend.setText(curFriend.toString());
				}
			}
		});
		
		jbtnSend.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				String speakMessage = jtxtSpeakContext.getText();
				jtxtSpeakContext.setText("");
				if (speakMessage.length() <= 0) {
					PromptBoxTool.showError(jfrmChatRoomView, "不能发送空消息!");
					return;
				}
				
				UserInfo curFriend = jlstFriendList.getSelectedValue();
				String orgNick = jlblCurrentFriend.getText();
				if (!curFriend.getNick().equals(orgNick)) {
					PromptBoxTool.showError(jfrmChatRoomView, "好友[" + orgNick + "]已经不在聊天室!");
					return;
				}
				
				ChatMessage chatMessage = new ChatMessage();
				String message = new ArgumentMaker()
						.add("friend", me)
						.add("message", speakMessage)
						.toString();
				if (curFriend.getId().equals(allId)) {
					chatMessage.setCommand(EAppCommand.TO_OTHER);
					chatMessage.setMessage(message);
					client.toOther(gson.toJson(chatMessage));
					
					showChatMessage("你对大家喊道:" + speakMessage);
				} else {
					chatMessage.setCommand(EAppCommand.TO_ONE);
					chatMessage.setMessage(message);
					client.toOne(curFriend.getNetId(), gson.toJson(chatMessage));
					
					showChatMessage("你悄悄地对[" + curFriend + "]说道:" + speakMessage);
				}
			}
		});
	}

	@Override
	public JFrame getFrame() {
		return jfrmChatRoomView;
	}

	class ChatRoomAction extends ClientActionAdapter {
		
		public ChatRoomAction() {
		}

		@Override
		public boolean confirmOffline() {
			int choice = PromptBoxTool.getChoice(jfrmChatRoomView, "是否下线?", JOptionPane.YES_NO_OPTION);
			
			return choice == JOptionPane.YES_OPTION;
		}

		@Override
		public void beforeOffline() {
			client.sendMessageToServer("用户[" + me + "]离开聊天室");
			// 向其他好友发送“本尊下线”的消息
			ChatMessage leaveMessage = new ChatMessage();
			leaveMessage.setCommand(EAppCommand.I_AM_GONE);
			leaveMessage.setMessage(gson.toJson(me));
			
			client.toOther(gson.toJson(leaveMessage));
		}

		@Override
		public void afterOffline() {
			try {
				exitView();
			} catch (FrameIsNullException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void serverAbnormalDrop() {
			PromptBoxTool.showError(jfrmChatRoomView, "服务器异常宕机,服务停止!");
			try {
				exitView();
			} catch (FrameIsNullException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void dealToOne(String sourceId, String message) {
			ChatMessage chatMessage = gson.fromJson(message, ChatMessage.class);
			EAppCommand command = chatMessage.getCommand();
			String parameter = chatMessage.getMessage();
			
			switch (command) {
			case I_AM_HERE:
				UserInfo friend = gson.fromJson(parameter, UserInfo.class);
				friendPool.addFriend(friend);
				dlmFriendList.addElement(friend);
				break;
			case TO_ONE:
				ArgumentMaker argument = new ArgumentMaker(parameter);
				UserInfo speaker = (UserInfo) argument.getValue("friend", UserInfo.class);
				String speakContext = (String) argument.getValue("message", String.class);
				
				showChatMessage("[" + speaker + "]对你悄悄地说:" + speakContext);
				break;
			default:
				break;
			}
		}

		@Override
		public void dealToOther(String sourceId, String message) {
			ChatMessage chatMessage = gson.fromJson(message, ChatMessage.class);
			EAppCommand command = chatMessage.getCommand();
			String parameter = chatMessage.getMessage();
			
			switch (command) {
			case I_AM_COMMING:
				UserInfo newFriend = gson.fromJson(parameter, UserInfo.class);
				friendPool.addFriend(newFriend);
				dlmFriendList.addElement(newFriend);
				showSystemMessage("好友[" + newFriend + "]进入聊天室");
				
				ChatMessage echoMessage = new ChatMessage();
				echoMessage.setCommand(EAppCommand.I_AM_HERE);
				echoMessage.setMessage(gson.toJson(me));
				client.toOne(sourceId, gson.toJson(echoMessage));
				break;
			case I_AM_GONE:
				UserInfo leaveFriend = gson.fromJson(parameter, UserInfo.class);
				friendPool.removeFriend(leaveFriend);
				showSystemMessage("好友[" + leaveFriend + "]离开聊天室");
				
				UserInfo curFriend = jlstFriendList.getSelectedValue();
				dlmFriendList.removeElement(leaveFriend);
				if (curFriend.equals(leaveFriend)) {
					jlstFriendList.setSelectedIndex(0);
					jlblCurrentFriend.setText(all.toString());
					PromptBoxTool.showWarnning(jfrmChatRoomView, "好友[" + leaveFriend + "]已经离开");
				}
				break;
			case TO_OTHER:
				ArgumentMaker argument = new ArgumentMaker(parameter);
				UserInfo speaker = (UserInfo) argument.getValue("friend", UserInfo.class);
				String speakContext = (String) argument.getValue("message", String.class);
				
				showChatMessage("[" + speaker + "]对大家喊道:" + speakContext);
				break;
			default:
				break;
			}
		}
		
		@Override
		public void serverForcedown() {
			PromptBoxTool.showMessage(jfrmChatRoomView, "服务器强制宕机,服务停止!");
			try {
				exitView();
			} catch (FrameIsNullException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	@Override
	public void init() {
		jfrmChatRoomView = new JFrame("右转哥粉丝聊天室");
		jfrmChatRoomView.setDefaultCloseOperation(
				JFrame.DO_NOTHING_ON_CLOSE);
		jfrmChatRoomView.setSize(800, 600);
		jfrmChatRoomView.setLocationRelativeTo(null);
		
		Container container = jfrmChatRoomView.getContentPane();
		container.setLayout(new BorderLayout());
		
		JLabel jlblTopic = new JLabel("右粉聊天室", JLabel.CENTER);
		jlblTopic.setFont(topicFont);
		jlblTopic.setForeground(topicColor);
		container.add(jlblTopic, BorderLayout.NORTH);
		
		jtatSystemMessage = new JTextArea(0, 15);
		jtatSystemMessage.setFont(normalFont);
		JScrollPane jscpSystemMessage = 
				new JScrollPane(jtatSystemMessage);
		jscpSystemMessage.setPreferredSize(new Dimension(200, 400));
		TitledBorder ttdbSystemMessage = new TitledBorder(" 系统信息 ");
		ttdbSystemMessage.setTitleFont(normalFont);
		ttdbSystemMessage.setTitlePosition(TitledBorder.ABOVE_TOP);
		ttdbSystemMessage.setTitleJustification(TitledBorder.CENTER);
		jscpSystemMessage.setBorder(ttdbSystemMessage);
		container.add(jscpSystemMessage, BorderLayout.EAST);
		
		jtatChat = new JTextArea();
		jtatChat.setFont(normalFont);
		JScrollPane jscpChat = new JScrollPane(jtatChat);
		TitledBorder ttdbChat = new TitledBorder(" 聊天信息 ");
		ttdbChat.setTitleFont(normalFont);
		ttdbChat.setTitleColor(Color.RED);
		ttdbChat.setTitlePosition(TitledBorder.ABOVE_TOP);
		ttdbChat.setTitleJustification(TitledBorder.CENTER);
		jscpChat.setBorder(ttdbChat);
		container.add(jscpChat, BorderLayout.CENTER);
		
		JPanel jpnlFriends = new JPanel(new BorderLayout());
		container.add(jpnlFriends, BorderLayout.WEST);
		
		JPanel jpnlWelcome = new JPanel(new GridLayout(0, 1));
		jpnlFriends.add(jpnlWelcome, BorderLayout.NORTH);
		
		JLabel jlblWelcome = new JLabel(" 欢迎 ", JLabel.CENTER);
		jlblWelcome.setFont(normalFont);
		jlblWelcome.setForeground(Color.RED);
		jpnlWelcome.add(jlblWelcome);
		
		JLabel jlblUserSelf = new JLabel(me.getNick(), JLabel.CENTER);
		jlblUserSelf.setFont(normalFont);
		jlblUserSelf.setForeground(topicColor);
		jpnlWelcome.add(jlblUserSelf);
		
		dlmFriendList = new DefaultListModel<>();
		jlstFriendList = new JList<>(dlmFriendList);
		jlstFriendList.setFont(normalFont);
		JScrollPane jscpFriendList = 
				new JScrollPane(jlstFriendList);
		jscpFriendList.setPreferredSize(new Dimension(200, 300));
		TitledBorder ttdbFriendList = 
				new TitledBorder(" 好友列表 ");
		ttdbFriendList.setTitleFont(normalFont);
		ttdbFriendList.setTitlePosition(TitledBorder.TOP);
		ttdbFriendList.setTitleJustification(
				TitledBorder.CENTER);
		jscpFriendList.setBorder(ttdbFriendList);
		jpnlFriends.add(jscpFriendList, BorderLayout.CENTER);
		
		JPanel jpnlCurFriend = 
				new JPanel(new GridLayout(0, 1));
		jpnlFriends.add(jpnlCurFriend, BorderLayout.SOUTH);
		
		JLabel jlblCurrentFriendCaption = 
				new JLabel("当前好友", 0);
		jlblCurrentFriendCaption.setFont(normalFont);
		jpnlCurFriend.add(jlblCurrentFriendCaption);
		
		jlblCurrentFriend = new JLabel("", JLabel.CENTER);
		jlblCurrentFriend.setFont(normalFont);
		jlblCurrentFriend.setForeground(Color.RED);
		jpnlCurFriend.add(jlblCurrentFriend);
		
		JPanel jpnlFooter = new JPanel();
		container.add(jpnlFooter, BorderLayout.SOUTH);
		
		JLabel jlblYousay = new JLabel("你说 ");
		jlblYousay.setFont(normalFont);
		jpnlFooter.add(jlblYousay);
		
		jtxtSpeakContext = new JTextField(40);
		jtxtSpeakContext.setFont(normalFont);
		jpnlFooter.add(jtxtSpeakContext);
		
		jbtnSend = new JButton("发送");
		jbtnSend.setFont(smallFont);
		jpnlFooter.add(jbtnSend);
	}
}

最后,本人再来给出所需的配置文件

配置文件

首先是 用于初始化客户端连接参数client.cfg.properties 文件

client.cfg.properties 文件:

ip=localhost
port=6666

启动层:

客户端启动类 —— ChatRoomClientMain类:

package edu.youzg.chat_room.client.Main;

import edu.youzg.betty.action.ActionBeanFactory;
import edu.youzg.chat_room.client.view.connect.ConnectToServerView;
import edu.youzg.util.exceptions.FrameIsNullException;

import java.net.UnknownHostException;

public class ChatRoomClientMain {

	public static void main(String[] args) {
		ActionBeanFactory.scanPackage("edu.youzg.chat_room.client.view");
		try {
			ConnectToServerView connectToServer = new ConnectToServerView();
			connectToServer.initClient();
			connectToServer.initView();
			connectToServer.showView();
			connectToServer.startConnect();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (FrameIsNullException e) {
			e.printStackTrace();
		}
	}

}

至于运行结果,本人将放在总集篇为同学们展示。
(本人 聊天室总集篇 博文 ——《【Betty】使用展示 —— 聊天室》链接:
https://www.cnblogs.com/codderYouzg/p/12749222.html)


posted @ 2020-04-22 00:42  在下右转,有何贵干  阅读(71)  评论(0编辑  收藏  举报