java聊天室群聊及私聊实现!
生活随笔
收集整理的這篇文章主要介紹了
java聊天室群聊及私聊实现!
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
java聊天室群聊及私聊實(shí)現(xiàn)!
一:業(yè)務(wù)邏輯
二:類(lèi)設(shè)計(jì)及代碼結(jié)構(gòu)
三:代碼
Mymessage類(lèi)代碼:
signup類(lèi)代碼:
package objtalk;/*創(chuàng)建一張talk數(shù)據(jù)表* 表結(jié)構(gòu)為usename和password* */import java.awt.event.ActionEvent;import java.awt.event.ActionListener; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException;import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextField;import com.mysql.jdbc.Connection; import com.mysql.jdbc.Statement;public class signup extends JFrame{private JTextField usename = new JTextField();//文本輸入框private JTextField password = new JTextField();private JButton signup = new JButton("注冊(cè)");//按鈕private JButton signin = new JButton("登陸");//數(shù)據(jù)庫(kù)信息private String user = "";private String pwd = "";private String url = "";//jdbc:myaql://ip或端口號(hào)/需要打開(kāi)的databaseprivate boolean tag = false;//判斷賬號(hào)密碼是否正確public signup() {// TODO Auto-generated constructor stubthis.setSize(300,400);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(EXIT_ON_CLOSE);this.setLayout(null);this.add(usename);this.add(password);this.add(signin);this.add(signup);usename.setSize(100,30);password.setSize(100,30);signin.setSize(100,50);signup.setSize(100,50);usename.setLocation(100,100);password.setLocation(100,200);signin.setLocation(50,300);signup.setLocation(150,300);try {Class.forName("com.mysql.jdbc.Driver");//開(kāi)啟數(shù)據(jù)庫(kù)} catch (ClassNotFoundException e2) {// TODO Auto-generated catch blocke2.printStackTrace();}signin.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String useName = usename.getText().toString();String passWord = password.getText().toString();if(useName.isEmpty()||passWord.isEmpty()){JOptionPane.showMessageDialog(null, "請(qǐng)輸入用戶名或密碼", "error",JOptionPane.ERROR_MESSAGE);}else{try {Connection con = (Connection) DriverManager.getConnection(url, user, pwd);//數(shù)據(jù)庫(kù)連Statement stmt = (Statement) con.createStatement();//創(chuàng)建語(yǔ)句對(duì)象String sql = "select * from talk";//數(shù)據(jù)庫(kù)語(yǔ)句ResultSet rs = (ResultSet) stmt.executeQuery(sql);//執(zhí)行語(yǔ)句得到結(jié)果,以行的角度表現(xiàn)查詢結(jié)果java.sql.ResultSetMetaData rsmd = rs.getMetaData();//結(jié)果以列的形式展現(xiàn)while(rs.next()){//按行逐個(gè)讀取查詢的內(nèi)容,next()表示行的移動(dòng)if(rs.getString(1).equals(useName)&&rs.getString(2).equals(passWord)){tag = true;new SocketFrame().setVisible(true);//跳轉(zhuǎn)到主界面exits();//關(guān)閉當(dāng)前界面return;}}if(tag==false){JOptionPane.showMessageDialog(null, "賬號(hào)密碼錯(cuò)誤!", "error",JOptionPane.ERROR_MESSAGE);}} catch (SQLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}});signup.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubString useName = usename.getText().toString();String passWord = password.getText().toString();if(useName.isEmpty()||passWord.isEmpty()){JOptionPane.showMessageDialog(null, "請(qǐng)輸入用戶名或密碼", "error",JOptionPane.ERROR_MESSAGE);}else{Connection con;try {con = (Connection) DriverManager.getConnection(url, user, pwd);Statement stmt = (Statement) con.createStatement();String sql = "insert talk value('"+useName+"','"+passWord+"');";stmt.executeUpdate(sql);JOptionPane.showMessageDialog(null,"注冊(cè)成功", "done",JOptionPane.ERROR_MESSAGE);//stmt.executeQuery(sql);//執(zhí)行語(yǔ)句得到結(jié)果,以行的角度表現(xiàn)查詢結(jié)果} catch (SQLException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}//數(shù)據(jù)庫(kù)連接,Connection是接口不能用new}}});}public void exits() {this.setVisible(false);}public static void main(String[] args) {new signup().setVisible(true);} }SocktFrame類(lèi)代碼
package objtalk;import java.awt.BorderLayout; import java.awt.Font; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedWriter; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.net.SocketAddress; import java.nio.channels.NonWritableChannelException; import java.nio.channels.SelectableChannel; import java.util.ArrayList; import java.util.List;import javax.imageio.ImageIO; import javax.lang.model.element.Element; import javax.swing.AbstractListModel; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.event.AncestorListener; import javax.swing.event.ListSelectionListener; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.text.BadLocationException; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument;public class SocketFrame extends JFrame {private JTextPane jtpMes = new JTextPane();//消息框private StyledDocument contentDoc = jtpMes.getStyledDocument();//取出文本(),屬性定義(sas的容器)private JScrollPane jspMes = new JScrollPane(jtpMes);//為消息框添加滑動(dòng)框private JButton btnSend = new JButton("Send");private JButton btnConnect = new JButton("Connect");private JButton btnSelectimg = new JButton("img");private JTextPane jtpNewMes = new JTextPane();//消息框(可以顯示圖片和文字)private JScrollPane jspNewMes = new JScrollPane(jtpNewMes);//為群聊框添加滑動(dòng)框private StyledDocument sendDoc = jtpNewMes.getStyledDocument();private JPanel panSend = new JPanel();JPanel btnPan = new JPanel();private Font font = new Font("宋體", Font.PLAIN, 20);private JList<String> listClient = new JList<>();private JScrollPane jspClientList = new JScrollPane(listClient);private Socket socket;private ObjectOutputStream out;private ReadThread reader;//讀取消息線程public SocketFrame() {this.setSize(800, 600);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(EXIT_ON_CLOSE);init();getContentPane().add(jspMes);getContentPane().add(panSend, BorderLayout.SOUTH);getContentPane().add(jspClientList, BorderLayout.EAST);}public void updateListClient(ArrayList list) {//跟新群聊用戶信息listClient.setModel(new ClientListModel(list));}class ClientListModel extends AbstractListModel {//更新list信息ArrayList list;public ClientListModel(ArrayList list) {super();this.list = list;}@Overridepublic Object getElementAt(int arg0) {return list.get(arg0);}@Overridepublic int getSize() {return list.size();}}private void init() {panSend.setLayout(new BorderLayout());panSend.add(jspNewMes,BorderLayout.CENTER);panSend.add(btnPan,BorderLayout.EAST);btnPan.add(btnSend);btnPan.add(btnConnect);btnPan.add(btnSelectimg);jtpMes.setEditable(false);jtpMes.setFont(font);jtpNewMes.setFont(font);btnSend.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent arg0) {String str = jtpNewMes.getText().trim();//得到文本System.out.println(str);if (str != null && str.length() > 0 && socket != null) {SocketAddress address = socket.getRemoteSocketAddress();//得到本地地址String ip = address.toString().substring(1,address.toString().indexOf(":") + 1);//獲得ipSimpleAttributeSet sas = new SimpleAttributeSet();//容器存儲(chǔ)消息體StyleConstants.setFontSize(sas,24);//設(shè)置字體try {/*senDoc消息內(nèi)容會(huì)自動(dòng)從輸入消息框獲取(綁定更新,50行57行代碼實(shí)現(xiàn)),這里只是在消息前面添加ip(類(lèi)似用戶名)*/sendDoc.insertString(0, ip, sas);} catch (BadLocationException e) {// TODO Auto-generated catch blocke.printStackTrace();}MyMessage mes = new MyMessage(true,MyMessage.MES_TYPE_PLAIN);mes.setContent(sendDoc);sendMes(mes);//發(fā)送消息try {sendDoc.remove(0, sendDoc.getLength());//去除容器中的內(nèi)容} catch (BadLocationException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}});btnConnect.addActionListener(new ActionListener() {//連接服務(wù)器@Overridepublic void actionPerformed(ActionEvent arg0) {if(socket==null){try {socket = new Socket("10.117.45.114", 12345);//具體ip自己設(shè)置reader = new ReadThread(socket);reader.start();out = new ObjectOutputStream(socket.getOutputStream());//創(chuàng)建消息輸入流} catch (Exception e) {e.printStackTrace();}}}});btnSelectimg.addActionListener(new ActionListener() {//選區(qū)本地圖片存入容器@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubJFileChooser fc = new JFileChooser("d:");//文件選擇器FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & GIF Image", "jpg","gif");//文件篩選器fc.setFileFilter(filter);int i = fc.showOpenDialog(SocketFrame.this);if(i == JFileChooser.APPROVE_OPTION){try {Image img = ImageIO.read(fc.getSelectedFile());ImageIcon icon = new ImageIcon(img);SimpleAttributeSet sas = new SimpleAttributeSet();//容器StyleConstants.setIcon(sas, icon);//把圖標(biāo)放入sas容器sendDoc.insertString(sendDoc.getLength(), "icon", sas);//把sas插入文本格式,屬性定義} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (BadLocationException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}});this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent arg0) {//關(guān)閉主界面后程序退出流關(guān)閉if (out != null) {MyMessage mes = new MyMessage(true,MyMessage.MES_TYPE_PLAIN);//mes.setContent("quit");sendMes(mes);reader.stopRun();}}});listClient.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {// TODO Auto-generated method stubsuper.mouseClicked(e);if(e.getClickCount()==2){//雙擊觸發(fā)私聊new PrivateDialog(listClient.getSelectedValue().toString()).setVisible(true);}}});}public void append(StyledDocument sd){int caretPosition = jtpMes.getStyledDocument().getLength();caretPosition+=sd.getLength();try {for(int i=0;i<sd.getLength();i++){javax.swing.text.Element e = sd.getCharacterElement(i);if(e.getName().equals("icon")){contentDoc.insertString(contentDoc.getLength(), "icon", e.getAttributes());i+=2;}else{String s = sd.getText(i, 1);contentDoc.insertString(contentDoc.getLength(), s, e.getAttributes());}}contentDoc.insertString(contentDoc.getLength(), "\n", null);} catch (BadLocationException e) {// TODO Auto-generated catch blocke.printStackTrace();}jtpMes.setCaretPosition(caretPosition);}public void sendMes(MyMessage m) {if (out != null) {try {out.reset();//反復(fù)發(fā)送同一個(gè)內(nèi)容不斷改變的對(duì)象需要使用reset(此時(shí)為sendDoc)out.writeObject(m);out.flush();} catch (IOException e) {e.printStackTrace();}}}class ReadThread extends Thread {Socket c;boolean flag = true;public ReadThread(Socket c) {this.c = c;}@Overridepublic void run() {try {ObjectInputStream in = new ObjectInputStream((c.getInputStream()));MyMessage newMes = (MyMessage) in.readObject();while (flag) {switch (newMes.getMesType()) {case MyMessage.MES_TYPE_PLAIN:append(newMes.getContent());//將得到的消息添加進(jìn)聊天框break;case MyMessage.MES_TYPE_UPDATE_CLIENTLIST:updateListClient(newMes.getClientList());//更新聊天人信息break;}//將輸入流和message對(duì)象初始化供下次使用in = new ObjectInputStream((c.getInputStream()));newMes = (MyMessage) in.readObject();}} catch (Exception e) {e.printStackTrace();}}public void stopRun() {flag = false;}}class PrivateDialog extends JDialog{//單獨(dú)對(duì)話框private JTextPane jtpPriMes = new JTextPane();private JScrollPane jspPriMes = new JScrollPane(jtpPriMes);private JButton btnPriSend = new JButton("Send");private JButton btnselect = new JButton("select");private JPanel panFun = new JPanel();private String ip;public PrivateDialog(String ip) {// TODO Auto-generated constructor stubthis.ip = ip;this.setTitle(ip);this.setSize(400, 300);this.setLocationRelativeTo(null);init();this.add(panFun);}private void init() {panFun.add(jtpPriMes);panFun.add(btnPriSend);panFun.add(btnselect);btnPriSend.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubString str = jtpPriMes.getText().trim();if(str!=null&&str.length()>0&&socket!=null){MyMessage mes = new MyMessage(false,MyMessage.MES_TYPE_PLAIN);mes.setIp(ip);mes.setContent(jtpPriMes.getStyledDocument());sendMes(mes);}}});btnselect.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubJFileChooser fc = new JFileChooser("d:");FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & GIF Image", "jpg","gif");//文件篩選器fc.setFileFilter(filter);int i = fc.showOpenDialog(SocketFrame.this);if(i == JFileChooser.APPROVE_OPTION){try {Image img = ImageIO.read(fc.getSelectedFile());ImageIcon icon = new ImageIcon(img);SimpleAttributeSet sas = new SimpleAttributeSet();//容器StyleConstants.setIcon(sas, icon);//把圖標(biāo)放入sas容器jtpPriMes.getStyledDocument().insertString(jtpPriMes.getStyledDocument().getLength(), "icon", sas);//把sas插入文本格式,屬性定義} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (BadLocationException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}});}}}ServerSocketTest代碼
package objtalk;import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator;import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument;import org.omg.CORBA.SystemException;public class ServerSocketTest {ServerSocket server;HashSet<Socket> clientSet = new HashSet<>();public ServerSocketTest() {try {server = new ServerSocket(12345);} catch (IOException e) {e.printStackTrace();}}public void work() {int no = 0;//連接服務(wù)器的個(gè)數(shù)try {while (true) {Socket client = server.accept();clientSet.add(client);SendUpdateClientList();no++;new ClientThread(client, no).start();}} catch (IOException e) {e.printStackTrace();}}public void SendUpdateClientList() {//發(fā)送用戶變更的消息,用戶退出和加入的監(jiān)聽(tīng)MyMessage mes = new MyMessage(true,MyMessage.MES_TYPE_UPDATE_CLIENTLIST);mes.setClientList(getClientList());massMes(mes);}public void massMes(MyMessage mes) {//群發(fā)消息Iterator<Socket> it = clientSet.iterator();while (it.hasNext()) {sendMes(it.next(), mes);}}public void singleMes(MyMessage mes){//單發(fā)消息for(Socket s : clientSet){if(s.getRemoteSocketAddress().toString().equals(mes.getIp())){//String判等必須用equalssendMes(s, mes);break;}}}public void sendMes(Socket s, MyMessage mes) {ObjectOutputStream out;try {out = new ObjectOutputStream(s.getOutputStream());out.writeObject(mes);out.flush();} catch (IOException e1) {e1.printStackTrace();}}public ArrayList<String> getClientList() {ArrayList<String> list = null;if (clientSet.size() > 0) {list = new ArrayList<String>();Iterator<Socket> it = clientSet.iterator();int index = 0;while (it.hasNext()) {list.add(it.next().getRemoteSocketAddress().toString());}}return list;}class ClientThread extends Thread {Socket c;int no;public ClientThread(Socket c, int no) {super();this.c = c;this.no = no;}@Overridepublic void run() {try (ObjectInputStream in = new ObjectInputStream((c.getInputStream()));) {MyMessage newMes = (MyMessage) in.readObject();while (newMes.getContent()!=null) {//不斷接收發(fā)來(lái)的消息if(newMes.getisIfmass()==true){massMes(newMes);System.out.println(newMes.getContent().getText(0,newMes.getContent().getLength() ));}else{singleMes(newMes);}newMes = (MyMessage) in.readObject();}} catch (Exception e) {e.printStackTrace();} finally {try {c.close();} catch (IOException e) {e.printStackTrace();}clientSet.remove(c);//用戶退出后SendUpdateClientList();}}}public static void main(String[] args) {new ServerSocketTest().work();}}四:使用方法:
五:項(xiàng)目github地址
https://github.com/Chaos1874/javaTalk
總結(jié)
以上是生活随笔為你收集整理的java聊天室群聊及私聊实现!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 自己动手写cpu光盘资源
- 下一篇: dtools: error while