zoukankan      html  css  js  c++  java
  • 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("
    ");
                        }
            } 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();
            }
        }
    }
    



  • 相关阅读:
    C++虚函数机制(转)
    C/C++中extern关键字详解(转)
    (转)Javascript定义类(class)的三种方法
    使用HtmlAgilityPack实现对网页内容的抓取
    (转)Lucene Document getBoost(float) 和 setBoost(float)
    (转)Ajax中Get请求与Post请求的区别
    (转)Lucene.net实现自定义排序
    Lucene.net基本功能核心代码
    (转)使用Lucene.Net实现全文检索
    C#将html table 导出成excel
  • 原文地址:https://www.cnblogs.com/emoji/p/4436864.html
Copyright © 2011-2022 走看看