事件扩展修饰符与位运算

今天查看别人重写的鼠标拖动事件的源码时,有一段代码很不解

1     public void mouseDragged(MouseEvent e) {
2         form.setCursor(mc);
3         if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0)
4             form.setLocation(e.getXOnScreen() - this.x, e.getYOnScreen()
5                     - this.y);
6     }

这里(e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0  究竟是什么意思呢?在判断什么呢?
经过查询资料后,发现e.getModifiersEx()方法返回此事件的扩展修饰符掩码。扩展修饰符表示所有模式键的状态,例如 ALT、CTRL、META 和事件发生后那一刻的鼠标按钮。

先将下面的例子,这是api上给的示例:

建议不使用 == 来比较此方法的返回值,因为在以后会增加新的修饰符。例如,检查 SHIFT 和 BUTTON1 已经按下而 CTRL 未按下的正确方法可以通过以下代码来演示:

    int onmask = SHIFT_DOWN_MASK | BUTTON1_DOWN_MASK;
    int offmask = CTRL_DOWN_MASK;
    if (event.getModifiersEx() & (onmask | offmask) == onmask) {
        ...
    }
 

即使添加了新的修饰符,上述代码仍然有效。

查看java源码中这些修饰符的定义,其实是将1进行位运算得出的,相当于标示位:

public static final int BUTTON1_DOWN_MASK = 1 << 10; //也就是 10000000000(二进制)

public static final int SHIFT_DOWN_MASK = 1 << 6;  //也就是1000000

 那么

SHIFT_DOWN_MASK | BUTTON1_DOWN_MASK=10001000000,那么也就是说,如果SHIFT 和 BUTTON1 已经按下返回的值应该是10001000000,所以应该和SHIFT_DOWN_MASK | BUTTON1_DOWN_MASK相等。

返回来看上面的问题,这是鼠标拖动事件重写,也就是鼠标左键要按下,而其他键不管,也就是修饰符的二进制码的从右往左的第7位必须是“1”(因为SHIFT_DOWN_MASK = 1 << 6;  //也就是1000000),而 & 的规则是“两边都是真才是真(0是假,1是真)”,所以如果修饰符的第七位是1的话,最后的结果必不为0,而是1000000。

由此可见,java通过二进制位上的数字来记录不同的状态,(e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0 目的就是检查鼠标左键是否按下

时间: 2024-09-27 22:34:22

事件扩展修饰符与位运算的相关文章

vue-learning:28 - component - 组件事件的修饰符`.native / .sync`,以及组件属性`model`

组件事件的修饰符.native / .sync,以及组件属性model .native 原生事件修饰符 在一个组件中,如果我们为其绑定一个原生的点击事件@click,基本是无效的. 在vue中对组件绑定原生事件需要带上原生事件修饰符.native. 在组件中同时存在原生事件和自定义事件,组件自定义事件先于原来事件执行 <div id="app"> <p>this is event example for .native/@<p> <com-ch

vue中常用的事件和修饰符简单总结

1:阻止冒泡事件 JS事件流其中一种是冒泡事件,当一个元素被触发一个事件时,该目标元素的事件会优先被执行,然后向外传播到每个祖先元素,恰如水里的一个泡泡似的,从产生就一直往上浮,到在水平面时,它才消失.在这个过程中,如果你只希望事件发生在目标元素,而不想它传播到祖先元素上去,那么你需要在"泡泡"离开对象之前刺破它. 在vue中怎么写? 2:阻止默认行为 在vue中怎么写? 3:键盘事件 获取键码?通过事件对象来获取 注意:keydown事件和keyup事件的区别? keydown是在键

Vue.js学习笔记(三) - 修饰符

本篇将简单介绍常用的修饰符. 在上一篇中,介绍了 v-model 和 v-on 简单用法.除了常规用法,这些指令也支持特殊方式绑定方法,以修饰符的方式实现.通常都是在指令后面用小数点“.”连接修饰符名称. 一.v-model的修饰符 v-model 是用于在表单表单元素上创建双向数据绑定的指令.在 <input> 和 <textarea> 上,默认通过监听元素的 input 事件来更新绑定的属性值. 为了能明显的看到绑定属性值的变化,需要在Chrome浏览器中安装Vue Devto

【转】Cocoa中的位与位运算

转自:http://www.tuicool.com/articles/niEVjy 介绍 位操作是程序设计中对位模式或二进制数的一元和二元操作. 在许多古老的微处理器上, 位运算比加减运算略快, 通常位运算比乘除法运算要快很多. 在现代架构中, 情况并非如此:位运算的运算速度通常与加法运算相同(仍然快于乘法运算).(摘自wikipedia) OC作为c的扩展和超集,位运算自然使用的是c的操作符.c提供了6个位操作符,$,|,^,~,<<,>>.本文不打算做位运算的基础教学,只介绍一

12、类成员访问修饰符public/private/producted/readonly

1.private 类的私有成员 private 类的私有成员,只能在内部访问,在外部访问不到,无法被继承,我们可以将不需要被外部修改的定义为私有的 私有成员,只能在内部访问,在外部访问不到 private 可以在类的内部访问私有成员,不能再外部访问,但是在外部可以访问这个getType,从而访问到type,方法也是默认public公开的 私有成员无法被继承  2.protected受保护的 和private类似,也是私有成员,只能在内部访问,外部无法访问,但是可以被继承 可以被继承,但是只能在

C#原始类型扩展方法—this参数修饰符

扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用.对于用 C# 和 Visual Basic 编写的客户端代码,调用扩展方法与调用在类型中实际定义的方法之间没有明显的差异. 扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的.它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀.仅当您使用 using 指令将命名空间显式导入到源代码中之后,扩

使用 &amp; ^ &lt;&lt; 等 位符实现加法运算

学习过C语言的同学都知道,再写代码的时候,位操作运算总比算数运算操作快, 本文就是用C语言提供的位运算实现两个数的加法. 本文使用的代码都经过调试正常并且能够运行,调试环境centos     gcc  一下是实现代码,以及测试结果: #include<stdio.h> #include<stdlib.h> int main(int argc, char **argv) { int add_a,add_b; int sum; if(3!=argc) printf("usa

C# this用法系列(二) 通过this修饰符为原始类型扩展方法

定义一个静态类,类中定义静态方法,方法中参数类型前边加上this修饰符,即可实现对参数类型的方法扩展 示例如namespace Demo{ // 这里的类必须为静态类 public static class Json { // 方法为静态方法 // this修饰符后边是string类型,即为string类型扩展出了ToJson方法 public static object ToJson(this string Json) { return Json == null ? null : JsonCo

Swift中的访问修饰符对于扩展(extension)的影响

在Swift中,有一种结构extension,类似于OC中的Category分类,非常适合于对代码进行管理 同时,常用的访问修饰符有public.internal.private,而对于这三个访问修饰符,对extension的影响是各不一样的 在本文中,我将对同一文件下和不同文件下的extension.在本类和其他类调用,共四种情况进行分别介绍. 在介绍前,我先创建了一个非常简单的iOS项目,并新建了一个Person类和Person类的extension文件,如下图: 其中,Person类的代码