精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2015-05-28
1. 基本的气泡消息聊天窗口效果 2. 改变聊天窗口大小时,消息段落能够自动折行,气泡能够自适应调整大小(gif动画,有点大) 3. 气泡消息能够支持图文混合,改变聊天窗口大小时,气泡消息中的图片可以自适应缩放(gif动画,有点大) 当然,气泡消息图文混合也支持gif动画图片文件,这里就不演示了。后面会向大家介绍一下基本的技术实现思路,算是抛砖引玉,欢迎大家一起讨论。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2015-05-31
吊炸天啊,大神,求源码学习
|
|
返回顶楼 | |
发表时间:2015-06-02
楼主我爱你
|
|
返回顶楼 | |
发表时间:2015-06-03
牛!功力很深厚啊!
|
|
返回顶楼 | |
发表时间:2015-06-03
最后修改:2015-06-03
下面开始分享一下如何用Java Swing实现的仿QQ气泡消息聊天窗口效果。针对这个截图的测试程序窗口,我把它分成上下两个部分,采用JSplitter,下面是输入消息的区域,上面是显示消息的区域。这两个区域都是采用JTextPane的派生子类实现的。我的逻辑是,先定义输入消息区域JTextPane子类,类名为JIMSendTextPane,然后再基于JIMSendTextPane派生一个新的子类JIMHistoryTextPane作为显示消息区域。两个JTextPane的派生子类都采用JScrollPane放置,并将各自的JScrollPane设置为水平滚动条永远禁止,垂直滚动条按需出现。为什么要创建JTextPane的派生子类,主要是考虑到Java自带的JTextPane存在一个问题。我们知道默认情况下,如果JTextPane所在的JScrollPane禁止水平滚动条出现时,JTextPane是具备基于单词(Word)为最小单位的自动换行功能的。对于中文而言,最小单位就是一个汉字;对于英文或拉丁语言而言,就是以空格为单位的字母组合。但是有一个情况,如果你一直输入英文字母,中间不空格,那么JTextPane就会认为这是一个很长的单词,一直没有结束,那么它是不会自动换行的。这显然是不符合我们要求的。为了能够一劳永逸地解决这个问题,使JTextPane能够在任何情况下都能对超出宽度的内容进行自动换行,就需要对JTextPane进行派生子类定义,对其内部负责换行的地方做些修改。具体代码如下:
import javax.swing.JTextPane; import javax.swing.text.AbstractDocument; import javax.swing.text.BoxView; import javax.swing.text.ComponentView; import javax.swing.text.Element; import javax.swing.text.IconView; import javax.swing.text.LabelView; import javax.swing.text.ParagraphView; import javax.swing.text.StyleConstants; import javax.swing.text.StyledEditorKit; import javax.swing.text.View; import javax.swing.text.ViewFactory; /** * 该类是真正实现超长单词都能自动换行的 JTextPane 的子类 * Java 7 以下版本的 JTextPane 本身都能实现自动换行,对 * 超长单词都能有效,但从 Java 7 开始读超长单词就不能自动 * 换行,导致 JTextPane 的实际宽度变大,使得滚动条出现。 * 下面的方法是对这个 bug 的较好修复。 * * Created by dolphin on 15-2-3. */ public class JIMSendTextPane extends JTextPane { // 内部类 // 以下内部类全都用于实现自动强制折行 private class WarpEditorKit extends StyledEditorKit { private ViewFactory defaultFactory = new WarpColumnFactory(); @Override public ViewFactory getViewFactory() { return defaultFactory; } } private class WarpColumnFactory implements ViewFactory { public View create(Element elem) { String kind = elem.getName(); if (kind != null) { if (kind.equals(AbstractDocument.ContentElementName)) { return new WarpLabelView(elem); } else if (kind.equals(AbstractDocument.ParagraphElementName)) { return new ParagraphView(elem); } else if (kind.equals(AbstractDocument.SectionElementName)) { return new BoxView(elem, View.Y_AXIS); } else if (kind.equals(StyleConstants.ComponentElementName)) { return new ComponentView(elem); } else if (kind.equals(StyleConstants.IconElementName)) { return new IconView(elem); } } // default to text display return new LabelView(elem); } } private class WarpLabelView extends LabelView { public WarpLabelView(Element elem) { super(elem); } @Override public float getMinimumSpan(int axis) { switch (axis) { case View.X_AXIS: return 0; case View.Y_AXIS: return super.getMinimumSpan(axis); default: throw new IllegalArgumentException("Invalid axis: " + axis); } } } // 本类 // 构造函数 public JIMSendTextPane() { super(); this.setEditorKit(new WarpEditorKit()); } } 这个派生子类JIMSendTextPane作为输入消息区域,是完全能够满足要求了,也可以实现插入图片,图文混排,文字样式自定义等等。但是对于显示消息的区域,这个派生子类还不够。因为显示消息的区域涉及到聊天消息气泡、头像的绘制,这必须依靠JTextPane派生子类的自绘方式实现。当然,显示消息区域也必须要具备任意情况下的超宽内容换行,而JIMSendTextPane恰好已具备了这个换行能力,所以显示消息区域要以JIMSendTextPane为父类,再进行子类派生。(未完待续) |
|
返回顶楼 | |
发表时间:2015-06-07
cyberniuniu 写道 下面开始分享一下如何用Java Swing实现的仿QQ气泡消息聊天窗口效果。针对这个截图的测试程序窗口,我把它分成上下两个部分,采用JSplitter,下面是输入消息的区域,上面是显示消息的区域。这两个区域都是采用JTextPane的派生子类实现的。我的逻辑是,先定义输入消息区域JTextPane子类,类名为JIMSendTextPane,然后再基于JIMSendTextPane派生一个新的子类JIMHistoryTextPane作为显示消息区域。两个JTextPane的派生子类都采用JScrollPane放置,并将各自的JScrollPane设置为水平滚动条永远禁止,垂直滚动条按需出现。为什么要创建JTextPane的派生子类,主要是考虑到Java自带的JTextPane存在一个问题。我们知道默认情况下,如果JTextPane所在的JScrollPane禁止水平滚动条出现时,JTextPane是具备基于单词(Word)为最小单位的自动换行功能的。对于中文而言,最小单位就是一个汉字;对于英文或拉丁语言而言,就是以空格为单位的字母组合。但是有一个情况,如果你一直输入英文字母,中间不空格,那么JTextPane就会认为这是一个很长的单词,一直没有结束,那么它是不会自动换行的。这显然是不符合我们要求的。为了能够一劳永逸地解决这个问题,使JTextPane能够在任何情况下都能对超出宽度的内容进行自动换行,就需要对JTextPane进行派生子类定义,对其内部负责换行的地方做些修改。具体代码如下:
import javax.swing.JTextPane; import javax.swing.text.AbstractDocument; import javax.swing.text.BoxView; import javax.swing.text.ComponentView; import javax.swing.text.Element; import javax.swing.text.IconView; import javax.swing.text.LabelView; import javax.swing.text.ParagraphView; import javax.swing.text.StyleConstants; import javax.swing.text.StyledEditorKit; import javax.swing.text.View; import javax.swing.text.ViewFactory; /** * 该类是真正实现超长单词都能自动换行的 JTextPane 的子类 * Java 7 以下版本的 JTextPane 本身都能实现自动换行,对 * 超长单词都能有效,但从 Java 7 开始读超长单词就不能自动 * 换行,导致 JTextPane 的实际宽度变大,使得滚动条出现。 * 下面的方法是对这个 bug 的较好修复。 * * Created by dolphin on 15-2-3. */ public class JIMSendTextPane extends JTextPane { // 内部类 // 以下内部类全都用于实现自动强制折行 private class WarpEditorKit extends StyledEditorKit { private ViewFactory defaultFactory = new WarpColumnFactory(); @Override public ViewFactory getViewFactory() { return defaultFactory; } } private class WarpColumnFactory implements ViewFactory { public View create(Element elem) { String kind = elem.getName(); if (kind != null) { if (kind.equals(AbstractDocument.ContentElementName)) { return new WarpLabelView(elem); } else if (kind.equals(AbstractDocument.ParagraphElementName)) { return new ParagraphView(elem); } else if (kind.equals(AbstractDocument.SectionElementName)) { return new BoxView(elem, View.Y_AXIS); } else if (kind.equals(StyleConstants.ComponentElementName)) { return new ComponentView(elem); } else if (kind.equals(StyleConstants.IconElementName)) { return new IconView(elem); } } // default to text display return new LabelView(elem); } } private class WarpLabelView extends LabelView { public WarpLabelView(Element elem) { super(elem); } @Override public float getMinimumSpan(int axis) { switch (axis) { case View.X_AXIS: return 0; case View.Y_AXIS: return super.getMinimumSpan(axis); default: throw new IllegalArgumentException("Invalid axis: " + axis); } } } // 本类 // 构造函数 public JIMSendTextPane() { super(); this.setEditorKit(new WarpEditorKit()); } } 这个派生子类JIMSendTextPane作为输入消息区域,是完全能够满足要求了,也可以实现插入图片,图文混排,文字样式自定义等等。但是对于显示消息的区域,这个派生子类还不够。因为显示消息的区域涉及到聊天消息气泡、头像的绘制,这必须依靠JTextPane派生子类的自绘方式实现。当然,显示消息区域也必须要具备任意情况下的超宽内容换行,而JIMSendTextPane恰好已具备了这个换行能力,所以显示消息区域要以JIMSendTextPane为父类,再进行子类派生。(未完待续) 果然是大神,以前我还在为这个问题纠结,为什么jdk版本高了这个好用的功能反而没了 |
|
返回顶楼 | |
发表时间:2015-06-07
嗯,是的,原来Java 6都还是好的,但是到了Java 7好像就出现这种问题了,你说它是个bug也行,但也许Oracle认为这不算bug,他们认为以空格为区分是很正当的吧,呵呵。。。
|
|
返回顶楼 | |
发表时间:2015-06-07
cyberniuniu 写道 嗯,是的,原来Java 6都还是好的,但是到了Java 7好像就出现这种问题了,你说它是个bug也行,但也许Oracle认为这不算bug,他们认为以空格为区分是很正当的吧,呵呵。。。
中文是没有问题的,不管在jdk几里面都可以换行,到了7之后英文和数字就没有了 大神,继续更贴,坐等学习 |
|
返回顶楼 | |
发表时间:2015-06-20
大神,为何不继续更贴了?
|
|
返回顶楼 | |
发表时间:2015-06-24
明天更新,这几天忙别的事了
|
|
返回顶楼 | |