事件处理机制:当事件发生后,会创建一个事件对象,然后,会在注册的事件监听列表中寻找能够处理该事件的监听器回调方法,处理完毕后事件被销毁,如果整个监听列表中都没有方法对其进行处理,最终也被销毁!
其整个处理过程是这样的,事件源可以注册事件监听器对象,并可以向事件监听器对象发送事件对象.事件发生后,事件源将事件对象发给已经注册的所有事件监听器. 监听器对象随后会根据事件对象内的相应方法响应这个事件。
应该说,当事件发生时,系统会创建事件对象,这个事件对象包括了事件的所有信息,即事件源,具体事件类型等;这样一来,事件对象就会被传到事件源,由事件源注册的事件监听进行处理!
事件对象应该是由系统(虚拟机)创建的,而不是应用程序,所以最初产生的事件对象类型都是鼠标键盘的标准事件对象,但是,在传给事件源进行处理的时候,监听器中的回调方法的事件参数可能是自定义的事件,但继承自EventObject,程序会不会尝试根据标准的事件对象来创建自定的事件对象,然后传入回调方法中进行处理呢?
如果不行,那么自定义事件作为事件处理方法的参数还有意义吗?
通过研究AWTInputHandler证明这一想法是正确的,jvm会创建ActionEvent,MouseEvent,KeyEvent对象,所以,我们将在这些监听中创建自定义的事件对象,调用相应的监听器进行处理!
对于系统怎么知道事件发生了这个问题,个人猜测是系统主动对鼠标,键盘等的状态进行判断的结果,说白了可能利用了死循环在进行判断,根据判断的结果生成事件对象,然后调用事件源监听器列表进行处理!
不过Window的消息处理机制否定了这一说法!
事件是窗口界面编程才有的概念,是用于实现用户交互,最终事件对象会发往窗体,而监听也是注册给窗体或控件的,这样,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();
}