JAVA文本域插入表情

这篇博客展示了如何在Java的JTextPane组件中插入并显示表情。通过三张图片,作者逐步演示了表情的插入过程,为Java GUI应用添加更多互动元素。
摘要由CSDN通过智能技术生成
[img]http://dl2.iteye.com/upload/attachment/0112/0047/555cb69e-6c67-3ef8-96f6-5eb728833281.png[/img]

[img]http://dl2.iteye.com/upload/attachment/0112/0049/31b3cee1-d885-312d-aa8f-cec8bd8824e5.png[/img]

[img]http://dl2.iteye.com/upload/attachment/0112/0051/e726d635-166d-31b8-9030-106982f22636.png[/img]


package JTextPane;

import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;

/**
* @version 1.0
* @author 刘胜军
*/
public class JTextPaneTest extends JFrame {
private static final long serialVersionUID = 1L;

/** 定义一个历史面板,用于显示已经发送的文字 */
private JTextPane _old = new JTextPane();

/** 定义一个输入面板,用于显示正在输入的内容 */
private JTextPane _new = new JTextPane();

/** 表情按钮 */
private JButton face = new JButton();

/** 表情面板 */
private FaceAll faceall = null;

/** 声明三组样式,具体的在方法public static void styleInit() {}中定义 */
private Style style1 = null;
private Style style2 = null;
private Style style3 = null;

/** 下拉列表,用于选择样式 */
private JComboBox<String> box = new JComboBox<String>();

/** 发送按钮,用于将消息提交到历史面板 */
private JButton send = new JButton("提交");

public static void main(String[] args) {
new JTextPaneTest();
}

/**
* 构造方法,需要完成所以初始化操作 鼠标放在方法名上,可以显示其内容
*/
public JTextPaneTest() {
styleInit();
init();
}

/** 样式初始化 */
public void styleInit() {

Style style = _new.getStyledDocument().addStyle(null, null);// 获取组件空样式,addStyle(null,
// null)会返回一个空样式

StyleConstants.setFontFamily(style, "楷体");// 为style样式设置字体属性
StyleConstants.setFontSize(style, 18);// 为style样式设置字体大小

Style normal = _new.addStyle("normal", style);// 将style样式添加到组件,并命名为normal,返回一个样式由Style
// normal变量接收
/** 这个时候,组件编辑器关联的模型中就添加了一个样式normal,这个样式是最基本的一个样式,其他样式可以根据他进行修改 */

style1 = _new.addStyle("style1", normal);// 基于normal样式,在添加三次,分别命名为style1,style2,style3
style2 = _new.addStyle("style2", normal);// 此时,style1,style2,style3三个样式和normal样式是一模一样的
style3 = _new.addStyle("style3", normal);// 如果修改,可以对每个变量单独修改,具体修改方式如下

StyleConstants.setForeground(style1, Color.GREEN);// 将style1的颜色设置为绿色

StyleConstants.setForeground(style2, Color.RED);// 将style2的颜色设置为红色

StyleConstants.setForeground(style3, Color.BLACK);// 将style3的颜色设置为黑色
StyleConstants.setFontSize(style3, 14);// 将style3的大小设置为14
}

/** 初始化布局 */
public void init() {
this.setBounds(200, 100, 420, 520);
this.setLayout(null);

this._old.setEditable(false);
// 定义滚动面板,放历史面板,以实现滚动条(有需要的时候显示)和换行
JScrollPane js_old = new JScrollPane(_old,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// 设置位置大小
js_old.setBounds(0, 0, 400, 300);
// 添加到窗体
this.add(js_old);

// 定义滚动面板,放输入面板,以实现滚动条(有需要的时候显示)和换行
JScrollPane js_new = new JScrollPane(_new,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// 设置位置大小
js_new.setBounds(0, 350, 400, 150);
// 添加到窗体
this.add(js_new);

this.box.addItem("style1");
this.box.addItem("style2");
this.box.addItem("style3");
this.box.setBounds(50, 315, 100, 20);
this.add(this.box);

this.face.setBounds(190, 315, 20, 20);
this.add(this.face);

this.face.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
super.mouseEntered(e);
face.setBorder(BorderFactory.createLineBorder(Color.ORANGE));
}

@Override
public void mouseExited(MouseEvent e) {
super.mouseExited(e);
face.setBorder(null);
}

@Override
public void mouseReleased(MouseEvent e) {
if (null == faceall) {
faceall = new FaceAll(JTextPaneTest.this);
faceall.setVisible(true);
// 设置控件相对于父窗体的位置
Point loc = getLocationOnScreen();
faceall.setBounds(loc.x + 10, loc.y + 30, 350, 300);
}
faceall.requestFocus();
}

});

this.send.setBounds(250, 315, 100, 20);
this.add(this.send);

this.send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
insertMessage(buildAllInfo());
}
});

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}

/**
* 遍历发送窗体内容,将表情信息提取出来,单独处理,每个表情的格式为:0&93+:第1个数字代表在消息内容里面的位置,&代码间隔,
* 第2个数字是表情编号 ,+代表结束符
*
* @return 返回表情信息完整字符串
*/
private String buildIconInfo() {
StringBuilder sb = new StringBuilder("");
// 遍历JTextpane找出所有的图片信息封装成指定格式
for (int i = 0; i < this._new.getText().length(); i++) {
if (_new.getStyledDocument().getCharacterElement(i).getName().equals("icon")) {
Icon icon = StyleConstants.getIcon(_new.getStyledDocument().getCharacterElement(i).getAttributes());
FaceIcon cupic = (FaceIcon) icon;
sb.append(i + "&" + cupic.getNumber() + "+");
}
}
return sb.toString();
}

/**
* 获取将要发送的信息内容,包括内容及表情,其中"|"代表的是文字消息与表情之间的分隔符
*
* @return 返回完整的将要发送的消息内容
*/
private String buildAllInfo() {
StringBuilder sb = new StringBuilder("");
sb.append(_new.getText());
sb.append("|");
sb.append(buildIconInfo());
return sb.toString();
}

/**
* 插入消息到聊天记录JTextPane
*
* @param message
*/
public void insertMessage(String message) {
try {
_old.setCaretPosition(_old.getStyledDocument().getLength()); /* 设置滚动到最下边 */
String mess = null;
String icon = null;
{// 拆分消息和图片代码
int index = message.lastIndexOf("|");// 获取最后间隔符的下标
mess = message.substring(0, index) + "\n";// 获取文字消息
icon = message.substring(index + 1, message.length());// 获取图片信息
}
// 记录历史面板要插入聊天消息的开始位置
int pos = _old.getStyledDocument().getLength();
{// 添加消息
_old.getStyledDocument().insertString(pos,mess,
(box.getSelectedItem().equals("style1")) ? style1 : (box.getSelectedItem().equals("style2")) ? style2 : style3);
}
// 添加表情
insertPics(icon, pos);
_old.setCaretPosition(_old.getStyledDocument().getLength()); /* 设置滚动到最下边 */
} catch (BadLocationException e) {
e.printStackTrace();
}
}

/**
* 插入图片
*
* @param icon
* 图片代码字符串
* @param pos
* 消息插入点位置
*/
private void insertPics(String icon, int pos) {
String[] ico = null;
ico = icon.split("[+]");
int i = 0;
for (String string : ico) {
String[] values = string.split("[&]");
if (values.length == 2) {
_old.setCaretPosition(pos + Integer.valueOf(values[0]) + i); /* 设置插入位置 */
String fileName = "/JTextPane/face/" + values[1] + ".gif";/* 修改图片路径 */
_old.insertIcon(new ImageIcon(JTextPaneTest.class.getResource(fileName))); /* 插入图片 */
i++;
}
}
}

/** 插入图片 */
public void insertImage(Icon icon) {
this._new.insertIcon(icon);
}

/** 清空表情面板 */
public void setFaceAll() {
this.faceall = null;
}

}



package JTextPane;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;

/**
* 自定义表情弹窗
*
* @version 1.0
* @author 刘胜军
*/
public class FaceAll extends JDialog {

private static final long serialVersionUID = 1L;

private JPanel contentPane;// 主容器
private JScrollPane JSPanel;// 滚动面板

private JLabel[] label = new JLabel[105];// 标签数组

private JTextPaneTest src;// 哪个窗体调用的

public FaceAll(JTextPaneTest src) {
this.src = src;
initGUI();
}

private void initGUI() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setBounds(100, 100, 350, 300);
setUndecorated(true);// 简易模式,没有标题栏
setAlwaysOnTop(true);// 所有窗体的最前面

contentPane = new JPanel();
contentPane.setBackground(Color.WHITE);
contentPane.setLayout(new GridLayout(12, 0));

JSPanel = new JScrollPane(contentPane,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
getContentPane().add(JSPanel, BorderLayout.CENTER);

String fileName = "";
for (int i = 0; i < label.length; i++) {
fileName = "/JTextPane/face/" + i + ".gif";
label[i] = new JLabel(new FaceIcon(FaceAll.class.getResource(fileName), i), SwingConstants.CENTER);
label[i].setBorder(BorderFactory.createLineBorder(new Color(225, 225, 225), 1));
label[i].setToolTipText(":)" + i);

label[i].addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
JLabel temp = (JLabel) e.getSource();
temp.setBorder(BorderFactory.createLineBorder(Color.BLUE));
}

@Override
public void mouseExited(MouseEvent e) {
JLabel temp = (JLabel) e.getSource();
temp.setBorder(BorderFactory.createLineBorder(new Color(225, 225, 225), 1));
}

@Override
public void mouseClicked(MouseEvent e) {
JLabel temp = (JLabel) e.getSource();
FaceIcon pic = (FaceIcon) temp.getIcon();
src.insertImage(pic);
FaceAll.this.setVisible(false);
src.setFaceAll();
FaceAll.this.dispose();
}
});
contentPane.add(label[i]);
}
this.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
FaceAll.this.setVisible(false);
src.setFaceAll();
FaceAll.this.dispose();
}
});
}
}



package JTextPane;

import java.net.URL;

import javax.swing.ImageIcon;

/**
* 自定义表情ICON
*
* @version 1.0
* @author 刘胜军
*/
public class FaceIcon extends ImageIcon {
private static final long serialVersionUID = 1L;
/**
* 图片编号
*/
private int number = 0;

/**
*
* @param url
* 图片URL
* @param number
* 图片编号
*/
public FaceIcon(URL url, int number) {
super(url);
this.number = number;
}

/**
* 获取图片编号
*
* @return
*/
public int getNumber() {
return number;
}

/**
* 重置图片编号
*
* @param number
*/
public void setNumber(int number) {
this.number = number;
}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值