`

JAVA文本域插入表情

阅读更多







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;
	}
}
  • 大小: 7.2 KB
  • 大小: 84.8 KB
  • 大小: 10.5 KB
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

Global site tag (gtag.js) - Google Analytics