下午在公司闲的蛋疼,花了2个小时整了个局域网的聊天工具玩。界面模仿飞鸽传书,基于UDP协议,只有最基本的聊天功能。代码结构也比较乱,有兴趣的可以拿去玩玩。import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import java.util.Map;
import java.util.UUID;import javax.swing.JFrame;import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.border.EtchedBorder;
import javax.swing.table.DefaultTableModel;import java.awt.SystemColor;
import javax.swing.ScrollPaneConstants;
import java.awt.Color;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JLabel;public class Msg extends JFrame {
private static final long serialVersionUID = 3170335398335303363L;
private String uname = "qq"; private DatagramSocket server;// UDP
private InetAddress broadcastAddress;// 廣播地址
private int port;// 監聽端口 private final Map<String, UserInfo> userTable = new Hashtable<String, UserInfo>();// 用戶列表
private final String guid = UUID.randomUUID().toString().replace("-", "").toUpperCase();// 本機唯一標識 private JTable table;
private JTextArea textArea;
private JLabel lblNewLabel_1; public Msg() throws SocketException {
this(5413);
} public Msg(int port) throws SocketException {
this.port = port; getContentPane().setLayout(null);
getContentPane().setBackground(SystemColor.control); JButton btnNewButton = new JButton("刷新");
btnNewButton.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
refresh();
}
});
btnNewButton.setBackground(SystemColor.control);
btnNewButton.setBounds(299, 119, 83, 28);
getContentPane().add(btnNewButton); JScrollPane scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setBounds(12, 12, 275, 135);
getContentPane().add(scrollPane); table = new JTable(new DefaultTableModel(new Object[][] { { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, }, new String[] { "\u7528\u6236\u540D", "IP", "GUID" }) {
private static final long serialVersionUID = -6259343924352571655L; public boolean isCellEditable(int row, int column) {
return false;
}
});
table.setBackground(new Color(255, 255, 255));
scrollPane.setViewportView(table);
table.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null)); JScrollPane scrollPane_1 = new JScrollPane();
scrollPane_1.setBounds(12, 159, 370, 104);
getContentPane().add(scrollPane_1); textArea = new JTextArea();
textArea.setLineWrap(true);
textArea.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if ((e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER) || (e.isAltDown() && e.getKeyCode() == KeyEvent.VK_S)) {
sendMessage();
}
}
});
scrollPane_1.setViewportView(textArea); JButton button = new JButton("發送");
button.setBackground(SystemColor.control);
button.setBounds(141, 275, 83, 28);
button.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
sendMessage();
}
});
getContentPane().add(button); JButton button_1 = new JButton("關閉");
button_1.setBackground(SystemColor.control);
button_1.setBounds(22, 275, 83, 28);
button_1.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
Msg.this.dispatchEvent(new WindowEvent(Msg.this, WindowEvent.WINDOW_CLOSING));
}
});
getContentPane().add(button_1); JLabel lblNewLabel = new JLabel("當前在線人數");
lblNewLabel.setBounds(299, 29, 83, 18);
getContentPane().add(lblNewLabel); lblNewLabel_1 = new JLabel("0");
lblNewLabel_1.setBounds(305, 59, 55, 18);
getContentPane().add(lblNewLabel_1);
JLabel lblNewLabel_2 = new JLabel("Alt+S或Ctrl+Enter發送");
lblNewLabel_2.setBounds(242, 280, 140, 18);
getContentPane().add(lblNewLabel_2); this.setSize(400, 348);
setBackground(SystemColor.control);
setResizable(false);
setTitle("局域網聊天");
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
sendBroadcast((guid + "2").getBytes(), broadcastAddress);
} catch (Exception e2) {
}
}
}); try { uname = JOptionPane.showInputDialog("請輸入你的暱稱");
uname = uname == null ? "匿名" : uname;
server = new DatagramSocket(port); broadcastAddress = InetAddress.getByName("255.255.255.255"); new AcceptBroadcastThread().start();// 啟動監聽
sendBroadcast((guid + "0" + uname).getBytes(), broadcastAddress);// 發送全網廣播,通知上線
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "端口" + port + "被佔用!");
System.exit(0);
}
} /**
* 向外發送數據
*
* @param data
* @param address
* @throws IOException
*/
public void sendBroadcast(byte[] data, InetAddress address) throws IOException {
DatagramPacket dp = new DatagramPacket(data, data.length, address, port);
server.send(dp);
} /**
* 刷新列表
*/
public void refresh() {
// 清空列表
userTable.clear();
DefaultTableModel tableModel = ((DefaultTableModel) table.getModel());
for (int j = table.getRowCount(); j > 0; j--) {
tableModel.removeRow(j - 1);
}
try {
sendBroadcast((guid + "3" + uname).getBytes(), broadcastAddress);// 重新發送全網廣播,通知上線
} catch (Exception e) {
}
} public void alertMessage(final String msg) {
new Thread() {
public void run() {
JOptionPane.showMessageDialog(Msg.this, msg);
};
}.start();
} /**
* 發送文字消息
*/
public void sendMessage() {
int[] selectRows = table.getSelectedRows();
DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
String msg = guid + "1" + textArea.getText();
byte[] data = string2Bytes(msg);
for (int i = 0, j = selectRows.length; i < j; i++) {
String key = (String) tableModel.getValueAt(selectRows[i], 2);
UserInfo ui = key == null ? null : userTable.get(key);
if (ui != null) {
try {
textArea.setText("");
sendBroadcast(data, ui.getIpAddress());
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "發送消息到" + ui.getName() + "(" + ui.getIpAddress().getHostAddress() + ")失敗!", "發送失敗", JOptionPane.ERROR_MESSAGE);
}
}
}
} private byte[] string2Bytes(String str) {
try {
return str.getBytes("UTF-8");
} catch (Exception e) {
}
return null;
} class UserInfo { private String guid;
private String name;
private InetAddress ipAddress; public String getGuid() {
return guid;
} public void setGuid(String guid) {
this.guid = guid;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public InetAddress getIpAddress() {
return ipAddress;
} public void setIpAddress(InetAddress ipAddress) {
this.ipAddress = ipAddress;
}
} class AcceptBroadcastThread extends Thread {
public void run() {
while (true) {
try {
DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);
server.receive(dp); String msg = new String(dp.getData(), 0, dp.getLength(), "UTF-8");// 解析廣播數據包
String uid = msg.substring(0, 32);
String type = msg.substring(32, 33); if (type.equals("0") || type.equals("3")) {
UserInfo ui = new UserInfo();
ui.setGuid(uid);
ui.setName(msg.substring(33));
ui.setIpAddress(dp.getAddress()); // 刷新請求,只響應不做其他處理
if (userTable.containsKey(ui.getGuid()) && type.equals("3")) {
sendBroadcast((guid + "0" + uname).getBytes(), broadcastAddress);
} // 上線通知
if (!userTable.containsKey(ui.getGuid())) {
userTable.put(ui.getGuid(), ui);// 將新用戶添加到用戶表
lblNewLabel_1.setText("" + userTable.size()); sendBroadcast((guid + "0" + uname).getBytes(), broadcastAddress);// 響應非本機廣播
((DefaultTableModel) table.getModel()).insertRow(0, new String[] { ui.getName(), ui.getIpAddress().getHostAddress(), ui.getGuid() });
}
} else if (type.equals("1")) {
UserInfo ui = userTable.get(uid);
alertMessage(ui.getName() + "(" + ui.getIpAddress().getHostAddress() + ")-" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\r\n" + msg.substring(33));
} else {
userTable.remove(uid);// 移除用戶
lblNewLabel_1.setText("" + userTable.size()); DefaultTableModel tableModel = ((DefaultTableModel) table.getModel());
for (int i = 0, j = table.getRowCount(); i < j; i++) {
if (tableModel.getValueAt(i, 2).equals(uid)) {
tableModel.removeRow(i);
}
}
}
} catch (Exception e) {
}
}
}
} public static void main(String[] args) throws Exception {
Msg msg = new Msg();
msg.setVisible(true);
}
}
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import java.util.Map;
import java.util.UUID;import javax.swing.JFrame;import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.border.EtchedBorder;
import javax.swing.table.DefaultTableModel;import java.awt.SystemColor;
import javax.swing.ScrollPaneConstants;
import java.awt.Color;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JLabel;public class Msg extends JFrame {
private static final long serialVersionUID = 3170335398335303363L;
private String uname = "qq"; private DatagramSocket server;// UDP
private InetAddress broadcastAddress;// 廣播地址
private int port;// 監聽端口 private final Map<String, UserInfo> userTable = new Hashtable<String, UserInfo>();// 用戶列表
private final String guid = UUID.randomUUID().toString().replace("-", "").toUpperCase();// 本機唯一標識 private JTable table;
private JTextArea textArea;
private JLabel lblNewLabel_1; public Msg() throws SocketException {
this(5413);
} public Msg(int port) throws SocketException {
this.port = port; getContentPane().setLayout(null);
getContentPane().setBackground(SystemColor.control); JButton btnNewButton = new JButton("刷新");
btnNewButton.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
refresh();
}
});
btnNewButton.setBackground(SystemColor.control);
btnNewButton.setBounds(299, 119, 83, 28);
getContentPane().add(btnNewButton); JScrollPane scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setBounds(12, 12, 275, 135);
getContentPane().add(scrollPane); table = new JTable(new DefaultTableModel(new Object[][] { { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, }, new String[] { "\u7528\u6236\u540D", "IP", "GUID" }) {
private static final long serialVersionUID = -6259343924352571655L; public boolean isCellEditable(int row, int column) {
return false;
}
});
table.setBackground(new Color(255, 255, 255));
scrollPane.setViewportView(table);
table.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null)); JScrollPane scrollPane_1 = new JScrollPane();
scrollPane_1.setBounds(12, 159, 370, 104);
getContentPane().add(scrollPane_1); textArea = new JTextArea();
textArea.setLineWrap(true);
textArea.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if ((e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER) || (e.isAltDown() && e.getKeyCode() == KeyEvent.VK_S)) {
sendMessage();
}
}
});
scrollPane_1.setViewportView(textArea); JButton button = new JButton("發送");
button.setBackground(SystemColor.control);
button.setBounds(141, 275, 83, 28);
button.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
sendMessage();
}
});
getContentPane().add(button); JButton button_1 = new JButton("關閉");
button_1.setBackground(SystemColor.control);
button_1.setBounds(22, 275, 83, 28);
button_1.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
Msg.this.dispatchEvent(new WindowEvent(Msg.this, WindowEvent.WINDOW_CLOSING));
}
});
getContentPane().add(button_1); JLabel lblNewLabel = new JLabel("當前在線人數");
lblNewLabel.setBounds(299, 29, 83, 18);
getContentPane().add(lblNewLabel); lblNewLabel_1 = new JLabel("0");
lblNewLabel_1.setBounds(305, 59, 55, 18);
getContentPane().add(lblNewLabel_1);
JLabel lblNewLabel_2 = new JLabel("Alt+S或Ctrl+Enter發送");
lblNewLabel_2.setBounds(242, 280, 140, 18);
getContentPane().add(lblNewLabel_2); this.setSize(400, 348);
setBackground(SystemColor.control);
setResizable(false);
setTitle("局域網聊天");
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
sendBroadcast((guid + "2").getBytes(), broadcastAddress);
} catch (Exception e2) {
}
}
}); try { uname = JOptionPane.showInputDialog("請輸入你的暱稱");
uname = uname == null ? "匿名" : uname;
server = new DatagramSocket(port); broadcastAddress = InetAddress.getByName("255.255.255.255"); new AcceptBroadcastThread().start();// 啟動監聽
sendBroadcast((guid + "0" + uname).getBytes(), broadcastAddress);// 發送全網廣播,通知上線
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "端口" + port + "被佔用!");
System.exit(0);
}
} /**
* 向外發送數據
*
* @param data
* @param address
* @throws IOException
*/
public void sendBroadcast(byte[] data, InetAddress address) throws IOException {
DatagramPacket dp = new DatagramPacket(data, data.length, address, port);
server.send(dp);
} /**
* 刷新列表
*/
public void refresh() {
// 清空列表
userTable.clear();
DefaultTableModel tableModel = ((DefaultTableModel) table.getModel());
for (int j = table.getRowCount(); j > 0; j--) {
tableModel.removeRow(j - 1);
}
try {
sendBroadcast((guid + "3" + uname).getBytes(), broadcastAddress);// 重新發送全網廣播,通知上線
} catch (Exception e) {
}
} public void alertMessage(final String msg) {
new Thread() {
public void run() {
JOptionPane.showMessageDialog(Msg.this, msg);
};
}.start();
} /**
* 發送文字消息
*/
public void sendMessage() {
int[] selectRows = table.getSelectedRows();
DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
String msg = guid + "1" + textArea.getText();
byte[] data = string2Bytes(msg);
for (int i = 0, j = selectRows.length; i < j; i++) {
String key = (String) tableModel.getValueAt(selectRows[i], 2);
UserInfo ui = key == null ? null : userTable.get(key);
if (ui != null) {
try {
textArea.setText("");
sendBroadcast(data, ui.getIpAddress());
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "發送消息到" + ui.getName() + "(" + ui.getIpAddress().getHostAddress() + ")失敗!", "發送失敗", JOptionPane.ERROR_MESSAGE);
}
}
}
} private byte[] string2Bytes(String str) {
try {
return str.getBytes("UTF-8");
} catch (Exception e) {
}
return null;
} class UserInfo { private String guid;
private String name;
private InetAddress ipAddress; public String getGuid() {
return guid;
} public void setGuid(String guid) {
this.guid = guid;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public InetAddress getIpAddress() {
return ipAddress;
} public void setIpAddress(InetAddress ipAddress) {
this.ipAddress = ipAddress;
}
} class AcceptBroadcastThread extends Thread {
public void run() {
while (true) {
try {
DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);
server.receive(dp); String msg = new String(dp.getData(), 0, dp.getLength(), "UTF-8");// 解析廣播數據包
String uid = msg.substring(0, 32);
String type = msg.substring(32, 33); if (type.equals("0") || type.equals("3")) {
UserInfo ui = new UserInfo();
ui.setGuid(uid);
ui.setName(msg.substring(33));
ui.setIpAddress(dp.getAddress()); // 刷新請求,只響應不做其他處理
if (userTable.containsKey(ui.getGuid()) && type.equals("3")) {
sendBroadcast((guid + "0" + uname).getBytes(), broadcastAddress);
} // 上線通知
if (!userTable.containsKey(ui.getGuid())) {
userTable.put(ui.getGuid(), ui);// 將新用戶添加到用戶表
lblNewLabel_1.setText("" + userTable.size()); sendBroadcast((guid + "0" + uname).getBytes(), broadcastAddress);// 響應非本機廣播
((DefaultTableModel) table.getModel()).insertRow(0, new String[] { ui.getName(), ui.getIpAddress().getHostAddress(), ui.getGuid() });
}
} else if (type.equals("1")) {
UserInfo ui = userTable.get(uid);
alertMessage(ui.getName() + "(" + ui.getIpAddress().getHostAddress() + ")-" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\r\n" + msg.substring(33));
} else {
userTable.remove(uid);// 移除用戶
lblNewLabel_1.setText("" + userTable.size()); DefaultTableModel tableModel = ((DefaultTableModel) table.getModel());
for (int i = 0, j = table.getRowCount(); i < j; i++) {
if (tableModel.getValueAt(i, 2).equals(uid)) {
tableModel.removeRow(i);
}
}
}
} catch (Exception e) {
}
}
}
} public static void main(String[] args) throws Exception {
Msg msg = new Msg();
msg.setVisible(true);
}
}
public class Messenger extends JFrame {
private static final long serialVersionUID = 3170335398335303363L; private final String guid = UUID.randomUUID().toString().replace("-", "").toUpperCase(); private final int online = 0;
private final int offline = 1;
private final int message = 2;
private final int refresh = 3; private JScrollPane spUser;
private JTable tabUser;
private JButton btnRefresh;
private JPanel paSeparator;
private JScrollPane spEdit;
private JTextArea taEdit;
private JButton btnClose;
private JButton btnSend;
private JLabel lblOnline;
private JLabel lblOnlineNum; private DatagramSocket ds;
private String userName = "匿名";
private Map<String, User> userTable = new Hashtable<String, Messenger.User>();
private JLabel lblNewLabel; public Messenger() {
generateWindow();// 生成窗體
setUserName();// 設置用戶名
listen();// 開始監聽消息
broadcast(online);// 廣播上線消息
} /**
* 設置用戶名稱
*/
public void setUserName() {
String str = JOptionPane.showInputDialog("請輸入您的用戶名,最多6個字符");
if (str != null && str.trim().length() != 0) {
// userName = toUTF8(userName);
userName = str.trim();
if (userName.length() > 6) {
userName = userName.substring(0, 6);
}
}
} /**
* 發送消息
*/
public void send() {
try {
String msg = taEdit.getText();
taEdit.setText("");
byte[] data = (msg == null) ? (message + guid + "").getBytes("UTF-8") : (message + guid + msg).getBytes("UTF-8");
DatagramPacket dp = new DatagramPacket(data, data.length); DefaultTableModel dtm = (DefaultTableModel) tabUser.getModel();
for (int i : tabUser.getSelectedRows()) {
Object key = dtm.getValueAt(i, 2);
if (key != null) {
User user = userTable.get(key);
if (user != null) {
dp.setAddress(user.getInetAddress());
dp.setPort(5413); ds.send(dp);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 彈出消息盒子
*/
public void showMessage(final String uid, final String msg) {
new Thread() {
public void run() {
MessageBox mb = new MessageBox(userTable.get(uid), msg);
mb.setVisible(true);
};
}.start();
} /**
* 回复消息
*
* @param uid
*/
public void reply(String uid) {
DefaultTableModel dtm = (DefaultTableModel) tabUser.getModel();
for (int i = 0; i < tabUser.getRowCount(); i++) {
if (uid.equals(dtm.getValueAt(i, 2))) {
tabUser.setRowSelectionInterval(i, i);
}
}
taEdit.setFocusable(true);
} /**
* 刷新用戶列表
*/
public void refresh() {
// 清空用戶列表
userTable.clear();
// 清空表格
DefaultTableModel dtm = (DefaultTableModel) tabUser.getModel();
for (int i = tabUser.getRowCount(); i > 0; i--) {
dtm.removeRow(i - 1);
}
// 添加5個空行
for (int i = 0; i < 5; i++) {
dtm.addRow(new Object[] { null, null, null });
}
// 發送刷新廣播
broadcast(refresh);
} /**
* 新用戶上線
*
* @param user
*/
public void addUser(User user) {
userTable.put(user.getGuid(), user);
DefaultTableModel dtm = (DefaultTableModel) tabUser.getModel();
dtm.insertRow(0, new Object[] { user.getUserName(), user.getHostAddress(), user.getGuid() });
lblOnlineNum.setText(userTable.size() + "");
} /**
* 用戶下線
*
* @param uid
*/
public void removeUser(String uid) {
userTable.remove(uid);
DefaultTableModel dtm = (DefaultTableModel) tabUser.getModel();
for (int i = 0; i < tabUser.getRowCount(); i++) {
if (uid.equals(dtm.getValueAt(i, 2))) {
dtm.removeRow(i);
}
}
lblOnlineNum.setText(userTable.size() + "");
} /**
* 發送廣播消息
*/
public void broadcast(int flag) {
try {
if (ds != null) {
byte[] data = (flag + guid + userName).getBytes("UTF-8");
ds.send(new DatagramPacket(data, 0, data.length, InetAddress.getByName("255.255.255.255"), 5413));
}
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 監聽消息
*/
public void listen() {
try {
ds = new DatagramSocket(5413);// 啟動監聽器
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "5413端口被佔用", "錯誤", JOptionPane.ERROR_MESSAGE);
dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
return;
}
// 啟動一個線程開始監聽
new Thread() {
public void run() {
while (true) {
try {
DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);
ds.receive(dp);// 此方法會阻塞線程,直到收到消息 // 將發送過來的消息還原成字符串
String msg = new String(dp.getData(), 0, dp.getLength(), "UTF-8"); if (msg != null && msg.length() > 0) { int msgType = Integer.parseInt(msg.substring(0, 1));// 第1個字符為消息類型
String uid = msg.substring(1, 33);// 第2到33個字符為用戶唯一標識 switch (msgType) {
case 0:// 上線廣播
if (!userTable.containsKey(uid)) {
User user = new User();
user.setGuid(uid);
user.setUserName(msg.substring(33));// 如果是上線廣播則第33位以後就是用戶名
user.setInetAddress(dp.getAddress()); addUser(user);// 添加到用戶表中 // 發送響應
byte[] data = (online + guid + userName).getBytes("UTF-8");
DatagramPacket p = new DatagramPacket(data, data.length, dp.getAddress(), 5413);
ds.send(p);
}
break;
case 1:// 下線廣播
removeUser(uid);
break;
case 2:// 用戶消息
showMessage(uid, msg.substring(33));// 如果是用戶消息則第33位開始為用戶消息
break;
case 3:// 刷新廣播
if (!guid.equals(uid) || !userTable.containsKey(uid)) {
// 發送響應
byte[] data = (online + guid + userName).getBytes("UTF-8");
DatagramPacket p = new DatagramPacket(data, data.length, dp.getAddress(), 5413);
ds.send(p);
}
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}.start();
} /**
* 生成窗體
*/
private void generateWindow() {
setSize(415, 315);
setResizable(false);
setLocationRelativeTo(null);
setTitle("局域網聊天");
getContentPane().setLayout(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 窗體關閉事件,發送下線廣播
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
broadcast(offline);
if (ds != null) {
ds.close();
}
}
}); // 用戶列表滾動條
spUser = new JScrollPane();
spUser.setBounds(12, 12, 292, 102);
getContentPane().add(spUser); // 用戶列表
tabUser = new JTable(new DefaultTableModel(new Object[][] { { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, }, new String[] { "\u7528\u6236\u540D", "IP\u5730\u5740", "\u552F\u4E00\u6A19\u8B58" }) {
private static final long serialVersionUID = 8891200084509298048L;
private boolean[] columnEditables = new boolean[] { false, false, false }; public boolean isCellEditable(int row, int column) {
return columnEditables[column];
}
});
spUser.setViewportView(tabUser); // 文本編輯器滾動條
spEdit = new JScrollPane();
spEdit.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
spEdit.setBounds(12, 126, 383, 102);
getContentPane().add(spEdit); // 文本編輯區
taEdit = new JTextArea();
taEdit.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if ((e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER) || (e.isAltDown() && e.getKeyCode() == KeyEvent.VK_S)) {
send();
}
}
});
taEdit.setLineWrap(true);
spEdit.setViewportView(taEdit); // 分隔條
paSeparator = new JPanel();
paSeparator.setBorder(new EtchedBorder(EtchedBorder.RAISED, null, null));
paSeparator.setBounds(12, 117, 383, 5);
getContentPane().add(paSeparator); // 刷新按鈕
btnRefresh = new JButton("刷新");
btnRefresh.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
refresh();
}
});
btnRefresh.setBounds(316, 77, 79, 28);
getContentPane().add(btnRefresh); // 關閉按鈕
btnClose = new JButton("關閉");
btnClose.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
Messenger.this.dispatchEvent(new WindowEvent(Messenger.this, WindowEvent.WINDOW_CLOSING));
}
});
btnClose.setBounds(12, 240, 98, 28);
getContentPane().add(btnClose); // 發送按鈕
btnSend = new JButton("發送");
btnSend.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
send();
}
});
btnSend.setBounds(297, 240, 98, 28);
getContentPane().add(btnSend); // 當前在線人數標籤
lblOnline = new JLabel("當前在線人數");
lblOnline.setBounds(316, 13, 79, 28);
getContentPane().add(lblOnline); // 當前在線人數
lblOnlineNum = new JLabel("0");
lblOnlineNum.setHorizontalAlignment(SwingConstants.CENTER);
lblOnlineNum.setBounds(326, 42, 55, 18);
getContentPane().add(lblOnlineNum); lblNewLabel = new JLabel("Alt + S 或 Ctrl + Enter 發送");
lblNewLabel.setBounds(128, 245, 158, 18);
getContentPane().add(lblNewLabel);
}
* 消息盒子
*
* @author 小綿羊
*/
class MessageBox extends JFrame {
private static final long serialVersionUID = -2027863244344802324L; private JPanel panel;
private JLabel lblInfo;
private JLabel lblTime;
private JScrollPane scrollPane;
private JTextArea taMessage;
private JButton btnClose;
private JButton btnReply;
private User user;
private String msg;
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public MessageBox(User user, String msg) {
this.user = user;
this.msg = msg;
generateWindow();
} /**
* 生成消息窗體
*/
private void generateWindow() {
setSize(415, 315);
setResizable(false);
setLocationRelativeTo(null);
setTitle("收到消息");
getContentPane().setLayout(null);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); panel = new JPanel();
panel.setBorder(new TitledBorder(new TitledBorder(null, "\u6D88\u606F\u4F86\u81EA...", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 70, 213)), "", TitledBorder.LEADING, TitledBorder.TOP, null, Color.BLACK));
panel.setBounds(10, 10, 389, 73);
panel.setLayout(null);
getContentPane().add(panel); lblInfo = new JLabel(user.toString());
lblInfo.setHorizontalAlignment(SwingConstants.CENTER);
lblInfo.setBounds(12, 15, 365, 18);
panel.add(lblInfo); lblTime = new JLabel("時間:" + format.format(new Date()));
lblTime.setHorizontalAlignment(SwingConstants.CENTER);
lblTime.setBounds(12, 45, 365, 16);
panel.add(lblTime); scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setBounds(10, 94, 389, 141);
getContentPane().add(scrollPane); taMessage = new JTextArea(msg);
taMessage.setLineWrap(true);
taMessage.setEditable(false);
scrollPane.setViewportView(taMessage); btnClose = new JButton("關閉");
btnClose.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
MessageBox.this.dispatchEvent(new WindowEvent(MessageBox.this, WindowEvent.WINDOW_CLOSING));
}
});
btnClose.setBounds(65, 245, 98, 28);
getContentPane().add(btnClose); btnReply = new JButton("回复");
btnReply.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
MessageBox.this.dispatchEvent(new WindowEvent(MessageBox.this, WindowEvent.WINDOW_CLOSING));
Messenger.this.reply(user.getGuid());
}
});
btnReply.setBounds(253, 245, 98, 28);
getContentPane().add(btnReply);
}
} class User {
private String guid;
private String userName;
private String hostAddress;
private InetAddress inetAddress; public String getGuid() {
return guid;
} public void setGuid(String guid) {
this.guid = guid;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public String getHostAddress() {
return hostAddress;
} public InetAddress getInetAddress() {
return inetAddress;
} public void setInetAddress(InetAddress inetAddress) {
this.inetAddress = inetAddress;
this.hostAddress = inetAddress.getHostAddress();
} public String toString() {
return userName + "(" + hostAddress + ")";
}
} public static void main(String[] args) {
new Messenger().setVisible(true);
}
}