一、应用场景
之前一直使用的是QQ的截图功能,但有时候QQ忘记上线,想要进行截图还得重新上线之后才行。就想着开发一个简单的小工具用于实现单纯截图,并将截图复制到粘贴板供用户粘贴。
二、关键点
- 如何实现截图
- 如何实现快捷键注册监听
- 如何实现开机启动
- 如何生成可执行文件
三、待解决的问题
- 快捷键每次只能按一下,长按会出错。(注册热键监听之后没按一次快捷键都会触发监听事件,长按会一直触发事件)
- 可执行文件运行之后截图的背景板不是全屏背景。(必须在桌面的显示设置中将放缩比例设置成100%才能正常运行,而默认并不是100%)
待后续更新。
五、项目实施
(一)核心代码实现
全屏截图:
//Dimension用于封装组件得宽和高
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
//Rectangl用于描述一个封闭得矩形区域
Rectangle screenRectangle = new Rectangle(screenSize);
//根据获取矩形区域中的像素,生成可访问的额图像数据缓冲区
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(screenRectangle);
选取截图:
private void captureScreen(int x, int y, int w, int h) {
//fullBufferedImage是全屏图像数据
//根据以(x,y)为左上角起点,宽为w高为h的矩形区域来选取图像数据实现部分截图
currBufferedImage = fullBufferedImage.getSubimage(x, y, w, h);
}
截图复制到粘贴板
/**
* 将截图复制到粘贴板
* @param buffImage 缓冲图像数据
*/
private void screenCopy(final BufferedImage buffImage) {
try {
Transferable trans = new Transferable() {
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{DataFlavor.imageFlavor};
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return DataFlavor.imageFlavor.equals(flavor);
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (isDataFlavorSupported(flavor))
return buffImage;
throw new UnsupportedFlavorException(flavor);
}
};
//复制到粘贴板
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(trans, null);
} catch (Exception exe) {
exe.printStackTrace();
//设置错误弹窗
JOptionPane.showMessageDialog(new JDialog(), "Error copying to pasteboard!", "Eorrr", JOptionPane.ERROR_MESSAGE);
}
}
设置快捷键并注册监听
import com.melloware.jintellitype.HotkeyListener;
import com.melloware.jintellitype.JIntellitype;
/**
* @author QinJiaYing
* @description: 全局键盘监听
* @date 2021/10/25 13:31
*/
public class GlobalListener {
public GlobalListener() {
//组合键ctrl+shfit+A:进行截图
JIntellitype.getInstance().registerHotKey(0, JIntellitype.MOD_CONTROL + JIntellitype.MOD_SHIFT, (int) 'A');
//组合键ctrl+shfit+O:退出程序
JIntellitype.getInstance().registerHotKey(1, JIntellitype.MOD_CONTROL + JIntellitype.MOD_SHIFT, (int) 'O');
}
public void listening() {
JIntellitype.getInstance().addHotKeyListener(new HotkeyListener() {
public void onHotKey(int markCode) {
switch (markCode) {
case 0://给标识符为0的热键设置监听
System.out.println("I am listening……");
ScreenCapture.getInstance().doFunction();
break;
case 1://给标识符为1的热键设置监听
//用于移除热键注册的方法,把变量名为1的变量删除。
JIntellitype.getInstance().unregisterHotKey(1);
//用于移除热键注册的方法,把变量名为0的变量删除。
JIntellitype.getInstance().unregisterHotKey(0);
//结束程序
System.exit(0);
}
}
});
}
}
(二)开机启动
想着使用JNIRegistry操作Windows注册表,向其中添加开机启动项目,但没有找到64bit的工具包(官网给的是32bit的),所以这部分功能没有通过程序实现。手动添加注册表可以参考注册表里如何添加开机启动项
待后续更新
(三)项目打包
参考链接:使用IDEA将项目打成jar包
这里选择第二个选项,将外部工具包也导出。
(四)生成exe文件
1、创建一个文件夹,将打包好的jar、jre文件夹、icon图标放进入。
icon在线制作工具:
1、制作图标:https://www.canva.cn/design/DAEtvQ2htmU/T_EDA-gWRm-ScD6HuleLMg/edit
2、转换为icon文件:http://www.ico51.cn/
2、选择项目类型
3、设置应用程序的名称以及输出位置
4、执行的方式默认选择GUI appliication。如果想要看到输出在控制台的信息则选择Console application.
5、设置32bit(默认)或64bit。
6、将用到的jar全部添加进去。"Main class from "中选择程序的主函数
7、设置jre最低版本要求。最高版本可简省
8、配置jre目录
可以将默认选择全部删除(如不不删除的话会按顺序从上到下找jre环境)。
重新添加jre目录
9、直接finish或一路nxet。最终生成文件成功,可点击直接运行。
安装完之后会发现真正的应用程序大小不到1M,但是运行环境就占了近200M,这就是Java语言为实现跨平台而带来的弊端。(其他编译型语言比如C++,编写的应用程序就不写要添加额外的运行环境就能将代码编译成可执行文件)。优化方法:
1、jre进行精简化,将一些程序中用不到的api删掉。
2、可以使用Install4J(官网下载,有3个月的试用期)进行应用程序的打包。(使用install4j打包之后就可以向其他应用程序一样提供给用户安装了。但个人在尝试使用的时候没成功,暂时不会用,后续待更新)
小结
缺憾:由于是第一次写此类项目,加之个人能力有限,最终代码实现存在较大的缺陷。(待后续完善)
收获:了解了桌面应用开发的流程。