前言

今天, 说一下java.awt.Robot 的用法, 此类用于为测试自动化、自运行演示程序和其他需要控制鼠标和键盘的应用程序生成本机系统输入事件。Robot 的主要目的是便于 Java 平台实现自动测试。

这个家伙可厉害了, 可以模拟键盘操作, 鼠标操作, 以及截图
其实 我接触这个家伙, 也是在一个比较偶然的情况下, 一个家伙在贴吧问如何实现透明的界面, 然后司马大水神貌似是贴了一下Robot截图的时候, 然后 后来搜了一下api文档, 看了一下
从此 一些相关的问题, 我通常会向Robot考虑一下的

注意

请确保你在发消息的过程中不会有其他的弹窗之类的出现, 如果有的话, 那么会对该窗口产生相应的按键的效果的 !
所以 此类一定要慎用, 确保两批模拟按键之间的间隔时间内你能够关掉程序, 否则 是很危险的 !

试想 如下场景, 如果你启动了一个程序, 将鼠标每次移动到(100, 100)的位置, 并且占用了键盘[用户不能操作键盘了], 而每两次模拟鼠标移动的时间间隔为100毫秒, 那么 只要程序启动起来了, 你的机器是不是就只能看着他在这里干耗电 或者强制关机了!

又或者 你在模拟点击的时候恰好一个弹窗出来, 然后程序点击了他, 给你造成了经济 或者其他的损失, 那是不是非常不划算 !

所以 再次提醒, 请慎用 !

01 qq消息刷屏

不知道各位快要毕业的同学是否收到过这样的消息, 卧槽 隔三差五的给你发这么一条消息, 还叫你不要方案, 是不是不能忍…
那么 我经常干的事情就是, 给他发个几十条废话发送过去, 虽然 这样没有什么用, 但是 至少能够满足满足我们也骚扰一下他们的心里呗

思路 : 将给定的字符串复制到剪切板, 然后等待prepareMillus毫秒, 给用户准备的时间 [用户需要做的准备工作就是获取聊天对象的窗口], 然后就是一个循环发送消息[模拟"ctrl+v" 将剪切板的消息粘贴到聊天窗口, 然后再"alt+enter"发送消息]

当然 这也依赖于qq聊天的一个特性发送消息过后, 焦点会继续回到当前聊天窗口

效果如下图 :

参考代码如下 :
当然 一下代码是scala代码, 将他改写成java代码就好了, 替换一下属性, 方法的表示, 以及循环的表示

1 Test02SendMsgOnClipBoardForQQ : qq发送剪切板的信息

package com.hx.test01/*** fileName : Test02SendMsgOnClipBoardForQQ * Created by 970655147 on 2015-10-18 21:55.*/
object Test02SendMsgOnClipBoardForQQ {// 可配置对象// 两个按键// 发送消息的次数, 发送消息之前让用户准备的时间// 发送消息的间隔, 打印日志的间隔val robot = new Robot()val ctrlV = Array[Int](KeyEvent.VK_CONTROL, KeyEvent.VK_V)val ctrlEnter = Array[Int](KeyEvent.VK_CONTROL, KeyEvent.VK_ENTER)val prepareMillus = 5 * 1000val chatInterval = 1 * 100val sleepPerLog = 5 * 100// 消息, 消息内容的长度阈值, 获取消息内容 [超长, 用".."表示]val msg = "宝宝小逗比 !"val sendMsgTimes = 10val msgContentThreshold = 20val leaveOut = "..."val msgContent = if(msg.length > msgContentThreshold) {msg.substring(0, msgContentThreshold - leaveOut.length) + leaveOut} else {msg}// qq聊天 "ctrl+v" + "ctrl+enter"// 发送给逗逗def main(args :Array[String]) = {Tools.copyDataToClipBoard(msg)await(prepareMillus)for(i <- 0 until sendMsgTimes) {pressBts(ctrlV)pressBts(ctrlEnter)println("send the msg '" + msgContent + "' at : " + i + " times ... ")Tools.sleep(chatInterval)}}// 等待之前的打印日志def await(sleepMillus :Int) = {var remaining = sleepMilluswhile(remaining > 0) {println("before send msg : " + remaining + " ms")Tools.sleep(sleepPerLog)remaining -= sleepPerLog}}// 模拟按给定的按键序列, 并松开// 这里发现了一个问题 scala能够使用 "1 to 10", 表示"1, 2, ..., 10", 但是不能使用"1 to 10 2", 也就是说不能带步长// 带步长的使用方式 "1 to (10, 2)"def pressBts(keyCodes :Array[Int]) :Unit = {for (i <- 0 until keyCodes.length) {robot.keyPress(keyCodes(i))}//    for (i <- Range.inclusive(keyCodes.length-1, 0, -1)) {for (i <- (keyCodes.length-1) to (0, -1) ) {robot.keyRelease(keyCodes(i))}}}

2 Tools. copyDataToClipBoard(Object obj) : 将给定的字符串复制到剪切板

 // 将数据复制到剪切板public static void copyDataToClipBoard(Object obj) {Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();StringSelection ss = new StringSelection(obj.toString() );clipboard.setContents(ss, null);}

02 游聚刷新闻

。。这个小应用是关于一个游戏平台玩游戏的时候, 刷刷刷屏是否是感觉非常有逼格, 在你玩游戏的时候, 居然还能够发出消息,会让别人有一种神奇的感脚的[你的 手速这么快么, 还能边玩游戏, 边刷屏…]!

思路 : 将获取游聚游戏面板的焦点, 然后模拟"enter"获取聊天窗口的焦点, 然后模拟"ctrl+v"将数据粘贴到聊天窗口, 然后在模拟"enter"发送消息
这个过程中 需要改变的就是消息的内容啦, 至于消息的内容嘛, 可以从其他的输入源获取
我这里 是从百度上面抓取的新闻
当然, 这也依赖于游聚聊天的一个特性, 当获取游戏面板的焦点后, 按下enter键可以获取到聊天输入框的焦点

当然 这里还可以导出一个刷屏的方式, f1-f8为游聚的刷屏的快捷键, 冷却[硬直]时间间隔为5 sec, 所以 只要隔5 sec模拟一次"fn"的按键即可

因为gif太大了, 所以我将其分成了两部分


参考代码如下 :
1 Test03CrawlForBaiduNews : 爬取baidu新闻 [依赖于jsoup]

/*** file name : Test03CrawlForBaiduNews.java* created at : 8:54:12 PM Jun 26, 2015* created by 970655147*/package com.hx.crawler;public class Test03CrawlForBaiduNews {// 测试站点 : http://news.baidu.com/// 爬取百度新闻的, 所有主题public static void main(String []args) {String url = "http://news.baidu.com/";try {List<String> news = getAllNewsTitle(url);Log.log(news.iterator() );Log.log("get " + news.size() + " news !");} catch (IOException e) {e.printStackTrace();}}// 爬取所有的新闻标题public static List<String> getAllNewsTitle(String url) throws IOException {List<String> res = new LinkedList<>();Document doc = Jsoup.connect(url).get();Elements body = doc.select("div#body");// 1. 解析热点要闻Elements allKindOfNews = doc.select("div#pane-news");for(Element ele01 : allKindOfNews) {logTitle(ele01.parent().previousElementSibling(), "li.active");logNews(ele01, "ul", "li a", res);Log.enter(2);}// 2. 解析地方新闻, 以及其他 等等Elements withIdsDivs = body.select("div[id] div[class=column-title-home]");Set<Element> otherNews = new HashSet<>();for(Element ele01 : withIdsDivs) {
//          newsIds.add(ele.parent().attr("id"));Elements newss = ele01.parent().select("div ul");if(newss.size() == 0) {otherNews.add(ele01);}logTitle(ele01, "h2 a");logNews(newss, "li a", res);Log.enter(2);}// 解析特殊的新闻, 图片新闻for(Element otherNew : otherNews) {logTitle(otherNew, "h2 a");Elements news = otherNew.parent().select("a.txt");for(Element ele03 : news) {Log.log(ele03.text());res.add(ele03.text());}}return res;}// 打印标题private static void logTitle(Element ele, String selectStr) {Element title = ele.select(selectStr).get(0);Log.log(title.text());Log.horizon();}// 打印一个主题的新闻private static void logNews(Element ele, String selectStr01, String selectStr02, List<String> res) {Elements newss = ele.select(selectStr01);for(Element ele02 : newss) {Elements news = ele02.select(selectStr02);for(Element ele03 : news) {
//              Log.log(ele03.text());res.add(ele03.text());}Log.enter();}}// 重载, 相对于上面的方法, 这里直接提供了上面的newssprivate static void logNews(Elements newss, String selectStr01, List<String> res) {for(Element ele02 : newss) {Elements news = ele02.select(selectStr01);for(Element ele03 : news) {
//              Log.log(ele03.text());res.add(ele03.text());}Log.enter();}}}

2 Test04GetAllNewsToChat : 模拟发送游聚消息

/*** file name : Test04GetAllNewsToChat.java* created at : 8:11:31 PM Jun 27, 2015* created by 970655147*/package com.hx.crawler;public class Test04GetAllNewsToChat {// 将新闻内容 复制到游聚平台 聊天public static void main(String []args) {String url = "http://news.baidu.com/";int interval = 5000;List<String> news = null;try {news = Test03CrawlForBaiduNews.getAllNewsTitle(url);} catch (IOException e) {e.printStackTrace();}//        news  = new HashSet<>();
//      news.add("ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd");int start = 20;sendNews(news, interval, start);Log.log("end ... ");}// 发送所有的新闻public static void sendNews(List<String> newss, int interval, int start) {int idxForNews = start;Iterator<String> it = newss.listIterator(idxForNews);while(it.hasNext() ) {String news = it.next();Tools.sleep(interval);Log.log((idxForNews++ ) + " : " + news);sendNews0(news);}}// 模拟操作的robotprivate static Robot robot;private static int PAUSE_INTERVAL;static {try {PAUSE_INTERVAL = 10;robot = new Robot();} catch (AWTException e) {e.printStackTrace();}}// 按住enter的序列, 和按住 (ctrl + v) 的序列static List<Integer> enterSeq;static List<Integer> ctrlVSeq;static {enterSeq = new ArrayList<>();ctrlVSeq = new ArrayList<>();enterSeq.add(KeyEvent.VK_ENTER);ctrlVSeq.add(KeyEvent.VK_CONTROL);ctrlVSeq.add(KeyEvent.VK_V);}// 发送消息[复制信息到剪切板 + enter + (ctrl + v) + enter]public static void sendNews0(String news) {copyDataToClipBoard(news);pressVK(enterSeq);pressVK(ctrlVSeq);pressVK(enterSeq);}// 按住keyCodes, 并松开public static void pressVK(List<Integer> keyCodes) {for(int i=0; i<keyCodes.size(); i++) {robot.keyPress(keyCodes.get(i));}
//      Tools.sleep(PAUSE_INTERVAL);for(int i=keyCodes.size()-1; i>=0; i--) {robot.keyRelease(keyCodes.get(i));}}// 将数据复制到剪切板private static void copyDataToClipBoard(Object obj) {Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();StringSelection ss = new StringSelection(obj.toString() );clipboard.setContents(ss, null);}}

03 windows常亮

这是一个 由于以前遇到的一个问题, 因为 我的机器有时候睡眠之后, 在输入密码的话 网络就会断掉, 然后 再去点击链接无线的时候, 就会发现, 一个无线热点都不见了, 这时候 就只能重启电脑了,
还有一个场景就是玩游戏的有事的时候, 需要离开一会儿, 之后 回来的时候, 你会发现电脑休眠了, 然后重新登录时候, 就会发现游戏已经断开连接了…
所以 为了这几个问题, 我思考了一会儿 使用Robot定时模拟按键来维护windows的常亮

参考代码如下

/*** file name : Test06WindowsAlwaysOn.java* created at : 9:42:46 PM Aug 22, 2015* created by 970655147*/package com.hx.test01;public class Test06WindowsAlwaysOn {// 是系统常亮[不会进入睡眠状态]public static void main(String []args) {alwaysOn();}// robot 模拟用户操作static Robot robot;static int SLEEP_INTERVAL = 20 * 1000;static Point pos;static {try {robot = new Robot();pos = new Point(100, 100);} catch (AWTException e) {e.printStackTrace();}}// 是系统常亮[不会进入睡眠状态]public static void alwaysOn() {while(true ) {Log.log("program run now : " + getCurrentTime() );Point pos = getNextPoint();robot.mouseMove(pos.x, pos.y);sleep(SLEEP_INTERVAL);}}// 获取下一个鼠标的位置private static Point getNextPoint() {return pos;}// 获取当前时间的字符串表示private static String getCurrentTime() {return new Date().toString();}// 是当前线程睡眠sleep秒public static void sleep(int sleep) {try {Thread.sleep(sleep);} catch (InterruptedException e) {e.printStackTrace();}}}

======================= add at 2020.02.24 =======================

java – Robot.mouseMove在Mac OS X中根本不起作用
http://www.chinaoc.com.cn/p/1086831.html

在“系统偏好设置”(“齿轮”图标)中,在“安全”和“安全”下.隐私,单击顶部的“隐私”选项卡,然后选择左侧的“辅助功能”.这列出了可以“控制您的计算机”的所有程序.我正在使用STS,而不是IntelliJ.我看到STS与BetterSnapTool和KeyCastr一起列出.检查BetterSnapTool和KeyCastr.未检查STS.而且,所有这些都是灰色的,所以我不能改变任何检查.窗口左下角有一个Lock图标.我点击了图标,出现了一个提示,要求输入我的密码(我有一定级别的系统管理员权限).我输入了密码,现在我可以“检查”STS.我“检查”了STS(你将“检查”IntelliJ).在“检查”STS之后,我再次单击左下角的“锁定”图标.这个“关闭”了锁.现在,当我运行程序时,机器人命令会移动我的鼠标.

以上内容引用自上面的这个链接

end

总结 : 还是那句话, 请慎用 !

07 java.awt.Robot的一些使用相关推荐

  1. 使用java.awt.Robot实现java版的自动点击事件

    1.最近遇到了一个需要人工点击的事情,很麻烦,于是找了一下资料,写了一个自动的鼠标点击的程序 使用的包: java.awt.Robot 具体的代码 Robot robot = new Robot(); ...

  2. java.awt.robot api,像java.awt.Robot中的Andr​​oid API

    Is there an Android API analogous to java.awt.Robot, i.e. an API allowing to take screenshots? 解决方案 ...

  3. JAVA工具篇--java.awt.Robot模拟微信批量添加好友

    前言:java.awt.Robot可以控制鼠标和键盘,本文基于此通过模拟认为添加微信好友的过程实现批量添加微信好友,并最终输出微信号/手机号是否有好友及好友的基本信息,本文代码示例禁用学习交流使用: ...

  4. java awt robot

    Robot 类用于生成本机系统输入事件,用于测试自动化,自动运行演示和需要鼠标和键盘控制的其他应用程序. Robot的主要目的是为了方便Java平台实现的自动化测试. 经过封装后的 Robot api ...

  5. Mac环境下用Java(Sikuli+Robot)实现页游自动化

    转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ Sikulix(以前叫Sikuli)在Mac电脑的环境配置步骤如下: 1.从官网上下载Sikuli ...

  6. import java.awt.BorderLayout;_import java.awt

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 import java.awt.AWTException; import java.awt.BorderLayout; import java.awt.C ...

  7. Java:使用Robot类模拟键盘, 以Alt码方式输出汉字

    Java:使用Robot类模拟键盘, 以Alt码方式输出汉字 文章目录 Java:使用Robot类模拟键盘, 以Alt码方式输出汉字 java.awt.Robot类 使用Alt码输出汉字 尝试 `Al ...

  8. java中Robot

    用者本身这个系统事件,或根据使用者的需要(例如程序需要自动展示一些功能等)来控制鼠标或键盘.  在 Robot 这个类中产生的事件有别于在AWT元件中的事件,在AWT 元件中的事件(例如 MouseE ...

  9. java毕业设计——基于java+Java awt+swing的愤怒的小鸟游戏设计与实现(毕业论文+程序源码)——愤怒的小鸟游戏

    基于java+Java awt+swing的愤怒的小鸟游戏设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+Java awt+swing的愤怒的小鸟游戏设计与实现,文章末尾附有本毕 ...

  10. java.awt.color,AWT Color类

    颜色类规定在默认sRGB颜色空间或颜色的任意颜色空间中的颜色确定的颜色. 类的声明 以下是声明java.awt.Color类: publicclassColorextendsObjectimpleme ...

最新文章

  1. NNVM Compiler,AI框架的开放式编译器
  2. 网站SEO优化之如何建设外链提升网站权重?
  3. 北京大学Cousera学习笔记--3-计算导论与C语言基础-第一讲.计算机的基本原理-计算机怎么计算-数的二进制...
  4. python的运行环境_python-运行环境配置-1
  5. jQuery学习(五)—课堂实训题专栏
  6. 怎么通过controller层退出登录_控制层访问拦截
  7. C#调用GDAL算法进度信息传递
  8. 【渝粤教育】电大中专电子商务网站建设与维护 (3)作业 题库
  9. Make.am中生成.la动态库的同时要链接.a静态库的问题
  10. SharePoint And Ajax Technology(2):Ajax Control Toolkit学习
  11. 【unity发布webgl】遇到的问题和解决办法
  12. 4.7开发者日:创业工场麦刚认为创业者活下去最重要
  13. 使用卷积神经网络进行图片分类 2
  14. C++课程学习代码汇总基础
  15. 中国呼吸介入领导者堃博医疗在港交所挂牌上市;勃林格殷格翰收购Abexxa Biologics | 医药健闻...
  16. qt网络编程及readyread信号
  17. SpringMVC视图视图控制器
  18. Hyperf 热更新Watcher
  19. 使用lterator遍历set、list
  20. Java:学生管理系统

热门文章

  1. $body.on(‘click‘,‘button‘,function() {中.on在这里是什么意思的
  2. Toolbar中setNavigationIcon的返回图标太大,图标大小调整解决方法
  3. realize与recognize辨析
  4. linu安装JDK1.8
  5. C# OpenCvSharp 连通区域最小衔接矩形+最小标注信息(minx,miny,Width,Height)
  6. 禁漫排行榜周目公告版_华泰证券手机版下载-华泰证券涨乐财富通手机版下载V7.5.0安卓版...
  7. 潘多拉路由器搭建php,MT7620A 无线路由 极路由 1S 定制版 OPERWRT 潘多拉 中继 营销...
  8. openstack下创建windows虚机出现do_hivex_close
  9. Windows服务器应该如何保持长时间连接不断开。
  10. <冈萨雷斯图像处理>局部直方图处理:直方图统计(Histogram Statistics)