用Java编写的聊天室程序,具有用户界面和服务器界面
首现,服务器代码:
package com.niit.chatroom;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import org.dyno.visual.swing.layouts.Constraints;
import org.dyno.visual.swing.layouts.GroupLayout;
import org.dyno.visual.swing.layouts.Leading;
//VS4E -- DO NOT REMOVE THIS LINE!
public class Server extends JFrame {
private static final long serialVersionUID = 1L;
private JMenuItem jMenuItem0;
private JMenu jMenu0;
private JMenuBar jMenuBar0;
private JLabel jLabel0;
private JLabel jLabel1;
private JTextArea jTextArea0;
private JScrollPane jScrollPane0;
private JList jList0;
private JScrollPane jScrollPane1;
private static final String PREFERRED_LOOK_AND_FEEL = "javax.swing.plaf.metal.MetalLookAndFeel";
List
ServerSocket ss = null;
boolean flag = false;
public Server() {
initComponents();
}
private void initComponents() {
setLayout(new GroupLayout());
add(getJLabel1(), new Constraints(new Leading(3, 448, 10, 10), new Leading(0, 12, 12)));
add(getJLabel0(), new Constraints(new Leading(469, 128, 12, 12), new Leading(0, 12, 12)));
add(getJScrollPane1(), new Constraints(new Leading(461, 136, 12, 12), new Leading(20, 452, 10, 10)));
add(getJScrollPane0(), new Constraints(new Leading(0, 454, 12, 12), new Leading(19, 453, 12, 12)));
setJMenuBar(getJMenuBar0());
setSize(600, 500);
setResizable(false);
}
private JScrollPane getJScrollPane1() {
if (jScrollPane1 == null) {
jScrollPane1 = new JScrollPane();
jScrollPane1.setViewportView(getJList0());
}
return jScrollPane1;
}
DefaultListModel listModel = new DefaultListModel();
private JList getJList0() {
if (jList0 == null) {
jList0 = new JList();
jList0.setModel(listModel);
}
return jList0;
}
private JScrollPane getJScrollPane0() {
if (jScrollPane0 == null) {
jScrollPane0 = new JScrollPane();
jScrollPane0.setViewportView(getJTextArea0());
}
return jScrollPane0;
}
private JTextArea getJTextArea0() {
if (jTextArea0 == null) {
jTextArea0 = new JTextArea();
jTextArea0.setEditable(false);
jTextArea0.setLineWrap(true);
jTextArea0.setWrapStyleWord(true);
}
return jTextArea0;
}
private JLabel getJLabel1() {
if (jLabel1 == null) {
jLabel1 = new JLabel();
jLabel1.setText("用户聊天记录");
}
return jLabel1;
}
private JLabel getJLabel0() {
if (jLabel0 == null) {
jLabel0 = new JLabel();
jLabel0.setText("在线用户");
}
return jLabel0;
}
private JMenuBar getJMenuBar0() {
if (jMenuBar0 == null) {
jMenuBar0 = new JMenuBar();
jMenuBar0.add(getJMenu0());
}
return jMenuBar0;
}
private JMenu getJMenu0() {
if (jMenu0 == null) {
jMenu0 = new JMenu();
jMenu0.setText("jMenu0");
jMenu0.add(getJMenuItem0());
}
return jMenu0;
}
private JMenuItem getJMenuItem0() {
if (jMenuItem0 == null) {
jMenuItem0 = new JMenuItem();
jMenuItem0.setText("jMenuItem0");
}
return jMenuItem0;
}
private static void installLnF() {
try {
String lnfClassname = PREFERRED_LOOK_AND_FEEL;
if (lnfClassname == null)
lnfClassname = UIManager.getCrossPlatformLookAndFeelClassName();
UIManager.setLookAndFeel(lnfClassname);
} catch (Exception e) {
System.err.println("Cannot install " + PREFERRED_LOOK_AND_FEEL
+ " on this platform:" + e.getMessage());
}
}
public static void main(String[] args) {
final Server frame = new Server();
installLnF();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setDefaultCloseOperation(Server.EXIT_ON_CLOSE);
frame.setTitle("服务器");
frame.getContentPane().setPreferredSize(frame.getSize());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
frame.start();
}
public void start() {
try {
ss = new ServerSocket(8888);
flag = true;
} catch (BindException e) {
jTextArea0.setText("此端口已使用");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
try {
while (flag) {
Socket s = ss.accept();
jTextArea0.append("用户" + s.getInetAddress() + "接入 /n");
// listModel.addElement(s.getInetAddress());
Client c = new Client(s);
clients.add(c);
new Thread(c).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class Client implements Runnable {
private Socket s = null;
private DataInputStream dis = null;
private DataOutputStream dos = null;
private boolean connectflag = false;
public Client(Socket s) {
this.s = s;
try {
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
connectflag = true;
} catch (IOException e) {
e.printStackTrace();
}
}
String allname = null;
public void run() {
try {
while (connectflag) {
String name = dis.readUTF();
String str = dis.readUTF();
jTextArea0.append(name+" 说:"+str+"/n");
allname = allname + name + ":";
for (int i = 0; i < clients.size(); i++) {
Client c = clients.get(i);
c.dos.writeUTF(name);
c.dos.writeUTF(str);
c.dos.writeUTF(allname);
}
}
} catch (IOException e11) {
clients.remove(this);
jTextArea0.append("用户" + s.getInetAddress() + "离开/n");
listModel.removeElement(s.getInetAddress());
} finally {
try {
dis.close();
dos.flush();
dos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
下图为服务器效果界面
用户端代码
package com.niit.chatroom;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import org.dyno.visual.swing.layouts.Constraints;
import org.dyno.visual.swing.layouts.GroupLayout;
import org.dyno.visual.swing.layouts.Leading;
//VS4E -- DO NOT REMOVE THIS LINE!
public class Client extends JFrame implements ActionListener,KeyListener{
private static final long serialVersionUID = 1L;
private JMenuItem jMenuItem0;
private JMenu jMenu0;
private JMenuBar jMenuBar0;
private JLabel jLabel0;
private JLabel jLabel1;
private JButton jButton0;
private JComboBox jComboBox0;
private JTextArea jTextArea1;
private JScrollPane jScrollPane1;
private JLabel jLabel2;
private static JTextArea jTextArea2;
private JScrollPane jScrollPane2;
static OutputStream os = null;
private JList jList0;
private JScrollPane jScrollPane0;
private static String setname = null;
private static final String PREFERRED_LOOK_AND_FEEL = "javax.swing.plaf.metal.MetalLookAndFeel";
public Client(String setname) {
this.setname = setname;
initComponents();
jButton0.addActionListener(this);
jTextArea1.addKeyListener(this);
}
private void initComponents() {
setLayout(new GroupLayout());
add(getJLabel0(), new Constraints(new Leading(467, 130, 10, 10), new Leading(3, 19, 10, 10)));
add(getJLabel2(), new Constraints(new Leading(4, 453, 10, 10), new Leading(334, 12, 12)));
add(getJScrollPane2(), new Constraints(new Leading(3, 454, 12, 12), new Leading(21, 312, 10, 10)));
add(getJLabel1(), new Constraints(new Leading(6, 449, 12, 12), new Leading(0, 16, 12, 12)));
add(getJScrollPane1(), new Constraints(new Leading(2, 381, 12, 12), new Leading(357, 114, 12, 12)));
add(getJButton0(), new Constraints(new Leading(389, 70, 12, 12), new Leading(422, 49, 10, 10)));
add(getJComboBox0(), new Constraints(new Leading(389, 70, 12, 12), new Leading(358, 54, 10, 10)));
add(getJScrollPane0(), new Constraints(new Leading(467, 130, 12, 12), new Leading(21, 450, 12, 12)));
setJMenuBar(getJMenuBar0());
setSize(600, 500);
setResizable(false);
}
private JScrollPane getJScrollPane0() {
if (jScrollPane0 == null) {
jScrollPane0 = new JScrollPane();
jScrollPane0.setViewportView(getJList0());
// jScrollPane0.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
// jScrollPane0.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
}
return jScrollPane0;
}
static DefaultListModel listModel = new DefaultListModel();
private JList getJList0() {
if (jList0 == null) {
jList0 = new JList();
jList0.setModel(listModel);
}
return jList0;
}
private JScrollPane getJScrollPane2() {
if (jScrollPane2 == null) {
jScrollPane2 = new JScrollPane();
jScrollPane2.setViewportView(getJTextArea2());
}
return jScrollPane2;
}
private JTextArea getJTextArea2() {
if (jTextArea2 == null) {
jTextArea2 = new JTextArea();
jTextArea2.setEditable(false);
jTextArea2.setLineWrap(true);
jTextArea2.setWrapStyleWord(true);
}
return jTextArea2;
}
private JLabel getJLabel2() {
if (jLabel2 == null) {
jLabel2 = new JLabel();
jLabel2.setText("输入框");
}
return jLabel2;
}
private JScrollPane getJScrollPane1() {
if (jScrollPane1 == null) {
jScrollPane1 = new JScrollPane();
jScrollPane1.setViewportView(getJTextArea1());
jScrollPane1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
}
return jScrollPane1;
}
private JTextArea getJTextArea1() {
if (jTextArea1 == null) {
jTextArea1 = new JTextArea();
jTextArea1.setLineWrap(true);
jTextArea1.setWrapStyleWord(true);
}
return jTextArea1;
}
private JComboBox getJComboBox0() {
if (jComboBox0 == null) {
jComboBox0 = new JComboBox();
jComboBox0.setModel(new DefaultComboBoxModel(new Object[] { "群聊", "私聊"}));
jComboBox0.setDoubleBuffered(false);
jComboBox0.setBorder(null);
}
return jComboBox0;
}
private JButton getJButton0() {
if (jButton0 == null) {
jButton0 = new JButton();
jButton0.setText("发送");
}
return jButton0;
}
private JLabel getJLabel1() {
if (jLabel1 == null) {
jLabel1 = new JLabel();
jLabel1.setText("群聊中");
}
return jLabel1;
}
private JLabel getJLabel0() {
if (jLabel0 == null) {
jLabel0 = new JLabel();
jLabel0.setText("在线好友");
}
return jLabel0;
}
private JMenuBar getJMenuBar0() {
if (jMenuBar0 == null) {
jMenuBar0 = new JMenuBar();
jMenuBar0.add(getJMenu0());
}
return jMenuBar0;
}
private JMenu getJMenu0() {
if (jMenu0 == null) {
jMenu0 = new JMenu();
jMenu0.setText("运行");
jMenu0.add(getJMenuItem0());
}
return jMenu0;
}
private JMenuItem getJMenuItem0() {
if (jMenuItem0 == null) {
jMenuItem0 = new JMenuItem();
jMenuItem0.setText("设置用户名");
}
return jMenuItem0;
}
private static void installLnF() {
try {
String lnfClassname = PREFERRED_LOOK_AND_FEEL;
if (lnfClassname == null)
lnfClassname = UIManager.getCrossPlatformLookAndFeelClassName();
UIManager.setLookAndFeel(lnfClassname);
} catch (Exception e) {
System.err.println("Cannot install " + PREFERRED_LOOK_AND_FEEL
+ " on this platform:" + e.getMessage());
}
}
static int i = 0;
public static void main(String[] args) {
final Client frame = new Client("小王");
installLnF();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setDefaultCloseOperation(Client.EXIT_ON_CLOSE);
frame.setTitle("聊天窗口");
frame.getContentPane().setPreferredSize(frame.getSize());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
try{
Socket s = new Socket("127.0.01",8888);
jTextArea2.append("已连接到服务器/n");
os = s.getOutputStream();
InputStream is = s.getInputStream();
new Thread(frame.new ReadThread(is)).start();
}catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class ReadThread implements Runnable{
private InputStream is;
public ReadThread(InputStream is){
this.is= is;
}
public void run(){
DataInputStream dis = new DataInputStream(is);
String str = null;
String name = null;
String all = null;
try{
while(true){
name = dis.readUTF();
str = dis.readUTF();
all = dis.readUTF();
String[] users = all.split(":");
jList0 = new JList(users);
jTextArea2.append(name+ " 说: "+str+"/n");
}
}catch(IOException e){
e.printStackTrace();
}
finally{
try {
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void keyTyped(KeyEvent e) {}
public void keyPressed(KeyEvent e) {
int nKeyCode = e.getKeyCode();
if(nKeyCode == KeyEvent.VK_ENTER){
process();
}
}
public void keyReleased(KeyEvent e) {}
public void actionPerformed(ActionEvent e) {
process();
}
public void process(){
DataOutputStream dos = null;
try {
dos = new DataOutputStream(os);
dos.writeUTF(setname);
dos.writeUTF(jTextArea1.getText());
jTextArea1.setText(null);
} catch (IOException e) {
e.printStackTrace();
}
}
}
这两部分都通过测试,但是功能有待提高,现在只能群聊,客户端设置好自己的名字后,可以和别人聊天。现在我想实现的功能是用户上下线时服务器端和客户端能够及时更新用户列表,如果这个功能实现之后,还行能实现私聊功能,望各位高手指导。。谢谢