java 气泡_JAVA实现QQ聊天气泡

本文介绍了如何使用JAVA实现聊天气泡功能,通过自定义JBubble组件,结合JTextPane来展示聊天气泡。详细讲解了组件的绘制过程,包括头像、箭头、消息矩形框和文字的绘制,并解决了文字换行和宽度计算的问题。同时提供了MessagePane类来处理文字和图片的添加。
摘要由CSDN通过智能技术生成

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

先来看一下效果:

eb2f15c8c67f806baff28bd27fb5b31c.png

主要的思路是:以一个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中;

/***

* 添加文本消息

*

*@parammessages

* 要添加的消息

*@paramfla

* 是否是自己发送的消息*/

public void addTextMessage(String messages, booleanfla) {

Font font=jtextpane.getFont();//获取字符串的高度

int sHeight =getWordHeight(font, messages);

System.out.println("字符串取得的高度为" +sHeight);//获取字符串的宽度

int sWidth =getWordsWidth(font, messages);

System.out.println("字符串取得的宽度为" +sWidth);//存储分行的字符串

ArrayList str = new ArrayList();if (sWidth > width - 100) {//int i=0;

int beginIndex=0;int endIndex=1;while( endIndex

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++;

}

}elsestr.add(messages);

JBubble jbubble= new JBubble(sHeight, getWordsWidth(font,str.get(0)), str, fla);if(fla)

jbubble.setUserIcon(userIcon);elsejbubble.setUserIcon(otherIcon);

jbubble.setPreferredSize(new Dimension(width, sHeight * (str.size() + 1) + 30));

jtextpane.insertComponent(jbubble);

count++;

jtextpane.setCaretPosition(count);//jtextpane.repaint();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值