generalrules.html
来自「jsf、swing的官方指南」· HTML 代码 · 共 798 行 · 第 1/2 页
HTML
798 行
<blockquote>Every event-listener method has a single argument —an object that inherits from the<a class="APILink" target="_blank" href="http://java.sun.com/javase/6/docs/api/java/util/EventObject.html"><code>EventObject</code></a> class.Although the argument always descends from <code>EventObject</code>,its type is generally specified more precisely.For example, the argument for methods that handle mouse eventsis an instance of <code>MouseEvent</code>,where <code>MouseEvent</code> is an indirect subclassof <code>EventObject</code>.<p>The <code>EventObject</code> class defines one very useful method:<dl><dt> <strong><code>Object getSource()</code></strong><dd> Returns the object that fired the event.</dl><p>Note that the <code>getSource</code> method returns an <code>Object</code>.Event classes sometimes define methods similar to <code>getSource</code>,but that have more restricted return types.For example, the <code>ComponentEvent</code> classdefines a <code>getComponent</code>method that — just like <code>getSource</code> —returns the object that fired the event.The difference is that <code>getComponent</code>always returns a <code>Component</code>.Each how-to page for event listeners mentionswhether you should use <code>getSource</code>or another method to get the event source.<p>Often, an event class defines methods that return information about the event.For example, you can query a <code>MouseEvent</code> objectfor information about where the event occurred,how many clicks the user made, which modifier keys were pressed, and so on.<p></blockquote><a name="twokinds"><h3>Concepts: Low-Level Events and Semantic Events</h3></a><blockquote>Events can be divided into two groups:<em>low-level</em> events and <em>semantic</em> events.Low-level events represent window-system occurrencesor low-level input.Everything else is a semantic event.<p>Examples of low-level events include mouse and key events —both of which result directly from user input.Examples of semantic events include action and item events.A semantic event might be triggered by user input;for example, a button customarily fires an action event whenthe user clicks it, and a text field fires an action event whenthe user presses <i>Enter</i>. However, some semantic eventsaren't triggered by low-level events, at all. For example,a table-model event might be fired when a table model receivesnew data from a database.<p>Whenever possible, you should listen for semantic eventsrather than low-level events.That way, you can make your code as robust and portable as possible.For example, listening for action events on buttons,rather than mouse events,means that the button will react appropriatelywhen the user tries to activate the buttonusing a keyboard alternative or a look-and-feel-specific gesture.When dealing with a compound component such as a combo box,it's imperative that you stick to semantic events,since you have no reliable way of registeringlisteners on all the look-and-feel-specific componentsthat might be used to form the compound component.<p></blockquote><a name="eventAdapters"><h3>Event Adapters</h3></a><blockquote></p>Some listener interfaces contain more than one method.For example, the <code>MouseListener</code> interfacecontains five methods:<code>mousePressed</code>,<code>mouseReleased</code>,<code>mouseEntered</code>,<code>mouseExited</code>, and<code>mouseClicked</code>.Even if you care only about mouse clicks,if your class directly implements <code>MouseListener</code>, then you must implement all five <code>MouseListener</code> methods.Methods for those events you don't care about can have empty bodies.Here's an example:<blockquote><pre>//An example that implements a listener interface directly.public class MyClass implements MouseListener { ... someObject.addMouseListener(this); ... /* Empty method definition. */ public void mousePressed(MouseEvent e) { } /* Empty method definition. */ public void mouseReleased(MouseEvent e) { } /* Empty method definition. */ public void mouseEntered(MouseEvent e) { } /* Empty method definition. */ public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { <em>...//Event listener implementation goes here...</em> }}</pre></blockquote>The resulting collection of empty method bodies can make code harder to read and maintain. To help you avoid implementing empty method bodies,the API generally includes an <em>adapter</em> classfor each listener interface with more than one method.(The <a href="api.html">Listener API Table</a>lists all the listeners and their adapters.)For example, the <code>MouseAdapter</code> classimplements the <code>MouseListener</code> interface.An adapter class implements empty versionsof all its interface's methods.<p>To use an adapter, you create a subclass of it andoverride only the methods of interest, rather thandirectly implementing all methods of the listener interface.Here is an example of modifying the preceding codeto extend <code>MouseAdapter</code>. By extending<code>MouseAdapter</code>, it inherits empty definitionsof all five of the methods that <code>MouseListener</code>contains.<blockquote><pre>/* * An example of extending an adapter class instead of * directly implementing a listener interface. */public class MyClass extends MouseAdapter { ... someObject.addMouseListener(this); ... public void mouseClicked(MouseEvent e) { <em>...//Event listener implementation goes here...</em> }}</pre></blockquote></blockquote><h3><a name="innerClasses">Inner Classes and Anonymous Inner Classes</a></h3><blockquote><p>What if you want to use an adapter class, but don't wantyour public class to inherit from an adapter class?For example, suppose you write an applet,and you want your <code>Applet</code> subclassto contain some code to handle mouse events.Since the Java language doesn't permit multiple inheritance,your class can't extend both the <code>Applet</code>and <code>MouseAdapter</code> classes.A solution is to define an <em>inner class</em> —a class inside ofyour <code>Applet</code> subclass —that extends the <code>MouseAdapter</code> class.<p>Inner classes can also be useful for event listeners thatimplement one or more interfaces directly.<blockquote><pre>//An example of using an inner class.public class MyClass extends Applet { ... someObject.addMouseListener(new MyAdapter()); ... class MyAdapter extends MouseAdapter { public void mouseClicked(MouseEvent e) { <em>...//Event listener implementation goes here...</em> } }}</pre></blockquote><blockquote><hr><strong>Performance note:</strong> When considering whether to use an inner class,keep in mind that application startup time and memoryfootprint are typically directly proportional to the numberof classes you load. The more classes you create, thelonger your program takes to start up and the morememory it will take. As an application developer you haveto balance this with other design constraints you may have.We are not suggesting you turn your application intoa single monolithic class in hopes of cutting down startuptime and memory footprint — this would lead to unnecessary headaches and maintenance burdens.<hr></blockquote><p>You can create an inner class without specifying aname — this is known as an <em>anonymous inner class</em>.While it might look strange at first glance, anonymousinner classes can make your code easier to read becausethe class is defined where it is referenced. However,you need to weigh the convenience against possibleperformance implications of increasing the number of classes.<p>Here's an example of using an anonymous inner class:<blockquote><pre>//An example of using an anonymous inner class.public class MyClass extends Applet { ... someObject.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { <em>...//Event listener implementation goes here...</em> } }); ... }}</pre></blockquote><p><blockquote><hr><strong>Note:</strong> One drawback of anonymous inner classes is that they can't be seenby the long-term persistence mechanism.For more information see the API documentation for the<a class="APILink" target="_blank" href="http://java.sun.com/javase/6/docs/api/java/beans/package-summary.html#package_description">JavaBeans<sup><font size=-1>TM</font></sup> package</a> and the<a class="TutorialLink" target="_top" href="../../javabeans/persistence/">Bean Persistence</a> lesson in the<a class="TutorialLink" target="_top" href="../../javabeans/">JavaBeans</a> trail.<hr></blockquote><p>Inner classes work even if your event listenerneeds access to private instance variablesfrom the enclosing class.As long as you don't declare an inner class to be <code>static</code>,an inner class can refer to instance variables and methodsjust as if its code is in the containing class.To make a local variable available to an inner class,just save a copy of the variableas a <code>final</code> local variable.<p>To refer to the enclosing instance, you can use<code><em>EnclosingClass</em>.this</code>.For more information about inner classes, see <a class="TutorialLink" target="_top" href="../../java/javaOO/nested.html">Nested Classes</a>.</blockquote><h3><a name="eventHandlers">The EventHandler Class</a></h3><blockquote>Release 1.4 introduced an<a class="APILink" target="_blank" href="http://java.sun.com/javase/6/docs/api/java/beans/EventHandler.html"><code>EventHandler</code></a> class that supports dynamically generating simple, one-statement event listeners.Although <code>EventHandler</code> is only usefulfor a certain class of extremely simple event listeners,it's worth mentioning for two reasons. It is useful for:<ul><li>Making an event listener that persistence can see and yet doesn't clog up your own classes with event listener interfaces and methods.<li>Not adding to the number of classes defined in an application — this can help performance.</ul><p>Creating an <code>EventHandler</code> by hand is difficult.An <code>EventHandler</code> must be carefully constructed.If you make a mistake, you won't be notified at compile time —it will throw an obscure exception at runtime.For this reason, <code>EventHandler</code>s are best createdby a GUI builder. <code>EventHandler</code>sshould be carefully documented. Otherwise you run therisk of producing hard-to-read code.<p>An <code>EventHandler</code> can only be used in a situation whereyou need to set a property on an object (any <code>Object</code>will work) that has a <code>set</code> method for the property,as specified by the JavaBeans component architecture.The value that you set the property to has to be reachable usinga <code>get/is</code> method, from the event that the<code>EventHandler</code> handles.For example, all events have the event source (availablevia <code>getSource</code>). Ifthe event source is the only object you can get to from the event,then whatever value you're getting has to be reachable from theevent source.Also, you can't do any "if"s or any other kind of checking in theevent listener. It directly assigns a value to a property and nothing more.<p>The<a class="TutorialLink" target="_top" href="../components/colorchooser.html">ColorChooserDemo</a> example in <a class="TutorialLink" target="_top" href="../components/colorchooser.html">How to Use Color Choosers</a> can be modified to use an event listener to dynamically createa <code>ChangeListener</code>. The change listener class definesonly one method — <code>stateChanged</code>. If it had morethan one method and handled those methods differently,the method name would need to be specified as oneof the parameters. For example, a <code>MouseListener</code> would probably wantto treat mouse click and mouse down events differently.<p>Here is how <code>ColorChooserDemo</code> would look if it utilized an <code>EventHandler</code>:<blockquote><pre>import java.beans.EventHandler;...//Note that the class no longer implements the//ChangeListener interface.public class ColorChooserDemo extends JPanel { ... //The following replaces the line: //tcc.getSelectionModel().addChangeListener(this); tcc.getSelectionModel().addChangeListener( (ChangeListener)EventHandler.create( ChangeListener.class, //banner. banner, // setForeground( "foreground", // e.getSource().getSelectedColor()); "source.selectedColor")); ) ... //This method is no longer necessary. //public void stateChanged(ChangeEvent e) { // Color newColor = tcc.getColor(); // banner.setForeground(newColor); //} ...}</pre></blockquote> </blockquote> <div class=NavBit> <a target=_top href=intro.html>« Previous</a> • <a target=_top href=../TOC.html>Trail</a> • <a target=_top href=eventsandcomponents.html>Next »</a> </div> </div> <div id=Footer><div id=TagNotes> Problems with the examples? Try <a target="_blank" href=../../information/run-examples.html>Compiling and Running the Examples: FAQs</a>. <br> Complaints? Compliments? Suggestions? <a target="_blank" href="http://developer.sun.com/contact/tutorial_feedback.jsp">Give us your feedback</a>.<br><br> <a target="_blank" href="../../information/copyright.html">Copyright</a> 1995-2006 Sun Microsystems, Inc. All rights reserved. <span id=Download></span></div> </div> <div class=PrintHeaders> <b>Previous page:</b> Introduction to Event Listeners <br><b>Next page:</b> Listeners Supported by Swing Components </div> </body></html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?