仿照了网上的代码和思路对之前的1.0版本进行了修改,按别人的界面和思路来写代码巨难受

设计到的一些知识点

1.swing界面:

BorderLayout与FlowLayout的区别

BorderLayout类:

BorderLayout将版面分成EAST(东),SOUTH(南),WEST(西),NORTH(北),CENTER(中),五个区域块,并语序将组件放在指定的区域块内,因为将组件放入BorderLayout版面内会造成组件变形,所以不适合加入JButton(按钮)这类组件,而比较合适JPanel(面板);

FlowLayout类

FlowLayout的配置方式也是从左到右,从上到下,排列,如果窗口宽度足够,会将所有的语速放在同一行;如果宽度不够,自动换行。FlowLayout默认组件居中对齐,也可以按照需求左对齐或者右对齐 ,加入FlowLayout版面的组件也是按照顺序摆放的,所以也无法直接指定要摆放的位置。组价不会变形可以加入JButton这类组件。

另外还有个GridLayout(int rows, int cols, int hgap, int vgap) :

创建具有指定行数、列数以及组件水平、纵向一定间距的网格布局

JOptionPane类的使用:主要用于弹出提示框

showConfirmDialog():确认对话框 
showInputDialog():输入对话框 
showMessageDialog():消息对话框 
showOptionDialog():选择对话框

2.针对窗口事件的监听类

addWindowListener(new WindowAdapter() { //窗口关闭后断开连接@Overridepublic void windowClosing(WindowEvent e) {try {if (socket != null)socket.close();if (inputStream!= null)inputStream.close();if (outputStream != null)outputStream.close();} catch (IOException e1) {e1.printStackTrace();}}})

addWindowListener:添加窗口事件监听器

WindowAdapter是抽象类,它是专门用于接收窗口事件的抽象适配器,由于抽象类不能被实例化,所以上面的程序中,创建了一个继承于WindowAdapter的匿名内部类,注意:继承并不需要重载所有方法,只要针对想处理的进行重写就可。

3.JTextArea中setText与append的区别

setText是让文本框显示你要的信息  而append则是在不改变文本框内容的基础上再它后面添加你的信息
textArea.setEditable(false);//设置为不可操作

如果要让文本框显示自己的信息则要用append

4.flush()方法的作用:flush()方法将输入流和输出流中的缓冲进行刷新,使缓冲区中的元素即时做输入和输出,而不必等缓冲区满

代码如下

客户端页面

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
//import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;public class TwoClientView extends JFrame implements ActionListener,KeyListener,Runnable{private JTextArea textArea;private JTextField textfield,tfname;private JButton btnSend,btnId;private JLabel label;private JPanel jp1, jp2;public boolean isConnect=false;private Socket socket=null;private DataInputStream inputStream=null;private DataOutputStream outputStream=null;private JScrollPane scrollpane;private static TwoClientView view;public JTextArea getTextArea() {return textArea;}public DataInputStream getInputStream() {return inputStream;}public DataOutputStream getOutputStream() {return outputStream;}public static void main(String[] args) {view=new TwoClientView();TwoServiceView.clientviews.add(view);//添加到客户端集合中Thread thread=new Thread(view);thread.start();}public TwoClientView(){initView();try {socket = new Socket("localhost", 9090);//连接本地服务器} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}private void initView() {textArea=new JTextArea(20,20);textArea.setEditable(false);//设置为不可操作textfield=new JTextField(15);scrollpane=new JScrollPane(textArea);//可以自动产生滚动轴textfield.addKeyListener(this);btnSend=new JButton("发送");btnSend.addActionListener(this);label=new JLabel("昵称");tfname=new JTextField(8);jp1=new  JPanel();jp2=new JPanel();jp1.add(label);jp1.add(tfname);tfname.setText("用户0");jp1.setLayout(new FlowLayout(FlowLayout.CENTER));jp2.add(textfield);jp2.add(btnSend);jp2.setLayout(new FlowLayout(FlowLayout.CENTER));this.add(jp1,BorderLayout.NORTH);this.add(scrollpane, BorderLayout.CENTER);this.add(jp2, BorderLayout.SOUTH);this.setTitle("聊天室");setSize(500, 500);setLocation(450, 150);setVisible(true);setDefaultCloseOperation(EXIT_ON_CLOSE);this.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {try {if(socket!=null) socket.close();//如果socket本身就是null关不关也就无所谓了if(inputStream!=null) inputStream.close();if(outputStream!=null) outputStream.close();}catch(IOException e1){e1.printStackTrace();}}});}public void actionPerformed(ActionEvent e) {if(e.getSource()==btnSend) {SendMsg();}}private void SendMsg() {try {String str=textfield.getText();if(!str.equals("")) {textfield.setText("");textArea.append(tfname.getText()+":\n"+str+"\n");//将内容发到自身的area上outputStream=new DataOutputStream(socket.getOutputStream());outputStream.writeUTF(tfname.getText()+"#"+str);//将内容读入文件输出流outputStream.flush();//清空缓存数据}}catch(IOException e) {e.printStackTrace();}}@Overridepublic void keyPressed(KeyEvent arg0) {//也可使用回车键发送if (arg0.getKeyCode() == KeyEvent.VK_ENTER) {SendMsg();}}@Overridepublic void keyReleased(KeyEvent arg0) {}@Overridepublic void keyTyped(KeyEvent arg0) {}@Overridepublic void run() {try {inputStream=new DataInputStream(socket.getInputStream());while(true) {String []s=inputStream.readUTF().split("#");
textArea.append(s[0]+":\n"+s[1]+"\n");//用于向其他用户发送信息}}catch(IOException e) {e.printStackTrace();}}
}

2服务端页面

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;public class TwoServiceView extends JFrame implements ActionListener{private JButton btnOpen,btnStop;private JLabel label;private TwoService service=null;public static ArrayList<TwoClientView> clientviews=new ArrayList<>();private static TwoServiceView view;public static TwoServiceView getView() {return view;}public static void main(String[] args) {view=new TwoServiceView();}public TwoServiceView() {initView();}private void initView() {btnOpen=new JButton("打开服务器");btnStop=new JButton("关闭服务器");btnStop.setEnabled(false);btnOpen.addActionListener(this);btnStop.addActionListener(this);label=new JLabel("服务器停止工作");add(label);add(btnOpen);add(btnStop);setTitle("服务器");setLayout(new GridLayout(3, 1,0,10));setSize(300, 300);setLocation(450, 450);setVisible(true);setDefaultCloseOperation(EXIT_ON_CLOSE);}public void actionPerformed(ActionEvent e) {if(e.getSource()==btnOpen) {open();}else {stop();}}public void open() {service=new TwoService();Thread thread=new Thread(service);thread.start();label.setText("服务器正在运行");btnOpen.setEnabled(false);btnStop.setEnabled(true);}public void stop() {label.setText("服务器已关闭");btnOpen.setEnabled(true);btnStop.setEnabled(false);try {synchronized (TwoClientMannager.sockets) {//使用sockets作为同步监视器,任何线程进入同步代码块必须先for(TwoCharSocket socket:TwoClientMannager.sockets) {//获得对sockets的锁定socket.getInputStream().close();socket.getOutputStream().close();}TwoClientMannager.sockets.removeAllElements();//删除集合中的所有客户端信息}for(TwoClientView view: clientviews) {view.getInputStream().close();view.getOutputStream().close();}service.getserviceSocket().close();}catch(IOException e) {e.printStackTrace();}}
}

3开启服务端连接

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;import javax.swing.JOptionPane;public class TwoService implements Runnable{//本类用来开启服务端连接private ServerSocket serversocket=null;public ServerSocket getserviceSocket() {return serversocket;}
public void run() {try {serversocket=new ServerSocket(9090);//建立与客户端的连接while(true) {Socket socket=serversocket.accept();JOptionPane.showMessageDialog(TwoServiceView.getView(), "客户端连接端口", "TIP", JOptionPane.INFORMATION_MESSAGE);TwoCharSocket chatsocket=new TwoCharSocket(socket);TwoClientMannager.sockets.add(chatsocket);//每建立起一个连接就将它添加到连接集合中去Thread thread=new Thread(chatsocket);//启动线程不断接收客户端信息thread.start();//开启服务端连接通道}}catch(IOException e) {e.printStackTrace();System.out.println("服务器关闭");}
}
}

4。开启客户端连接

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;public class TwoCharSocket implements Runnable{开启服务端连接
private Socket socket=null;
private DataInputStream inputStream = null;
private DataOutputStream outputStream = null;
public DataInputStream getInputStream() {return inputStream;
}
public DataOutputStream getOutputStream() {return outputStream;
}
public TwoCharSocket(Socket socket) {this.socket=socket;try {inputStream = new DataInputStream(socket.getInputStream());outputStream = new DataOutputStream(socket.getOutputStream());} catch (IOException e) {e.printStackTrace();}
}
public void send(String str) {//用于将所有的信息输入服务端的输出流try {outputStream.writeUTF(str);outputStream.flush();}catch(IOException e) {e.printStackTrace();}}
public void run() {String accept=null;while(true) {try {accept=inputStream.readUTF();TwoClientMannager.sendAll(this, accept);}catch(IOException e) {TwoClientMannager.sockets.remove(this);}}
}
}

5向所有客户端发送信息的操作

import java.util.Vector;public class TwoClientMannager {//用于向所有客户端发送信息的操作
private TwoClientMannager() {
}
public static Vector<TwoCharSocket> sockets=new Vector<>();
public static void sendAll(TwoCharSocket charSocket,String send) {for(TwoCharSocket s:sockets) {if(!charSocket.equals(s)) {//判断是不是自身s.send(send);}}
}
}

Java聊天室2.0版本相关推荐

  1. Java小白版聊天室1.0版本

    一个Java初学者写出来的界面简陋,功能及其简单的小白版聊天室,接下来会花一点时间去完善它 1.构思:构建两个main方法,一个为服务端,一个为客户端,客户端向服务端发送消息,服务端创建集合,向集合中 ...

  2. 多人群聊聊天室java_#java 聊天室(一)—— 实现一个简单Telnet多人群聊聊天室...

    #java    聊天室(一)--  实现一个简单Telnet多人群聊聊天室 学习本文须要先准备的知识点:队列(或数组).类与对象.线程.InputStream和OutputStream的使用.jav ...

  3. java聊天室(实训项目)

    这里是我们实训的一个关于java聊天室的项目,有需要的同学可以看看,私聊功能未完善. 话不多说,直接上代码. 服务器: package ChatRoom;import java.awt.Color; ...

  4. java 聊天室之 传送图片文字等功能的实现

    前几日写的一篇简陋之极的java聊天室被各位前辈说是,一塌糊涂,乌烟瘴气,只是简单的实现了需要的功能,并未做到人性化.在下痛定思痛,心想还是先学会显示功能再做美化界面,美化代码的打算! 在奋斗了一天之 ...

  5. Java聊天室程序源码 Java即时通讯代码 Java局域网聊天系统 Java即时通讯 Java聊天系统

    Java聊天室程序源码 Java即时通讯代码 Java局域网聊天系统  Java即时通讯 Java聊天系统 public Swingtest002() {// 设置标题setTitle("请 ...

  6. java 聊天室之 传送图片文字等功能的实现

    前几日写的一篇简陋之极的java聊天室被各位前辈说是,一塌糊涂,乌烟瘴气,只是简单的实现了需要的功能,并未做到人性化.在下痛定思痛,心想还是先学会显示功能再做美化界面,美化代码的打算! 在奋斗了一天之 ...

  7. [java聊天室]多个客户端与服务器说话多线程(二)

    多客户端链接 之前(java聊天室一)只有第一个连接的客户端可以与服务端说话. 原因: 服务端只调用过一次accept方法,因此只有第一个客户端链接时服务端接受了链接并返回了Socket,此时可以与其 ...

  8. Java聊天室的设计与实现

    Java聊天室系统主要用于实现在线聊天,基本功能包括:服务端和客户端.本系统结构如下: (1)服务端: 1.能够开启和关闭服务器 2.等待着客户端从特殊端口发送的请求 3.监听的端口并不是固定的,服务 ...

  9. java聊天室论文,JAVA聊天室毕业论文

    JAVA聊天室毕业论文 毕业设毕业设计计 姓 名 学 号 系 部 信息工程系信息工程系 专 业 软件技术软件技术 设计题目 聊天室(聊天室(JavaJava)) 指导教师 职 称 2012 年 07 ...

最新文章

  1. webGL的一些咨询--web3D
  2. Windows,Xampp,Zend Stadio搭建php运行环境
  3. 我下载的mysql解压后没有安装_mysql 解压版安装配置方法教程
  4. 复述-软考网规--云计算专题
  5. Flink java模拟生成自定义流式数据
  6. android 抓取webview中的所有图片_Python|任意网页中的所有图片下载
  7. iptables的连接追踪机制和nf_conntrack调优
  8. python的编程软件有哪些_python编程工具有哪些
  9. 基于SpringBoot的后台管理系统(Encache配置、全局异常处理(重点))(四)
  10. html5 video play方法,html5 – 如何在现代Chrome上访问video.play()API
  11. Windows API一日一练(17-18)DialogBox DialogBoxParam EndDialog函数
  12. 【1】EFR32配置433Mhz(可通信CC1101)——EFR32 项目例程打开和烧录
  13. PEST、5W2H、逻辑树、4P营销理论、用户行为分析
  14. IE8 RC版 兼容模式的表格边框问题
  15. AR+LBS线下社交游戏尝试
  16. 左连接,右连接,内连接及全连接区别
  17. 多余的读写端口什么时候会对程序造成影响_RFID叉车仓储|RFID叉车读写器在智能仓库收发货环节中的应用...
  18. 4-10 阶乘计算升级版
  19. qt 判断文件是否存在
  20. esp分区创建 linux_EFI引导Ubuntu。分区如何手动创建

热门文章

  1. 管理exchange 2010用户邮箱本地移动请求
  2. Zookeeper Watcher(事件监听器)?
  3. git修改服务器的命令行,Git版本控制工具安装及命令行操作
  4. 分布式事务实践 解决数据一致性 分布式系统
  5. 利用perspective 和 transform 里面的几个参数来实现旋转照片墙
  6. PHP FPM源代码反刍品味之三: 多进程模型
  7. window.opener.location.reload() and href()的区别
  8. SpringBoot @CachePut注解的使用原理
  9. java求一个正整数的位数_java经典问题——求正整数的位数
  10. 面试问题背后的“猫腻”