实现远程控制系统,无非就是实现两点:
被控端远程屏幕的传送
客户端控制命令的传送
远程屏幕的传送这次先不做讨论,今天我们仅考虑下控制端操控信息的传送。
要实现远程控制,流程无非就是:
把客户机在服务器界面相应位置的鼠标、键盘信息记录下来--------按照协议打包消息-------发送给被控端------被控端接收消息-----依据协议解封消息------得到客户端传来的鼠标、键盘命令------根据命令,使用Robort对象驱动该命令------被控端系统做出响应。
完成远程操控的机制是明白了,然而讲述远程操控的机制并不是此文重点。
下面简单介绍下在根据完成以上流程时自己遇到的几个问题。
问题一:
不可识别的鼠标组合标识,报出异常
Exception in thread "main" java.lang.IllegalArgumentException: Invalid combination of button flags
在客户端,传送的鼠标标识通过e.getButton()得到
testJFrame.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
int flag=e.getButton(); }
到了被控端怎么就不可驱动了呢?
把每个鼠标事件得到的信息进行打印
发现,鼠标的左中右3个按键对应的flage值分别是 1 2 3
看Robot API,驱动鼠标时,传入的INT型参数buttons
用的分别是InputEvent.BUTTON1_MASK,InputEvent.BUTTON2_MASK,InputEvent.BUTTON3_MASK
打印着3个常量 对应的值分别是 16 8 4
并不是我们得到的flag值
也就是说我们直接用Robot.mousePress来驱动flag是不对的
必须使用对应的InputEvent里面的常量
接收鼠标按键信息,驱动鼠标事,代码可写为
try {
robot = new java.awt.Robot();
if (flag== 1) {
robot.mouseRelease(InputEvent.BUTTON1_MASK);
}
if (flag== 2) {
robot.mouseRelease(InputEvent.BUTTON2_MASK);
}
if (flag==3) {
robot.mouseRelease(InputEvent.BUTTON3_MASK);
}
问题搞定
问题二
keyBoardListener每次只能监听到键盘按键的一个信息(press/release)
如果我们要完成组合键功能该怎么实现呢?
一次传几个键的信息过去?
这个思路貌似是很顺其自然的。然而我们很快会发现,我们每次对键盘做出刺激后,键盘
只是做出反应
是无法监听到我们一次按下几个键,间隔了多少时间,而且根本就没有一个标准说多少秒 内按算是组合键,怎么样才算是组合键呢?这该怎么定义呢?
苦思良久
顿悟
所谓组合,不就是一个键press后,还没来得及release,另外一个键又press了嘛?
也就是说,我们只要在每个键press或release时,把该消息发给被控端,并且用robot驱动,则在服务端,系统能根据按键的信息,自动就完成了组合键的功能
问题3
全局热键
大家可能会有过这样的经历,看电影时,我们的QQ已经被最小化了,当我们听到好友消息时,只要按下提取消息的热键(比如Ctrl+Alt+Z),QQ面板就自动弹出来,提出消息
然后,大家可以做个测试,跟好友用QQ开远程协助,在远程协助界面按下提取消息的热键 (比如Ctrl+Alt+Z)咱看看弹出来的到底是咱自己的QQ面板还是被控端的QQ面板。
实验的结果是让人伤心的,弹出的是咱自己的QQ面板,也就是说这些系统的全局热键起作用的域是咱自己的机器,而不是传过去发给被控机。
问题提出来了,那该怎么解决呢?
百度之,GOOGLE之
全局热键,系统属性,VB VC改起来比较简单。JAVA就……………………
所以,先保留这个问题吧。
问题4
组建是否为屏幕焦点以及鼠标、键盘监听器到底应该加给界面的那个组件
写一个界面,我们在界面上加上JButton组件,给组件加鼠标的3个监听器。
通过输出打印测试,我们很容易发送,只有当鼠标进入界面,且界面为屏幕焦点时,鼠标事件才会被监听到
这本是个好事,这样的机制,确保只有当我们开始监控的时候才传送操作信息给被控端
以为键盘事件大致也会如此吧。
对界面加上键盘事件监听器keyBoardListener当界面上什么组件都不加的时候,通过打印我们发现界面能监听到键盘的所有操作。
如果我在界面上加个小组件,比如一个JButton butoon,然后,神奇的事情发生了,键盘事件监听不到了。
但是当我把键盘事件加在这个button组件上时,键盘事件又能监听到了。
难道要监听键盘事件,需要监听的组件在最前面,是屏幕的焦点?好奇!
同样的实验,把JButton换成JLabel发现彻底监听不到键盘事件,悲剧。。。。
此例中,为了实现鼠标事件和键盘事件的正确监听和发送,我们先把鼠标监听器加在显示Server界面的LABEL上,键盘监听器加在界面的操控按钮button上
下期关注
MouseAdapte与鼠标的3个监听器异同
监听器模型分析