3.8关于WorldWind中的事件

事件处理机制:当事件发生后,会创建一个事件对象,然后,会在注册的事件监听列表中寻找能够处理该事件的监听器回调方法,处理完毕后事件被销毁,如果整个监听列表中都没有方法对其进行处理,最终也被销毁!

其整个处理过程是这样的,事件源可以注册事件监听器对象,并可以向事件监听器对象发送事件对象.事件发生后,事件源将事件对象发给已经注册的所有事件监听器. 监听器对象随后会根据事件对象内的相应方法响应这个事件。

应该说,当事件发生时,系统会创建事件对象,这个事件对象包括了事件的所有信息,即事件源,具体事件类型等;这样一来,事件对象就会被传到事件源,由事件源注册的事件监听进行处理!

事件对象应该是由系统(虚拟机)创建的,而不是应用程序,所以最初产生的事件对象类型都是鼠标键盘的标准事件对象,但是,在传给事件源进行处理的时候,监听器中的回调方法的事件参数可能是自定义的事件,但继承自EventObject,程序会不会尝试根据标准的事件对象来创建自定的事件对象,然后传入回调方法中进行处理呢?

如果不行,那么自定义事件作为事件处理方法的参数还有意义吗?

通过研究AWTInputHandler证明这一想法是正确的,jvm会创建ActionEvent,MouseEvent,KeyEvent对象,所以,我们将在这些监听中创建自定义的事件对象,调用相应的监听器进行处理!

对于系统怎么知道事件发生了这个问题,个人猜测是系统主动对鼠标,键盘等的状态进行判断的结果,说白了可能利用了死循环在进行判断,根据判断的结果生成事件对象,然后调用事件源监听器列表进行处理!

不过Window的消息处理机制否定了这一说法!

Windows是一个以消息为导向的系统,应用程序只能被动地等待用户按键的消息,不能主动地去读键盘的状态,也就是说,每当键盘上有个键被按下,系统就会发出一个按键消息给窗口,告诉它某个键被按下去了,只要鼠标移动一下,系统也会发出相应的消息,并把鼠标的坐标信息传给窗口。
Windows可以同时执行许多程序,但键盘只有一个,怎么判断由哪个窗口接收键盘及鼠标的消息呢?采用“ 输入焦点”(input focus)技术可以解决这个问题。只要某个窗口取得输入焦点,它不但会被提升到屏幕的最前面,颜色也会有所不同,所有的键盘消息就会导向该窗口,该窗口也成为“ 活动窗口”。
Windows消息控制中心一般是 三层结构 ,其顶端就是Windows内核。Windows内核维护着一个 消息队列 ,第二级控制中心从这个消息队列中获取属于自己管辖的消息,后做出处理,有些消息直接处理掉,有些还要发送给下一级 窗体 (Window)或控件(Control)。第二级控制中心一般是各Windows应用程序的Application对象。第三级控制中心就是Windows 窗体对象 ,每一个窗体都有一个默认的窗体过程,这个过程负责处理各种接收到的消息。

事件是窗口界面编程才有的概念,是用于实现用户交互,最终事件对象会发往窗体,而监听也是注册给窗体或控件的,这样,jvm将消息处理后生成事件对象,然后发往当前的焦点窗体,由窗体的监听器进行处理!

对于作用于非窗体控件对象的事件,系统不会将其作为事件源生成事件,这样一来,就需要应用程序自行检测事件的发生与否,比方关于图形对象是否被选中的事件,需要不断根据鼠标的位置来判断该位置处是否有图形对象,从而决定是否发起事件SelectEvent发生的监听处理!

AWTInputHandler
protected javax.swing.Timer hoverTimer = new javax.swing.Timer(600, new ActionListener()
    {
        public void actionPerformed(ActionEvent actionEvent)
        {
            if (AWTInputHandler.this.pickMatches(AWTInputHandler.this.hoverObjects))
            {
                AWTInputHandler.this.isHovering = true;
                AWTInputHandler.this.callSelectListeners(new SelectEvent(AWTInputHandler.this.wwd,
                    SelectEvent.HOVER, mousePoint, AWTInputHandler.this.hoverObjects));
                AWTInputHandler.this.hoverTimer.stop();
            }
        }
    });

这说明了InputHandler的作用就是为当前的Canvas添加事件监听,AWTInputHandler继承了各种监听器接口!

关于WorldWind中一个重要的事件——图形拖动,是如何实现的呢?

因为图形对象保存到图层,当我们获取到图形对象时,就得到了该图形的数据信息,要实现图形的移动,我们只需要根据新的坐标来修改图形的坐标数据即可,而不是通过修改上下文状态来实现变换的!

Polygon    
public void moveTo(Position position)
    {
        if (position == null)
        {
            String msg = Logging.getMessage("nullValue.PositionIsNull");
            Logging.logger().severe(msg);
            throw new IllegalArgumentException(msg);
        }

        if (!this.isOuterBoundaryValid())
            return;

        Position oldPosition = this.getReferencePosition();
        if (oldPosition == null)
            return;

        List<List<? extends Position>> newBoundaries = new ArrayList<List<? extends Position>>(this.boundaries.size());

        for (List<? extends Position> boundary : this.boundaries)
        {
            if (boundary == null || boundary.size() == 0)
                continue;

            List<Position> newList = Position.computeShiftedPositions(oldPosition, position, boundary);
            if (newList != null)
                newBoundaries.add(newList);
        }

        this.boundaries = newBoundaries;
        this.setReferencePosition(position);
        this.reset();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值