1.产品展示

1.1这是我们的登录界面

2.细节!!!talk is cheap,show me the code

• UI设计
• Socket网络编程
• 多线程与线程通讯

2.1主页面

2.1.1注册表记住密码

/*** 注册表实现记住密码,注册表在我们的电脑里面,用键值对的方式存取
*/Preferences pre = Preferences.userNodeForPackage(getClass());// 注册表实现记住密码pre = Preferences.userNodeForPackage(UserLoginUI.class);pre.put(text_uname.getText(), text_pwd.getText());//存放密码pre.get(text_uname.getText(), null)//根据键,获取密码


2.1.2界面布局

  • 首先,我们采用的SWT编程,SWT的窗口会自动提供一个title框,这个title框可玩性太小,不能设置样式图层等,所以我们选择去掉title框
//自定义拖拽事件开始 private int startX;// 记录鼠标移动前的X坐标private int startY;// 记录鼠标移动前的y坐标private int lastX;// 记录鼠标移动后的x坐标private int lastY;// 记录鼠标移动后的y坐标private boolean isdown;// 记录鼠标是否按下UserMainUI thisOBJ = this;// 实现窗口拖拉 自己创建自己这个类/*** 设置指定区域label_topimage窗口移动事件,你要在那个组件上添加拖拽事件就在那里添加,我这里是在label里添加的*/label_topimage.addMouseListener(new MouseAdapter() {@Overridepublic void mouseDown(MouseEvent e) {thisOBJ.isdown = true;thisOBJ.startX = e.x;thisOBJ.startY = e.y;}@Overridepublic void mouseUp(MouseEvent e) {thisOBJ.isdown = false;super.mouseUp(e);}});label_topimage.addMouseMoveListener(new MouseMoveListener() {@Overridepublic void mouseMove(MouseEvent arg0) {if (thisOBJ.isdown) {thisOBJ.lastX = arg0.x;thisOBJ.lastY = arg0.y;int x = thisOBJ.lastX - thisOBJ.startX;int y = thisOBJ.lastY - thisOBJ.startY;org.eclipse.swt.graphics.Point location = shell.getLocation();int xx = location.x;int yy = location.y;shell.setLocation(x + xx, y + yy);}}});
  • 添加自定义的按钮,这里我的思路是直接在label里面贴图,然后设置label的MouseEnter、MouseExit、MouseDown事件,鼠标进入和离开label时通过更改label里贴的图造成按钮的感觉,通过MouseDown添加最小化shell.setMinimized(true)和做大化shell.setMaximized(true)以及销毁shell.dispose。
  • 这里关键的是当多个Composite面板和label框堆叠在一起时候的显示问题,我们的做法是把背景图的label放在最下面一层,这样就能呈现比较好的效果了

2.1.3用户主页采用的堆栈式布局StackLayout
主页我们采用的是堆栈式布局,这样就能配合自定义的label按钮的点击事件呈现切换界面的效果
SWT里的Composite面板为我们提供了六种布局方式,分别是

  • Absolute layout绝对布局
  • GridLayout网格式布局
  • FillLayout填充式布局
  • RowLayout行式布局
  • FormLayout从布局
  • StackLayout堆栈式布局

StackLayout堆栈式布局,他是所有的子面板都在堆叠在父面板上,可以通过父面板选在在最上面的那块,但只能看到堆在最上面的那块,可以设计触发事件改变最上面的面板达到切换界面的效果

private StackLayout stackLayoutne;// 堆栈式布局
// 采用堆栈式布局stackLayoutne = new StackLayout();composite_down.setLayout(stackLayoutne);// 将备选的三块面板层叠放到composite_down主面板下composite_tree = new Composite_tree(composite_down, SWT.NONE, fromQQ);composite_message = new Composite_message(composite_down, SWT.NONE, fromQQ);composite_weChat = new Composite_weChat(composite_down, SWT.NONE);stackLayoutne.topControl = composite_message;// 将composite_message聊天面板设置为主面板FormData fd_composite_down = new FormData();fd_composite_down.bottom = new FormAttachment(0, 673);fd_composite_down.right = new FormAttachment(0, 379);fd_composite_down.top = new FormAttachment(0, 222);fd_composite_down.left = new FormAttachment(0);composite_down.setLayoutData(fd_composite_down);composite_down.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
//事件里面切换面板label_center_center.addMouseListener(new MouseAdapter() {@Overridepublic void mouseDown(MouseEvent e) {lblNewLabel_center_left.setImage(SWTResourceManager.getImage(UserMainUI.class, "/images/消息_不亮.png"));label_center_center.setImage(SWTResourceManager.getImage(UserMainUI.class, "/images/联系人_亮.png"));label_center_right.setImage(SWTResourceManager.getImage(UserMainUI.class, "/images/空间_不亮.png"));stackLayoutne.topControl = composite_tree;// 将composite_message聊天面板设置为主面板composite_down.layout();// 重置布局,刷新界面}});

2.1.4用户主界面里的子面板采用SWT自带的滑动面板ScrolledComposite
这样就可以在以面板为父类的组件增长时自动产生滚动条,如果嫌ScrolledComposite太丑不好看的话,可以自己写一个子类继承ScrolledComposite,重写里面的方法

//设置滚动面板    ScrolledComposite scrolledComposite = new ScrolledComposite(this, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);scrolledComposite.setBounds(0, 0, 380, 496);scrolledComposite.setExpandHorizontal(true);scrolledComposite.setExpandVertical(true);Composite composite_1 = new Composite(scrolledComposite, SWT.NONE);composite_1.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));composite_1.setLayout(new RowLayout(SWT.VERTICAL));// 先将面板设置成行式布局RowLayout,再设置为VERTICAL垂直增长composite_1.setSize(composite_1.computeSize(SWT.DEFAULT, SWT.DEFAULT));scrolledComposite.setContent(composite_1);// 这一行代码至关重要,关于自动增长序列,每次判断下是不是超出设定好的大小,超出了自动设置滑动条scrolledComposite.setMinSize(composite_1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
//这里值得注意的是,如果是动态增长Composite里的组件,想要自动增长滚动条必须每次刷新后判断//-----------------<!--自动增长组件的代码--!>------------------------------------------------------------------composite_1.layout();// 重置布局,刷新界面// 超级注意!!!必须重置页面再判断是否增长滚动条,否则会出现无法及时增长滚动条的异常// 这一行代码至关重要,关于自动增长序列,每次判断下是不是超出设定好的大小,超出了设置滑动条scrolledComposite_chat.setMinSize(composite_1.computeSize(SWT.DEFAULT, SWT.DEFAULT));

2.1.5其他界面
其他界面基本上是自定义的Composite,每次用的时候new一个,并通过构造函数传递参数进去

eclipse里面组件太多了,网上的资料也很分散不系统,可以看看这本书——>《Eclipse SWT/JFACE 核心应用》 清华大学出版社

2.2Socket编程与多线程

建立实时的通讯软件有很多常用的模式,例如同步阻塞IO(JAVA BIO)、同步非阻塞IO(Java NIO) 、异步阻塞IO(Java NIO)、(Java AIO(NIO.2))异步非阻塞IO,由于临近期末考试,笔者也是边学边用,所以用的是最简单也是在业务层次最不成熟的方案同步阻塞IO(JAVA BIO),关于这些模式B站上面有个很好的课程,黑马程序员-Java的IO模式讲解(AIO&BIO&NIO),期考完后我会去好好看的哈哈哈,我这里写的也很简单,通俗易懂,当然问题也还有很多

2.2.1Socket编程
我这里采用的是TCP协议,总体的思路是每个客户端只需要跟服务器进行聊天,不对用户产生点对点的聊天,由服务器充当中介的角色进行消息的转发。每个客户端在连接服务器的时候会先发送一条消息,通过自己写的简单协议将自己的fromQQ,对方的toQQ和消息message以及信号值传递过去,其中信号值flag用来判断用户是想进行单聊群聊还是和机器人聊天,代码里面写的都很详细,大家可以看看,有问题多多指出一起学习哈

package com.fx.net;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import com.yc.util.YcUtil;
import com.yc.util.fxNetUtil;
/*** 采用TCP协议的服务器,设计思路为当有用户连接上服务器时,* 用一个map将其socket存起来,key为用户qq号,为群聊时,将群聊里所有用户的socket存在list里面* * @author fx* @time 2021年6月30日08:44:25**/
public class ServiceDemo {/*** 分别用map和qunliao存放不同连接的scoket对象*/static Map<String, Socket> map = new HashMap<String, Socket>();// 用来存放单人聊天的fromQQ和其socket对象// 用来放不同对象的map,包含一组socket对象static volatile List<Socket> list = new ArrayList<Socket>();//用volatile修饰可以使其他线程实时获取到这个变量public static void main(String[] args) {// 服务器// 创建一个服务器System.out.println("++++++++++++++++++++");System.out.println("腾迅QQ服务器启动");System.out.println("++++++++++++++++++++");System.out.println("服务器启动,时间:" + new SimpleDateFormat("yyyy年MM月dd日HH:mm").format(new Date()));// 各种对象用以连接Scanner inScanner = null;ServerSocket ss = null;Socket socket = null;String message;// 记录客户端发送过来的协议消息try {ss = new ServerSocket(9999);//占有并开放端口while (true) {// 创建一个接收连接客户端的对象 9999为开放的端口socket = ss.accept();String ip_port = new String(socket.getRemoteSocketAddress().toString()).split("/")[1];System.out.println("有客户端联接上来了,它是:" + ip_port);// 首先要接受客户端发到的第一句话,包含fromQQ,toQQ,message和flag信号值inScanner = new Scanner(socket.getInputStream());// 接受收入流里的字节流message = inScanner.nextLine();//这样接收消息高效且简单if ("0".equals(YcUtil.objToString(fxNetUtil.getflag(message)))) {// 判断为与机器人聊天new Thread(new ServiceThread(socket)).start();// new一个机器人的线程与用户交流} else if ("1".equals(YcUtil.objToString(fxNetUtil.getflag(message)))) {// 判断为单聊,先将socket对象存到map中map.put(fxNetUtil.getfromQQ(message), socket);// 查找其聊天对象是否在线上,在线上应存在socket对象if (map.containsValue(map.get(fxNetUtil.gettoQQ(message)))) {// 存在,即通过两个好友的socket对象进行聊天new Thread(new ServiceThreadsingleChat(map.get(fxNetUtil.gettoQQ(message)),map.get(fxNetUtil.getfromQQ(message)))).start();}if (map.size() == 2) {// 当有两个用户建立连接后,清空map,为后面用户腾出空间map.clear();}} else if ("2".equals(YcUtil.objToString(fxNetUtil.getflag(message)))) {// 判断为群聊,先将此时访问的用户qq和其socket对象存储起来list.add(socket);// 每个用户进入群聊都开启一个线程进行监控,但list对象共享new Thread(new ServiceThreadWechat(message, socket)).start();}}} catch (IOException e) {e.printStackTrace();} finally {// 关闭所有资源if (null != socket) {try {socket.close();} catch (IOException e) {e.printStackTrace();}}if (null != ss) {try {ss.close();} catch (IOException e) {e.printStackTrace();}}}}
}

其他单聊群聊与和机器人聊天的代码在源码里都有,可以去参看一下,问题还是有很多滴,这里就不献丑展示了,只能说代码能实现,但一点都不优美

2.2.2接入图灵机器人API,进行机器人聊天
代码是网上东拼西凑的,我就截取来一下爬取到数据里面的有效字段,其他的也搞不懂

package com.fx.http;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
/*** @Author fx* @Date 2021年7月1日09:20:25*/
public class HttpTest {static String url = null;static String param = "";public static String GetUrl(String question) {if (null == question) {question = "衡阳天气怎么样";}url = "http://api.jisuapi.com/iqa/query?appkey=62958a3a6ef3c56d&question=" + encode(question);String result = "";// 访问返回结果BufferedReader read = null;// 读取访问结果try {// 创建urlURL realurl = new URL(url + "?" + param);// 打开连接URLConnection connection = realurl.openConnection();// 设置通用的请求属性connection.setRequestProperty("accept", "*/*");connection.setRequestProperty("connection", "Keep-Alive");connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 建立连接connection.connect();// 获取所有响应头字段Map<String, List<String>> map = connection.getHeaderFields();read = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));String line;// 循环读取while ((line = read.readLine()) != null) {result += line;}} catch (Exception e) {e.printStackTrace();} finally {if (read != null) {// 关闭流try {read.close();} catch (Exception e) {e.printStackTrace();}}}// 截取需要的有效字符return new String(result).split("\"content\":\"")[1].split("\",\"relquestion\"")[0];}/*** Unicode编码* * @param url* @return*/public static String encode(String url){try {String encodeURL = URLEncoder.encode(url, "UTF-8");return encodeURL;} catch (UnsupportedEncodingException e) {return "Issue while encoding" + e.getMessage();}}/*** Unicode解码* * @param url* @return*/public static String decode(String url) {try {String prevURL = "";String decodeURL = url;while (!prevURL.equals(decodeURL)) {prevURL = decodeURL;decodeURL = URLDecoder.decode(decodeURL, "UTF-8");}return decodeURL;} catch (UnsupportedEncodingException e) {return "Issue while decoding" + e.getMessage();}}
}

其他的问题暑假再一一完善叭,仓库里面的代码有很多试错时候留下的初期版本,没时间去掉了!!!写了半个月,现在要好好准备期末考试了

笔记我是先放在了我的笔记本里面,里面效果会好一点
笔记本地址:我的笔记,大佬轻喷!
源码地址:我的Gitee,@奉先大大鸭

java+SWT+Oracle做的一款类似于QQ的实时通讯软件相关推荐

  1. 一款类似于mac-dock栏的windows软件

    一款类似于mac-dock栏的windows软件 软件名称叫 Winstep Nexus Ultimate 软件链接如下: 链接:https://www.lanzous.com/i1xnevc 密码: ...

  2. 来看看这款简单优雅的实时聊天软件

    今天要介绍的是一个用于即时消息渠道的客户支持工具 -- Chatwoot,它可以帮助企业提供特殊的客户支持. Chatwoot的发展始于2016年,但未能作为一家企业获得成功,最终在2017年关闭了这 ...

  3. 一款类似于mac dock栏的windows软件

    原文链接:一款类似于mac-dock栏的windows软件 一款类似于mac-dock栏的windows软件 软件名称叫 Winstep Nexus Ultimate 软件链接如下: 链接:https ...

  4. 五款功能十分强大的办公软件,务必低调使用

    万彩脑图大师 万彩脑图大师是一款功能强大且免费的思维导图绘制软件. 拥有可视化的数据与思维方式.多样的结构布局与主题库,更有图文并茂的思维导图功能,带给用户强大的功能,内置大量精美模板,还能绘制鱼骨图 ...

  5. 独家对话谢宝友:做一款类似于 Linux 的国产操作系统 | 人物志

    作者 | 郑丽媛 来源 | CSDN(ID:CSDNnews) 从国外操作系统的长期垄断到中国自主研发操作系统数十年的起落浮沉,技术自主创新独立已成为国产基础软件的主要突破口.近几年间,随着物联网时代 ...

  6. 独家对话谢宝友:做一款类似于 Linux 的国产操作系统 | 人物志

    作者 | 郑丽媛 责编 | 屠敏 出品 | CSDN(ID:CSDNnews) 从国外操作系统的长期垄断到中国自主研发操作系统数十年的起落浮沉,技术自主创新独立已成为国产基础软件的主要突破口.近几年间 ...

  7. java servlet+oracle 新手可看

    最近公司领导告诉接下去接的一个产品,可能会涉及到oracle数据库,以前用得最多的是mssql,前些时间学了下mysql也算少许用过.oracle没接触过.应为我之前做过.net开发,所以数据访问接口 ...

  8. 【译】使用Java编写Oracle Tuxedo应用

    Oracle Tuxedo Java编程介绍 简介 Oracle Tuxedo服务可以使用纯java来编写.使用java实现的服务的功能和其他Tuxedo服务实现是一样的.你可以使用客户端或者Tuxe ...

  9. JAVA Swt初识

    JAVA Swt 进入java C/S世界 很多人以为swt与swing是同一种东西.其实不然. awt/swing是sun公司发布的jdk里的,拥有较强的跨平台性.swt/jface是开发eclip ...

最新文章

  1. java中缀表达式转后缀表达式(逆波兰算法)
  2. STM32单片机真的落后?
  3. api.dll自己的理解
  4. Exchange DAG备份恢复(六)---通过Windows Server Backup对单个邮箱进行恢复
  5. 一文读懂Redis常见对象类型的底层数据结构
  6. 死磕 synchronized 底层实现
  7. 实验7-3-6 字符串转换成十进制整数 (15分)
  8. qt开发环境 - c++字符串操作
  9. readn writen实现linux下socket缓冲区读写
  10. 下周开幕!给深圳的嵌入式和电子工程师准备的嘉年华来了
  11. hdu 5326(基础题) work
  12. Android 系统(30)---如何用DDMS分析native memory leak
  13. select、poll和epoll的总结对比
  14. 关于对QQ 输入法的评价
  15. 计算机视觉 CS231n Course Introduction
  16. 如何拯救k8s镜像分发的阿喀琉斯之踵
  17. 创业反鸡汤--3.谈待遇
  18. Oracle analytics server(OAS) 支持 mysql 社区版配置
  19. python爬虫之——爬取煎蛋网图片
  20. 抱薪者说 | 薪火相传,薪之不绝,火亦不熄

热门文章

  1. 紫光展锐 虎贲T610、T618安卓4g核心板 性能参数对比
  2. 裁判主导比赛【尼日利亚-希腊 德国-萨尔维亚】
  3. gulp临时服务器显示html页面,Gulp实现静态网页模块化的方法详解
  4. 学成绩不佳的数学大师─埃尔米特 (Hermite)
  5. c语言 绘制任意斜率的直线,计算机图形学 绘制任意斜率的直线(1)
  6. 复旦大学计算机系女教授,复旦网红女教授,变成了大众炮轰的对象
  7. Linux 配置DNS子域授权
  8. 算法梳理boosting\bagging\RF(1)
  9. table边框合并问题
  10. 深度学习(3)之经典神经网络模型整理:神经网络、CNN、RNN、LSTM