最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

Java AWT: Delegation Event Model-1

工作和技术 crifan 1557浏览 0评论

Java AWT: Delegation Event Model



from jdk150 English Version

Last updated: February 3, 1997

Purpose

This document explains the rationale behind introducing a new event model into the AWT and describes specifically how the new model maps to the AWT API. This new model has also been adopted by the JavaBeans architecture for general event processing and is described at a high level in the JavaBeans Specification document.

The 1.0 Event Model

The model for event processing in version 1.0 of the AWT is based on inheritance. In order for a program to catch and process GUI events, it must subclass GUI components and override either action() or handleEvent() methods. Returning “true” from one of these methods consumes the event so it is not processed further; otherwise the event is propagated sequentially up the GUI hierarchy until either it is consumed or the root of the hierarchy is reached. The result of this model is that programs have essentially two choices for structuring their event-handling code:

  1. Each individual component can be subclassed to specifically handle its target events. The result of this is a plethora of classes.
  2. All events for an entire hierarchy (or subset thereof) can be handled by a particular container; the result is that the container’s overridden action() or handleEvent() method must contain a complex conditional statement in order to process the events.

While the above model works fine for small applets with simple interfaces, it does not scale well for larger java programs for the following reasons:

  • The requirement to subclass a component in order make any real use of its functionality is cumbersome to developers; subclassing should be reserved for circumstances where components are being extended in some functional or visual way.
  • The inheritance model does not lend itself well to maintaining a clean separation between the application model and the GUI because application code must be integrated directly into the subclassed components at some level.
  • Since ALL event types are filtered through the same methods, the logic to process the different event types (and possibly the event targets in approach #2) is complex and error-prone. It is not uncommon for programs to have perplexing bugs that are the result of returning an incorrect result (true or false) from the handleEvent() method. This becomes an even greater problem as new event types are added to the AWT; if the logic of existing handleEvent() methods isn’t set up to deal properly with unknown types, programs could potentially break in very unpredictable ways.
  • There is no filtering of events. Events are always delivered to components regardless of whether the components actually handle them or not. This is a general performance problem, particularly with high-frequency type events such as mouse moves.
  • For many components, the action() method passes a String parameter which is equivalent to either the label of the component (Button, MenuItem) or the item selected (List, Choice). For programs which use approach #2, this often leads to poor coding and unwieldy string-compare logic that doesn’t localize well.



The Delegation Model

Version 1.1 of the JavaTM platform introduced a new delegation-based event model in AWT in order to:

  • Resolve the problems mentioned previously
  • Provide a more robust framework to support more complex java programs.


Design Goals

The primary design goals of the new model in the AWT are the following:

  • Simple and easy to learn
  • Support a clean separation between application and GUI code
  • Facilitate the creation of robust event handling code which is less error-prone (strong compile-time checking)
  • Flexible enough to enable varied application models for event flow and propagation
  • For visual tool builders, enable run-time discovery of both events that a component generates as well as the events it may observe
  • Support backward binary compatibility with the old model

Note: These goals are described from the particular perspective of the AWT. Since this model has also been designed to accommodate the JavaBeans architecture, the design goals from the JavaBeans perspective are described in the “Events” section of the JavaBeans Specification and may vary slightly from these goals. Event types are encapsulated in a class hierarchy rooted at java.util.EventObject. An event is propagated from a “Source” object to a “Listener” object by invoking a method on the listener and passing in the instance of the event subclass which defines the event type generated.

A Listener is an object that implements a specific EventListener interface extended from the generic java.util.EventListener. An EventListener interface defines one or more methods which are to be invoked by the event source in response to each specific event type handled by the interface.

An Event Source is an object which originates or “fires” events. The source defines the set of events it emits by providing a set of set<EventType>Listener (for single-cast) and/or add<EventType>Listener (for mult-cast) methods which are used to register specific listeners for those events.

In an AWT program, the event source is typically a GUI component and the listener is commonly an “adapter” object which implements the appropriate listener (or set of listeners) in order for an application to control the flow/handling of events. The listener object could also be another AWT component which implements one or more listener interfaces for the purpose of hooking GUI objects up to each other.

Event Hierarchy

Events are no longer represented by a single Event class (like java.awt.Event) with numeric ids, but instead by a hierarchy of event classes. Each event class is defined by the data representing that event type or related group of events types.

Since a single event class may be used to represent more than one event type (i.e. MouseEvent represents mouse up, mouse down, mouse drag, mouse move, etc), some event classes may also contain an “id” (unique within that class) which maps to its specific event types.

The event classes contain no public fields; the data in the event is completely encapsulated by proper get<Attr>()/set<Attr>() methods (where set<Attr>() only exists for attributes on an event that could be modified by a listener).

Although these are the concrete set defined by the AWT, programs are free to define their own event types by subclassing either java.util.EventObject or one of the AWT event classes. Programs should choose event ID values which are greater than the constant:

<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/AWTEvent.html#RESERVED_ID_MAX">java.awt.AWTEvent.RESERVED_ID_MAX</a>
</code>

Low-level vs. Semantic Events

The AWT provides two conceptual types of events: low-level and semantic.

A low-level event is one which represents a low-level input or window-system occurrence on a visual component on the screen. The low-level event classes defined by the AWT are as follows:

<code> java.util.EventObject
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/AWTEvent.html">java.awt.AWTEvent</a> </code>
<code>  &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/ComponentEvent.html">java.awt.event.ComponentEvent</a> (component resized, moved, etc.)
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/FocusEvent.html">java.awt.event.FocusEvent</a> (component got focus, lost focus)
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/InputEvent.html">java.awt.event.InputEvent</a>
</code>
<code>   &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/KeyEvent.html">java.awt.event.KeyEvent</a> (component got key-press, key-release, etc.)
</code>
<code>   &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/MouseEvent.html">java.awt.event.MouseEvent</a> (component got mouse-down, mouse-move, etc.)
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/ContainerEvent.html">java.awt.event.ContainerEvent</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/WindowEvent.html">java.awt.event.WindowEvent</a>
</code>

Semantic events are defined at a higher-level to encapsulate the semantics of a user interface component’s model. The semantic event classes defined by the AWT are as follows:

<code> java.util.EventObject
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp; java.awt.AWTEvent
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/ActionEvent.html">java.awt.event.ActionEvent</a> ("do a command")
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/AdjustmentEvent.html">java.awt.event.AdjustmentEvent</a> ("value was adjusted")
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/ItemEvent.html">java.awt.event.ItemEvent</a> ("item state has changed")
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/TextEvent.html">java.awt.event.TextEvent</a> ("the value of the text object changed")
</code>

Note that these semantic events are not tied to specific screen-based component classes, but may apply across a set of components which implement a similar semantic model. For example, a Button object will fire an “action” event when it is pressed, a List object will fire an “action” event when an item is double-clicked, a MenuItem will fire an “action” event when it was selected from a menu, and a non-visual Timer object might fire an “action” when its timer goes off (the latter is a hypothetical case).

Event Listeners

An EventListener interface will typically have a separate method for each distinct event type the event class represents. So in essence, particular event semantics are defined by the combination of an Event class paired with a particular method in an EventListener. For example, the FocusListener interface defines two methods, focusGained() and focusLost(), one for each event type that FocusEvent class represents.

The API attempts to define a balance between providing a reasonable granularity of Listener interface types and not providing a separate interface for every single event type.

The low-level listener interfaces defined by the AWT are as follows:

<code> java.util.EventListener
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/ComponentListener.html">java.awt.event.ComponentListener</a>
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/ContainerListener.html">java.awt.event.ContainerListener</a>
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/FocusListener.html">java.awt.event.FocusListener </a>
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/KeyListener.html">java.awt.event.KeyListener</a>
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/MouseListener.html">java.awt.event.MouseListener </a>
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/MouseMotionListener.html">java.awt.event.MouseMotionListener </a>
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/WindowListener.html">java.awt.event.WindowListener</a>
</code>

The semantic listener interfaces defined by the AWT are as follows:

<code> java.util.EventListener
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/ActionListener.html">java.awt.event.ActionListener</a>
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/AdjustmentListener.html">java.awt.event.AdjustmentListener</a>
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/ItemListener.html">java.awt.event.ItemListener </a>
</code>
<code> &nbsp;&nbsp;&nbsp;&nbsp;<a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/event/TextListener.html">java.awt.event.TextListener </a>
</code>

Event Sources

Because the events fired by an event source are defined by particular methods on that object, it is completely clear from the API documentation (as well as by using run-time introspection techniques) exactly which events an object supports.

All AWT event sources support a multicast model for listeners. This means that multiple listeners can be added and removed from a single source. The API makes no guarantees about the order in which the events are delivered to a set of registered listeners for a given event on a given source. Additionally, any event which allows its properties to be modified (via setXXX() methods) will be explicitly copied such that each listener receives a replica of the original event. If the order in which events are delivered to listeners is a factor for your program, you should chain the listeners off a single listener which is registered on the source (the fact that the event data is encapsulated in a single object makes propagating the event extremely simple).

Event delivery is synchronous (as with 1.0’s handleEvent()), however programs should not make the assumption that the delivery of an event to a set of listeners will occur on the same thread.

Once again, a distinction is drawn between low-level and semantic events. For low-level events, the source will be one of the visual component classes (Button, Scrollbar, etc) since the event is tightly bound to the actual component on the screen. The low-level listeners are defined on the following components:

  • java.awt.Component
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Component.html#addComponentListener(java.awt.event.ComponentListener)">addComponentListener(ComponentListener l)</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Component.html#addFocusListener(java.awt.event.FocusListener)">addFocusListener(FocusListener l)</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Component.html#addKeyListener(java.awt.event.KeyListener)">addKeyListener(KeyListener l)</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Component.html#addMouseListener(java.awt.event.MouseListener)">addMouseListener(MouseListener l)</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Component.html#addMouseMotionListener(java.awt.event.MouseMotionListener)">addMouseMotionListener(MouseMotionListener l)</a>
</code>
  • java.awt.Container
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Container.html#addContainerListener(java.awt.event.ContainerListener)">addContainerListener(ContainerListener l)</a>
</code>
  • java.awt.Dialog
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Dialog.html#addWindowListener(java.awt.event.WindowListener)">addWindowListener(WindowListener l)</a>
</code>
  • java.awt.Frame
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Frame.html#addWindowListener(java.awt.event.WindowListener)">addWindowListener(WindowListener l)</a>
</code>

For semantic events, the source is typically a higher-level interface representing the semantic model (and this higher-level interface is commonly `implemented’ by components using the model). Following are the semantic listeners defined for AWT components:

  • java.awt.Button
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Button.html#addActionListener(java.awt.event.ActionListener)">addActionListener(ActionListener l)</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Choice.html#addItemListener(java.awt.event.ItemListener)">addItemListener(ItemListener l)</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Checkbox.html#addItemListener(java.awt.event.ItemListener)">addItemListener(ItemListener l)</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/CheckboxMenuItem.html#addItemListener(java.awt.event.ItemListener)">addItemListener(ItemListener l)</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/List.html#addActionListener(java.awt.event.ActionListener)">addActionListener(ActionListener l)</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/List.html#addItemListener(java.awt.event.ItemListener)">addItemListener(ItemListener l)</a>
</code>
  • java.awt.MenuItem
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/MenuItem.html#addActionListener(java.awt.event.ActionListener)">addActionListener(ActionListener l)</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/Scrollbar.html#addAdjustmentListener(java.awt.event.AdjustmentListener)">addAdjustmentListener(AdjustmentListener l)</a>
</code>
  • java.awt.TextArea
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/TextComponent.html#addTextListener(java.awt.event.TextListener)">addTextListener(TextListener l)</a>
</code>
  • java.awt.TextField
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/TextField.html#addActionListener(java.awt.event.ActionListener)">addActionListener(ActionListener l)</a>
</code>
<code> <a href="mk:@MSITStore:C: Documents%20and%20Settings crifan_li 桌面 jdk150%20English%20Version.chm::/jdk150/api/java/awt/TextComponent.html#addTextListener(java.awt.event.TextListener)">addTextListener(TextListener l)</a>
</code>

Delegation Model Overview

Issues with the 1.0 Event Model

转载请注明:在路上 » Java AWT: Delegation Event Model-1

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
79 queries in 0.167 seconds, using 22.17MB memory