java实现多人在线聊天室

先放效果图:



登陆:


/**在本类109行附近调用了ChatClient类
 *
 */

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
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;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;


public class ClientLogin extends JFrame  {
    private JTextField nametext  ;
    private JPasswordField passwordtetx ;
    //private Object bPanel;
   
    public ClientLogin()  {
        this.init() ;       //init方法初始化
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);
    }
   
    public void init()  {
        this.setTitle("呆萌聊天室登陆");
        this.setSize(330,230);     //借用成熟美观尺寸
        int y = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight() ;
        int x = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth() ;
                /**以上的方法要是不借助Eclipse实在是很难记住,尼玛!
                 *
                 */
      this.setLocation( (x-this.getWidth() )/2, ( y-this.getHeight() )/2 );
      this.setResizable(false);     //不允许用户自行更改大小
      Icon icon = new ImageIcon("d:"+File.separator+"login.jpg") ;
      JLabel label = new JLabel(icon) ;   //设置登陆界面上边框
      this.add(label,BorderLayout.NORTH) ;
     
      JPanel mainPanel = new JPanel() ;
      Border border = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED) ;
      mainPanel.setBorder(BorderFactory.createTitledBorder(border,"输入登陆信息",TitledBorder.CENTER,TitledBorder.TOP)) ;
      this.add(mainPanel,BorderLayout.CENTER) ;     //将主面板加入frame
      mainPanel.setLayout(null) ;
      JLabel namelabel = new JLabel("请输入昵称") ;
      namelabel.setBounds(30,30,80,22) ;
      mainPanel.add(namelabel) ;
      nametext = new JTextField() ;
      nametext.setBounds(115,30,120,22);
      mainPanel.add(nametext) ;
      JLabel passwordlabel = new JLabel("请输入密码") ;
      passwordlabel.setBounds(30,60,80,22);
      mainPanel.add(passwordlabel) ;
      passwordtetx = new JPasswordField() ;
      passwordtetx.setBounds(115,60,120,22) ;
      mainPanel.add(passwordtetx) ;
     
      //接下来按钮位置排放
     JPanel bPanel = new JPanel() ;
     bPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)) ;
     this.add(bPanel,BorderLayout.SOUTH) ;
     JButton reset = new JButton("重置") ;
     reset.addActionListener(new ActionListener()  {    //为“重置”按钮添加事件监听
         public void actionPerformed(ActionEvent e)  {
             nametext.setText("");
             passwordtetx.setText("");
         }
         });
     bPanel.add(reset) ;
     
     /**下面开始实现提交按钮
      *
      */
     
     JButton submit = new JButton("登陆") ;
     submit.addActionListener(new LoginAction(this) );  //因为登陆相对复杂,重新为登陆写一个类
     bPanel.add(submit) ;
}
      


/**下面开始写登陆类
 *
 */

class LoginAction implements ActionListener  {
    private JFrame self ;
    public LoginAction(JFrame self)  {
        this.self = self ;
    }
   
    public void actionPerformed(ActionEvent e)  {
        //System.out.println("用户名是:"+nametext.getText()+" 密码是:"+new String(passwordtext.getPassword())) ;
        try  {
            //开始连接到服务器
            Socket socket = new Socket("127.0.0.1",8888) ;
            new ChatClient(socket,nametext.getText()) ;
            //调用dispose方法关闭登陆框
            self.dispose();
        }catch(UnknownHostException e1)  {
            e1.printStackTrace();
            JOptionPane.showConfirmDialog(self, "找不到指定服务器!~","连接失败",JOptionPane.OK_OPTION,JOptionPane.ERROR_MESSAGE) ;
        }catch(IOException e1)  {
            e1.printStackTrace() ;
            JOptionPane.showConfirmDialog(self, "连接服务器出错,请重试!","连接失败",JOptionPane.OK_OPTION,JOptionPane.ERROR_MESSAGE) ;
        }
    }
}
    public static void main(String args[])  {
        new ClientLogin() ;
    }
}



客户端:

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Date;
import java.text.SimpleDateFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;


public class ChatClient extends JFrame {
    private Socket socket ;                  //负责和服务器通信
    private JTextArea sendArea ;        //消息编辑区域
    private JTextArea contentArea ;   //群聊消息显示框
    private String name ;                   //当前用户名称
   
    public ChatClient(Socket socket,String name)  {
        this.socket = socket ;
        this.name  = name ;
        this.init()   ;       //初始化聊天客户端
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);
       
        /*接下来启动单独线程,专门从服务器中读取数据
         *
         */
       
        ClientThread thread  = new ClientThread(socket,contentArea) ;
        thread.start();
    }
   
public void init( )  {
        this.setTitle("我的聊天室");
        this.setSize(300,400);
        int x = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth() ;
        int y = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight() ;
       
        this.setLocation( (x-this.getWidth() )/2, ( y-this.getHeight() )/2 );
        this.setResizable(false);      //不允许用户改变大小
       
        contentArea = new JTextArea() ;
        contentArea.setLineWrap(true);  //换行方法
        JScrollPane logPanel  = new JScrollPane(contentArea,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER ) ;
       
        sendArea = new JTextArea() ;
        sendArea.setLineWrap(true);    //控制每行显示长度最大不超过界面长度
        JScrollPane sendPanel  = new JScrollPane(sendArea,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER ) ;
       
        //创建一个分隔窗格
        JSplitPane splitpane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,logPanel,sendPanel) ;
        splitpane.setDividerLocation(250);
        this.add(splitpane,BorderLayout.CENTER) ;
       
        //按钮面板
       
        JPanel bPanel  = new JPanel() ;
        bPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)) ;
        this.add(bPanel,BorderLayout.SOUTH) ;
       
        JLabel namelabel = new JLabel("昵称: "+this.name+"  ") ;
        bPanel.add(namelabel) ;
       
        JButton closeButton = new JButton("关闭") ;
        closeButton.addActionListener( new ActionListener( )  {
            public void actionPerformed(ActionEvent e)  {
               
            }
        });
        bPanel.add(closeButton) ;
       
        JButton sendButton = new JButton("发送") ;
       
        sendButton.addActionListener(new ActionListener() {
            //@Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                String str = sendArea.getText() ;
                SimpleDateFormat formater = new SimpleDateFormat("HH:mm:ss") ;
                String time  = formater.format(new Date() ) ;
                String sendStr = name+" "+time+" 说: "+str ;
                PrintWriter out = null ;
                try  {
                    out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream() ) ) ;
                    out.println(sendStr) ;
                    out.flush();
                }catch(Exception e1)  {
                    e1.printStackTrace();
                }
                sendArea.setText("");
            }
        });
       
        bPanel.add(sendButton) ;   
    }

}

//客户端与服务器端通信的线程类
class ClientThread extends Thread  {
    private Socket socket ;
    private JTextArea contentArea ;
   
    public ClientThread(Socket socket, JTextArea  conteArea)  {
        this.socket = socket ;
        this.contentArea = conteArea ;
    }
   
    public void run()  {
        BufferedReader br = null ;
        try  {
            br = new BufferedReader(new InputStreamReader( socket.getInputStream())) ;
            String str = null ;
                    while( (str = br.readLine()) != null)  {
                        System.out.println(str) ;
                        contentArea.append(str);
                        contentArea.append("\n");
                    }
        } catch(IOException e)  {
            e.printStackTrace();
        } finally  {
            if(br != null)  {
                try  {
                    br.close () ;
                }catch(IOException e) {
                e.printStackTrace();
            }
        }
    }
}}

服务器端:

import java.util.List;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;


public class ChatServer {
    private List<Socket> sockets = new ArrayList<Socket>() ;    //类集的应用
    public ChatServer() throws IOException  {
        ServerSocket ss = new ServerSocket(8888) ;
        System.out.println("服务器已在监听8888端口") ;
       
        while(true)  {
            Socket socket = ss.accept() ;
            sockets.add(socket) ;
            String ip = socket.getInetAddress().getHostAddress() ;
            System.out.println("新用户进入!ip是"+ip) ;
            Thread thread = new Thread(new ServerRunner(sockets,socket)) ;
            thread.start();
        }
    }
 
    public static void main(String args[])  {
        try {
            new ChatServer() ;
        } catch(Exception e)  {
            e.printStackTrace();
        }
    }

}

class ServerRunner implements Runnable  {
    private List<Socket> sockets ;
    private Socket currentSocket ;   //当前socket
   
    public ServerRunner (List<Socket> sockets,Socket currentSocket)  {
        this.sockets = sockets ;
        this.currentSocket = currentSocket ;
    }
   
    public void run()  {
        String ip = currentSocket.getInetAddress().getHostAddress() ;
        BufferedReader br = null ;
        try  {
            br = new BufferedReader(new InputStreamReader(currentSocket.getInputStream())) ;
            String str = null ;
            while((str = br.readLine()) != null)  {
                System.out.println(ip+"说"+str) ;
                //往所有的客户端写入信息
               
                for(Socket temp : sockets)  {
                    PrintWriter pw = new PrintWriter(new OutputStreamWriter(temp.getOutputStream())) ;
                    pw.println(str) ;
                    pw.flush();
                }
            }
        }catch(IOException e)  {
            e.printStackTrace();
        }
    }
}



posted @ 2014-11-25 15:16  emoji  阅读(2431)  评论(0编辑  收藏  举报