首页>代码>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日
最近浏览更多
微信网友_7550620088864768 LV1
6月16日
chenranr LV10
2024年6月15日
微信网友_6526583469690880
2023年6月19日
暂无贡献等级
belike
2023年5月26日
暂无贡献等级
wzy5432 LV1
2023年4月18日
win1991 LV6
2023年3月27日
hhdbzz LV1
2022年12月29日
13133117021 LV5
2022年12月24日
wwfl02 LV3
2022年12月16日
12cq345 LV6
2022年10月13日

