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 聊天窗体,支持图文模式的更多相关文章

  1. IOS开发UI篇--一个支持图文混排的ActionSheet

    一.简单介绍 UIActionSheet是IOS提供给我们开发人员的底部弹出菜单控件.一般用于菜单选择.操作确认.删除确认等功能.IOS官方提供的下面方式对UIActionView进行实例化: - ( ...

  2. Swing常用窗体

    Swing常用窗体 Swing 主要具有以下特点: ( 1 )轻量级组件. ( 2 )可插入外观组件. 窗体作为Swing的应用程序中组件的承载体,处于非常重要的地位.Swing中常用的窗体包括JFr ...

  3. C# 非模式窗体show()和模式窗体showdialog()的区别(转)

    对话框不是模式就是无模式的.模式对话框,在可以继续操作应用程序的其他部分之前,必须被关闭(隐藏或卸载).例如,如果一个对话框,在可以切换到其它窗 体或对话框之前要求先单击“确定”或“取消”,则它就是模 ...

  4. 二十九、EFW框架开发的系统支持SaaS模式和实现思路

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://p ...

  5. JavaScript和angularJs语法支持严格模式:”use strict”

    如果给JavaScript和angularjs代码标志为“严格模式”,则其中运行的所有代码都必然是严格模式下的.其一:如果在语法检测时发现语法问题,则整个代码块失效,并导致一个语法异常.其二:如果在运 ...

  6. nginx低版本不支持pathinfo模式,thinkphp针对此问题的解决办法

    将一个thinkphp项目从apache环境移到nginx1.2上,怎奈,nginx这个版本默认不支持pathinfo模式 首先,编辑nginx的虚拟主机配置文件 location ~ .*.(php ...

  7. JavaScript语法支持严格模式:"use strict"

    如果给JavaScript代码标志为“严格模式”,则其中运行的所有代码都必然是严格模式下的.其一:如果在语法检测时发现语法问题,则整个代码块失效,并导致一个语法异常.其二:如果在运行期出现了违反严格模 ...

  8. AS3聊天单行输入框图文混排完美实现

    几年前刚毕业.第一个游戏模块做的就是聊天.到如今.几个游戏写过几次聊天模块. 之前在4399做的<幻龙骑士>(又名<神骑士>),还有上周六刚上线的<疯狂的子弹>, ...

  9. 浅谈C#中的模式窗体和非模式窗体

    ShowDialog(); // 模式窗体 Show(); // 非模式窗体 区别: 返回值不同,DialogResult/void 模式窗体会使程序中断,直到关闭模式窗口 打开模式窗体后不能切换到应 ...

  10. C# 非模式窗体show()和模式窗体showdialog()的区别

    对话框不是模式就是无模式的.模式对话框,在可以继续操作应用程序的其他部分之前,必须被关闭(隐藏或卸载).例如,如果一个对话框,在可以切换到其它窗 体或对话框之前要求先单击"确定"或 ...

随机推荐

  1. 【思维题、KMP】P3526 [POI2011]OKR-Periodicity 题解

    P3526 [POI2011]OKR-Periodicity 题解 前言 一道非常厉害的思维题.看题解得到了一些提示搞出来了. 作为 2011 年的题还是很厉害的. 约定 定义 \(s[l,r]\) ...

  2. 深入解析:AntSK 0.1.7版本的技术革新与多模型管理策略

    在信息技术快速迭代的当下,.Net生态中的AntSK项目凭借其前沿的AI知识库和智能体技术,已经吸引了广大开发者的关注和参与.今天,我要给大家介绍的主角,AntSK 0.1.7版本,无疑将是这个开源项 ...

  3. ENVI为遥感影像设置空间坐标系的方法

      本文介绍基于ENVI软件,对不含有任何地理参考信息的栅格遥感影像添加地理坐标系或投影坐标系等地理参考信息的方法.   我们先来看一下本文需要实现的需求.现有以下两景遥感影像,其位于不同的空间位置: ...

  4. Python使用os模块创建带时间戳的文件

    直接上源码: import os import time # 定义函数名:在py文件路径下创建cache的txt文件 def txt(name, text): # os.getcwd() 获取当前的工 ...

  5. 阿里云配置http转https

    参考:https://www.cnblogs.com/alexfly/p/10615986.htmlhttps://www.cnblogs.com/SemiconductorKING/p/910697 ...

  6. 算法研究之合并两个已排序的数组java版

    package com.zken.test; /** * @author iamzken * 2015-8-28 * 合并两个有序数组 * */ public class Sorter2 { publ ...

  7. JSF之Action 与ActionListener的区别

     事件  检验  参数  事件产生  页面跳转  Action  有 无参数,不传入当前控件,有返回值    当铵钮被单击时产生事件.提交表单   返回页面---根据配置文件跳转  ActionLis ...

  8. 【leetcode 2949 统计美丽子字符串】

    import java.util.HashMap; import java.util.Map; class Solution { public static void main(String[] ar ...

  9. 笔记:vite 的启动链路以及背后的部分原理

    这里分享一篇找到的文章 原文地址:https://blog.csdn.net/frontend_frank/article/details/106632197 NO.1 vite 是什么 vite - ...

  10. 工作记录:TypeScript从入门到项目实战(进阶篇)

    内置对象的使用 JavaScript中有许多内置对象,可以直接在JavaScript程序中使用,同样的,TypeScript也延续了这些内置对象 全局的对象( global objects )或称标准 ...