JAVA实现QQ聊天气泡
最近做了聊天气泡功能,为自己的聊天室美化了一下聊天效果;
先来看一下效果:
主要的思路是:以一个JTextPane作为显示的面板,然后自定义一个组件JBubble气泡组件来实现他的聊天气泡,然后通过JTextPane中的insertComponent(jbubble);方法把组件添加
到JTextPane上。同时通过setCaretPosition(count);方法设置添加到末尾,count为当前以及有的组件的书目加一;
一:具体的过程:
(1)自定义JBubble组件:继承JComponent,重写paintComponent(Graphics g) 方法
在java中,所有的组件都是画出来的,所以这个聊天气泡画出来的;具体的步骤是:
- 首先画出发消息的人的头像 :g.drawImage(img, x, y, width, height, observer);
- 再画出消息箭头 g.fillPolygon(xPoints, yPoints, nPoints):通过给定缺点的几点来画一个多边形出来,第一个参数是一个是该多边形的所有的点的X轴坐标,第二个参数是该多边形的所有的点的Y轴的坐标,第三个点是该多边形的点数;
- 然后在根据消息的宽度,以及高度,画出消息矩形框:g.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
- 最后画出文字:g.drawString(str, x, y);
在构建组件的时候需要去区分一下是自己发的消息,还是他人发的消息,这样不同的发送方,画的位置不一样。
在实现这个组件中需要解决的问题是:
- 确定文字的高度和宽度
消息矩形框的高度和宽度是根据一段字符串的高度以及宽度来确定的。然后还需要考虑的是当字符串的宽度大于组件的宽度的时候我们就需要来考虑一下文字的换行问题;
在java中提供了一个FontMetrics类来可以获取文字的大小:
- FontMetrics fm = FontDesignMetrics.getMetrics(font);
- int width = fm.stringWidth(message);// 获取整个字符串的宽度
- int height = fm.getHeight();//获取字符的高度
在JBubble组件中利用了一个ArrayList来存储以及分好行的字符串,之前用过一个String类型的数组来存储,但是后面发现,每一个字符的宽度是不一样的(中文与英文以及数字之间是不一样的),所以不能够通过整除来确定划分的字符串的长度。虽然想过通过正则表达式来区分英文以及中文,数字这样,然后来进行分行,但最后还是选择了一种简单地方法;
(2) MessagePane类:实现文字和图片的处理,然后添加到JTextPane上面
为了划分字符串,实现分行,定义了一个MessagePane来管理所有的消息气泡;
主要的属性是:一个JTextPane对象,以及两个ImageICon对象来表示自己的头像以及他人的头像;然后两个int,分别表示一个组件的宽度以及 JTextPane中的组件的数目;
主要的方法是:
- addTextMessage(String messages, boolean fla);添加文字消息;
换行的操作比较简单,利用while循环来遍历整个字符串,当一段字符串的长度大于字符的时候就存入ArrayList中;
- /***
- * 添加文本消息
- *
- * @param messages
- * 要添加的消息
- * @param fla
- * 是否是自己发送的消息
- */
- public void addTextMessage(String messages, boolean fla) {
- Font font = jtextpane.getFont();
- // 获取字符串的高度
- int sHeight = getWordHeight(font, messages);
- System.out.println("字符串取得的高度为" + sHeight);
- // 获取字符串的宽度
- int sWidth = getWordsWidth(font, messages);
- System.out.println("字符串取得的宽度为" + sWidth);
- //存储分行的字符串
- ArrayList<String> str = new ArrayList<String>();
- if (sWidth > width - 100) {
- // int i=0;
- int beginIndex=0;
- int endIndex=1;
- while( endIndex<messages.length()){
- String s=messages.substring(beginIndex,endIndex);
- if(getWordsWidth(font, s)>(width - 100)||endIndex==messages.length()-1){
- str.add(messages.substring(beginIndex,endIndex-1));
- beginIndex=endIndex-1;
- }
- endIndex++;
- }
- } else
- str.add(messages);
- JBubble jbubble
- = new JBubble(sHeight, getWordsWidth(font,str.get(0)), str, fla);
- if (fla)
- jbubble.setUserIcon(userIcon);
- else
- jbubble.setUserIcon(otherIcon);
- jbubble.setPreferredSize(new Dimension(width, sHeight * (str.size() + 1) + 30));
- jtextpane.insertComponent(jbubble);
- count++;
- jtextpane.setCaretPosition(count);
- // jtextpane.repaint();
- }
JAVA实现QQ聊天气泡的更多相关文章
- QQ聊天气泡(图片拉伸不变样)、内容尺寸定制(高度随字数、字体而变)
- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; /** QQ聊 ...
- winform实现QQ聊天气泡200行代码
c# winform实现QQ聊天气泡界面,原理非常简单,通过webKitBrowser(第三方浏览器控件,因为自带的兼容性差)加载html代码实现,聊天界面是一个纯HTML的代码,与QQ的聊天界面可以 ...
- C#绘制三角形并填充,使用winform实现qq聊天气泡
首先是需求,需要制作一个聊天气泡, 但是winform中有没有类似Android的.9图,只有自己设计图形拼接气泡. 第一种是绘制空心三角形,第二种是绘制三角形区域,可以指定RGB颜色. privat ...
- 【HTML5】实现QQ聊天气泡效果
今天自己用 HTML/CSS 做了个类似QQ的聊天气泡,以下是效果图: 以下说下关键地方的样式设置.然后贴出html和css代码(不多). 步骤1:布局 消息採用div+float布局,每条消息用一个 ...
- css实现微信信息背景qq聊天气泡
用css实现一个椭圆形状的背景框很好实现 css: div{ width:200px; height:80px; background-color: #78DDF8; border-radius:10 ...
- 仿QQ聊天程序(java)
仿QQ聊天程序 转载:牟尼的专栏 http://blog.csdn.net/u012027907 一.设计内容及要求 1.1综述 A.系统概述 我们要做的就是类似QQ这样的面向企业内部的聊天软件,基本 ...
- reactnative实现qq聊天消息气泡拖拽消失效果
前言(可跳过) 我在开发自己的APP时遇到了一个类似于qq聊天消息气泡拖拽消息的需求,因为在网上没有找到相关的组件,所以自己动手实现了一下 需求:对聊天消息气泡拖拽到一定长度松开时该气泡会消失(可自行 ...
- 模拟QQ聊天与视频聊天同时进行-------java基础知识总结
前言:多线程的知识 代码: package com.day13.math; /** * 类说明 :模拟QQ聊天与视频聊天同时进行 * @author 作者 : chenyanlong * @versi ...
- Android—简单的仿QQ聊天界面
最近仿照QQ聊天做了一个类似界面,先看下界面组成(画面不太美凑合凑合呗,,,,):
随机推荐
- Django setting 常用配置
setting.py 这个文件包含了所有有关这个Django项目的配置信息,均大写: TEMPLATE_DIRS , DATABASE_NAME , 等. 最重要的设置是 RO ...
- python封装和解构
封装 将多个值使用逗号分割,组合在一起 本质上,返回一个元组,只是省略了小括号 python的特有的语法,被很多语言学习借鉴 t1 = (1,2) #定义元组 t2 = 1,2 #将1和2封装成元组 ...
- RabbitMQ简单Java示例——生产者和消费者
添加Maven依赖: 使用rabbitmq-client的最新Maven坐标: <!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp ...
- Spring Security(20)——整合Cas
整合Cas 目录 1.1 配置登录认证 1.1.1 配置AuthenticationEntryPoint 1.1.2 配置CasAuthenticationFilt ...
- GPIO相关寄存器描述和怎么配置
总寄存器图
- nginx 配置 https 并强制跳转(lnmp一键安装包)
目录 一.安装包 二.配置 三.查看配置文件 3.1.设定强制跳转 https 3.2 Rewrite 常用全局变量举例 一.安装包 安装大家按照官方说的安装即可. ./install.sh lnmp ...
- Pytorch Tensor, Variable, 自动求导
2018.4.25,Facebook 推出了 PyTorch 0.4.0 版本,在该版本及之后的版本中,torch.autograd.Variable 和 torch.Tensor 同属一类.更确切地 ...
- OPC Utgard的数据访问方式
1.同步读取某个点位的值 Item项的read()方法 Server server = new Server(BaseConfiguration.getCLSIDConnectionInfomatio ...
- 对ysoserial工具及java反序列化的一个阶段性理解【未完成】
经过一段时间的琢磨与反思,以及重读了大量之前看不懂的反序列化文章,目前为止算是对java反序列化这块有了一个阶段性的小理解. 目前为止,发送的所有java反序列化的漏洞中.主要需要两个触发条件: 1. ...
- Java学习笔记-抽象类与接口
抽象类用于在类中不用具体实现,而在子类中去实现的类 抽象类 抽象类概述 抽象定义:抽象就是从多个事物中将共性的,本质的内容抽取出来 抽象类:Java中可以定义没有方法体的方法,该方法的具体实现由子类完 ...