swing 聊天窗体,支持图文模式
package com.*.test; import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException; import javax.swing.JFrame;
import javax.swing.text.EditorKit;
import javax.swing.text.html.HTMLEditorKit; import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils; import javax.swing.JEditorPane;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener; import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.awt.event.ActionEvent; public class ChatForm { private JFrame frame; /**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ChatForm window = new ChatForm();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
} /**
* Create the application.
*/
public ChatForm() {
initialize();
} /**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame("与 XXX 对话");
frame.setSize(766, 615);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
EditorKit k = new HTMLEditorKit(); JScrollPane scrollPane_1 = new JScrollPane();
scrollPane_1.setBounds(10, 10, 730, 350);
frame.getContentPane().add(scrollPane_1); final JEditorPane editorPane = new JEditorPane();
scrollPane_1.setViewportView(editorPane);
editorPane.setEditable(false);
editorPane.setEditorKit(k); JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 373, 730, 161);
frame.getContentPane().add(scrollPane); final JEditorPane editorPane_1 = new JEditorPane();
scrollPane.setViewportView(editorPane_1);
editorPane_1.setEditorKit(k); // 注册剪贴板事件
KeyStroke aKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK, true);
editorPane_1.addAncestorListener(new AncestorListener() { @Override
public void ancestorRemoved(AncestorEvent event) {
System.out.println("ancestorRemoved");
} @Override
public void ancestorMoved(AncestorEvent event) {
System.out.println("ancestorMoved");
System.out.println(editorPane_1.getText());
} @Override
public void ancestorAdded(AncestorEvent event) {
System.out.println("ancestorAdded"); }
}); // 注册ctrl+v事件,每次添加都是在文档html末尾追加的方式,所以可以多次粘贴
editorPane_1.registerKeyboardAction(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
DataFlavor[] flavots = Toolkit.getDefaultToolkit().getSystemClipboard().getAvailableDataFlavors();
for (DataFlavor dataFlavor : flavots) {
try { // 获取剪贴板数据
Object obj = Toolkit.getDefaultToolkit().getSystemClipboard().getData(dataFlavor);
System.out.println(obj.getClass());
// 如果是文字内容
if (obj instanceof InputStream) {
InputStream bts = (InputStream) obj;
editorPane_1.setText(editorPane_1.getText().replace("</body>", IOUtils.readLines(bts, "utf-8").toString().replaceAll("\n", "<br/></body>")));
} else if (obj instanceof Collection<?>) {
// 多文件内容
Collection<?> c = (Collection<?>) obj;
String s = ""; for (Object object : c) {
File f = (File) object;
if (FilenameUtils.getExtension(f.getName()).equals("jpg")) {
s += "<img style=\\\"height:300px;width:200px\\\" src='file:///" + f.getAbsolutePath() + "'/><br/>";
}
}
editorPane_1.setText(s.replace("</body>", s + "</br></body>"));
} else if (obj instanceof BufferedImage) {
// 截图内容
BufferedImage img = (BufferedImage) obj;
String savePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
savePath = FilenameUtils.separatorsToUnix(savePath);
System.out.println(savePath);
File file = new File(savePath + "/" + System.currentTimeMillis() + ".png");
ImageIO.write(img, "png", file); editorPane_1.setText(editorPane_1.getText().replace("</body>", "<img style=\"height:300px;width:200px\" src='file:///" + file.getAbsolutePath() + "'/><br/></body>"));
}
} catch (HeadlessException e1) {
e1.printStackTrace();
} catch (UnsupportedFlavorException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}, aKeyStroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
JButton button = new JButton("发送"); // 点击发送按钮的事件
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 清空下面的内容,设置上面的内容
String s = editorPane_1.getText();
editorPane_1.setText("");
editorPane.setText(s);
}
}); // 注册ctrl+回车事件
button.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 清空下面的内容,设置上面的内容
String s = editorPane_1.getText();
editorPane_1.setText("");
editorPane.setText(s);
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, ActionEvent.CTRL_MASK, true), JComponent.WHEN_IN_FOCUSED_WINDOW);
button.setBounds(628, 544, 93, 23);
frame.getContentPane().add(button);
}
}
swing 聊天窗体,支持图文模式的更多相关文章
- IOS开发UI篇--一个支持图文混排的ActionSheet
一.简单介绍 UIActionSheet是IOS提供给我们开发人员的底部弹出菜单控件.一般用于菜单选择.操作确认.删除确认等功能.IOS官方提供的下面方式对UIActionView进行实例化: - ( ...
- Swing常用窗体
Swing常用窗体 Swing 主要具有以下特点: ( 1 )轻量级组件. ( 2 )可插入外观组件. 窗体作为Swing的应用程序中组件的承载体,处于非常重要的地位.Swing中常用的窗体包括JFr ...
- C# 非模式窗体show()和模式窗体showdialog()的区别(转)
对话框不是模式就是无模式的.模式对话框,在可以继续操作应用程序的其他部分之前,必须被关闭(隐藏或卸载).例如,如果一个对话框,在可以切换到其它窗 体或对话框之前要求先单击“确定”或“取消”,则它就是模 ...
- 二十九、EFW框架开发的系统支持SaaS模式和实现思路
回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://p ...
- JavaScript和angularJs语法支持严格模式:”use strict”
如果给JavaScript和angularjs代码标志为“严格模式”,则其中运行的所有代码都必然是严格模式下的.其一:如果在语法检测时发现语法问题,则整个代码块失效,并导致一个语法异常.其二:如果在运 ...
- nginx低版本不支持pathinfo模式,thinkphp针对此问题的解决办法
将一个thinkphp项目从apache环境移到nginx1.2上,怎奈,nginx这个版本默认不支持pathinfo模式 首先,编辑nginx的虚拟主机配置文件 location ~ .*.(php ...
- JavaScript语法支持严格模式:"use strict"
如果给JavaScript代码标志为“严格模式”,则其中运行的所有代码都必然是严格模式下的.其一:如果在语法检测时发现语法问题,则整个代码块失效,并导致一个语法异常.其二:如果在运行期出现了违反严格模 ...
- AS3聊天单行输入框图文混排完美实现
几年前刚毕业.第一个游戏模块做的就是聊天.到如今.几个游戏写过几次聊天模块. 之前在4399做的<幻龙骑士>(又名<神骑士>),还有上周六刚上线的<疯狂的子弹>, ...
- 浅谈C#中的模式窗体和非模式窗体
ShowDialog(); // 模式窗体 Show(); // 非模式窗体 区别: 返回值不同,DialogResult/void 模式窗体会使程序中断,直到关闭模式窗口 打开模式窗体后不能切换到应 ...
- C# 非模式窗体show()和模式窗体showdialog()的区别
对话框不是模式就是无模式的.模式对话框,在可以继续操作应用程序的其他部分之前,必须被关闭(隐藏或卸载).例如,如果一个对话框,在可以切换到其它窗 体或对话框之前要求先单击"确定"或 ...
随机推荐
- import.meta.globEager('./src/components/**/*.vue'); 遍历文件
main.js const importAll = (modules) => { Object.keys(modules).forEach((key) => { const compone ...
- STM32进入HardFault_Handler的调试方法
在编写STM32程序代码时由于自己的粗心会发现有时候程序跑着跑着就进入了 HardFault_Handler中断,按照经验来说进入HardFault_Handler故障的原因主要有两个方面: 1:内存 ...
- JSF之Action 与ActionListener的区别
事件 检验 参数 事件产生 页面跳转 Action 有 无参数,不传入当前控件,有返回值 当铵钮被单击时产生事件.提交表单 返回页面---根据配置文件跳转 ActionLis ...
- 矢量数据库与LLM的集成:实践指南
矢量数据库与LLM的集成:实践指南 本文将了解到什么是矢量数据库,以及如何与LLMs进行集成.通过LLMs和向量数据库的结合,可以节省微调带来的开销和时间. 通常,LLM会在各种各样的数据上进行训练, ...
- django项目(博客二)
扩展1:admin路由分发的本质 路由分发本质 include 可以无限制的 嵌套N多层 url(r'^index/',([],None,None)) 扩展2: 由于url方法第一个参数是正则表达式, ...
- WebView库功能完善
目录介绍 01.loadUrl到底做了什么 02.触发加载网页的行为 03.webView重定向怎么办 04.js交互的一点知识分享 05.拦截缓存如何优雅处理 06.关于一些问题和优化 07.关于一 ...
- Saltstack 最大打开文件数问题之奇怪的 8192
哈喽大家好,我是咸鱼. 今天分享一个在压测过程中遇到的问题,当时排查这个问题费了我们好大的劲,所以我觉得有必要写一篇文章来记录一下. 问题出现 周末在进行压测的时候,测试和开发的同事反映压测有问题,请 ...
- 李沐动手学深度学习pytorch实践笔记
1.pytorch中的矩阵乘法: 2.标量对向量求导: 3.pytorch的backward函数: 4.如何直观理解梯度下降: 梯度,是个向量,有方向和长度就是向量,向量里的各个元素是偏导.是标量对向 ...
- ps去除图片中间部分并拼合
今天分享一个用ps去除图片中间部分后,把剩下的部分拼合的技术. 需求 下面这张图,需要去掉第三列(顺丰包邮价) ps处理过程 1.导入图片到ps软件 快捷键方式:Ctrl + O: 手动打开方式:点击 ...
- C# 证件照替换底色、设置背景图
软件说明 基于以下开源项目,做了再次封装 PaddleSegSharp: 本项目是一个基于百度飞桨PaddleSeg项目的人像分割模块而开发的.NET的工具类库.PaddleSeg是基于飞桨Paddl ...