最近做了聊天气泡功能,为自己的聊天室美化了一下聊天效果;

先来看一下效果:

主要的思路是:以一个JTextPane作为显示的面板,然后自定义一个组件JBubble气泡组件来实现他的聊天气泡,然后通过JTextPane中的insertComponent(jbubble);方法把组件添加
到JTextPane上。同时通过setCaretPosition(count);方法设置添加到末尾,count为当前以及有的组件的书目加一;

一:具体的过程:

(1)自定义JBubble组件:继承JComponent,重写paintComponent(Graphics g) 方法

在java中,所有的组件都是画出来的,所以这个聊天气泡画出来的;具体的步骤是:

  1. 首先画出发消息的人的头像 :g.drawImage(img, x, y, width, height, observer);
  2. 再画出消息箭头 g.fillPolygon(xPoints, yPoints, nPoints):通过给定缺点的几点来画一个多边形出来,第一个参数是一个是该多边形的所有的点的X轴坐标,第二个参数是该多边形的所有的点的Y轴的坐标,第三个点是该多边形的点数;
  3. 然后在根据消息的宽度,以及高度,画出消息矩形框:g.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
  4. 最后画出文字: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聊天气泡的更多相关文章

  1. QQ聊天气泡(图片拉伸不变样)、内容尺寸定制(高度随字数、字体而变)

    - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; /** QQ聊 ...

  2. winform实现QQ聊天气泡200行代码

    c# winform实现QQ聊天气泡界面,原理非常简单,通过webKitBrowser(第三方浏览器控件,因为自带的兼容性差)加载html代码实现,聊天界面是一个纯HTML的代码,与QQ的聊天界面可以 ...

  3. C#绘制三角形并填充,使用winform实现qq聊天气泡

    首先是需求,需要制作一个聊天气泡, 但是winform中有没有类似Android的.9图,只有自己设计图形拼接气泡. 第一种是绘制空心三角形,第二种是绘制三角形区域,可以指定RGB颜色. privat ...

  4. 【HTML5】实现QQ聊天气泡效果

    今天自己用 HTML/CSS 做了个类似QQ的聊天气泡,以下是效果图: 以下说下关键地方的样式设置.然后贴出html和css代码(不多). 步骤1:布局 消息採用div+float布局,每条消息用一个 ...

  5. css实现微信信息背景qq聊天气泡

    用css实现一个椭圆形状的背景框很好实现 css: div{ width:200px; height:80px; background-color: #78DDF8; border-radius:10 ...

  6. 仿QQ聊天程序(java)

    仿QQ聊天程序 转载:牟尼的专栏 http://blog.csdn.net/u012027907 一.设计内容及要求 1.1综述 A.系统概述 我们要做的就是类似QQ这样的面向企业内部的聊天软件,基本 ...

  7. reactnative实现qq聊天消息气泡拖拽消失效果

    前言(可跳过) 我在开发自己的APP时遇到了一个类似于qq聊天消息气泡拖拽消息的需求,因为在网上没有找到相关的组件,所以自己动手实现了一下 需求:对聊天消息气泡拖拽到一定长度松开时该气泡会消失(可自行 ...

  8. 模拟QQ聊天与视频聊天同时进行-------java基础知识总结

    前言:多线程的知识 代码: package com.day13.math; /** * 类说明 :模拟QQ聊天与视频聊天同时进行 * @author 作者 : chenyanlong * @versi ...

  9. Android—简单的仿QQ聊天界面

    最近仿照QQ聊天做了一个类似界面,先看下界面组成(画面不太美凑合凑合呗,,,,):

随机推荐

  1. Qt编写自定义控件24-图片轮播控件

    一.前言 上一篇文章写的广告轮播控件,采用的传统widget堆积设置样式表做的,这次必须要用到更高级的QPainter来绘制了,这个才是最高效的办法,本控件参考雨田哥的轮播控件,经过大规模的改造而成, ...

  2. SpringBoot 2.x中为tomcat配置ssl(https)支持

    参考来源:https://www.cnblogs.com/imfjj/p/9058443.html https://blog.csdn.net/jackymvc/article/details/810 ...

  3. 计算1+2+...+n

    牛客上面一道题,闲来无事做做陶冶情操. 这一陶冶还真的陶冶出了骚操作 看一下题目吧: 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及 ...

  4. windows7-maven配置

    1.确认jdk安装 2.下载 3.解压缩 4.配置环境变量 (1)计算机属性--高级系统配置--高级--环境变量---系统变量--新建 (2)添加环境变量 MAVEN_HOME PATH中添加到mav ...

  5. 【计算机视觉】深度相机(六)--Kinect v2.0 手势样本库制作

    目录为1.如何使用Kinect Studio录制手势剪辑:2.如何使用Visual Gesture Builder创建手势项目:3.如何在我的C#程序中使用手势:4.关于录制.剪辑手势过程中的注意事项 ...

  6. Beta冲刺博客

    这个作业属于哪个课程 当然是属于程序分析与设计呀 这个作业要求在哪里 在这儿 团队名称 六扇门编程小组(团队博客) 这个作业的目标 完成为期两周的β版本冲刺 1.团队信息 姓名 学号 曹欢(组长) 2 ...

  7. 《剑指offer》查找二维数组内元素 c++

    在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序. 请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. cl ...

  8. [百家号]铁流:华为Hi1620发布 自研内核还是ARM改?

    华为Hi1620发布 自研内核还是ARM改? https://baijiahao.baidu.com/s?id=1618735211251270521&wfr=spider&for=p ...

  9. 【AtCoder】AGC008

    AGC008 A - Simple Calculator 如果符号相同,那么如果y比x大直接走,否则需要两次反号 如果符号不同,需要绝对值的差加一次反号 如果有一个是0,且y比x要小,那只需要一次反号 ...

  10. Python 解LeetCode:23. Merge k Sorted Lists

    题目描述:把k个排序的链表组成的列表合并成一个排序的链表 思路: 使用堆排序,遍历列表,把每个列表中链表的头指针的值和头指针本身作为一个元素放在堆中: 第一步中遍历完列表后,此时堆中最多会有n个元素, ...