Showing the changes to java/pkg/java/awt/doc-files (36 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,189 @@ | |||
| 1 | <!-- | ||
| 2 | Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | |||
| 5 | This code is free software; you can redistribute it and/or modify it | ||
| 6 | under the terms of the GNU General Public License version 2 only, as | ||
| 7 | published by the Free Software Foundation. Oracle designates this | ||
| 8 | particular file as subject to the "Classpath" exception as provided | ||
| 9 | by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | |||
| 11 | This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | accompanied this code). | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License version | ||
| 18 | 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | |||
| 21 | Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | or visit www.oracle.com if you need additional information or have any | ||
| 23 | questions. | ||
| 24 | --> | ||
| 25 | |||
| 26 | <html> | ||
| 27 | <body bgcolor=white> | ||
| 28 | |||
| 29 | <h1 align=center>AWT Threading Issues</h1> | ||
| 30 | |||
| 31 | <a name="ListenersThreads"></a> | ||
| 32 | <h2>Listeners and threads</h2> | ||
| 33 | |||
| 34 | Unless otherwise noted all AWT listeners are notified on the event | ||
| 35 | dispatch thread. It is safe to remove/add listeners from any thread | ||
| 36 | during dispatching, but the changes only effect subsequent notification. | ||
| 37 | <br>For example, if a key listeners is added from another key listener, the | ||
| 38 | newly added listener is only notified on subsequent key events. | ||
| 39 | |||
| 40 | <a name="Autoshutdown"></a> | ||
| 41 | <h2>Auto-shutdown</h2> | ||
| 42 | |||
| 43 | According to | ||
| 44 | <cite>The Java™ Virtual Machine Specification</cite>, | ||
| 45 | sections 2.17.9 and 2.19, | ||
| 46 | the Java virtual machine (JVM) initially starts up with a single non-daemon | ||
| 47 | thread, which typically calls the <code>main</code> method of some class. | ||
| 48 | The virtual machine terminates all its activity and exits when | ||
| 49 | one of two things happens: | ||
| 50 | <ul> | ||
| 51 | <li> All the threads that are not daemon threads terminate. | ||
| 52 | <li> Some thread invokes the <code>exit</code> method of class | ||
| 53 | <code>Runtime</code> or class <code>System</code>, and the exit | ||
| 54 | operation is permitted by the security manager. | ||
| 55 | </ul> | ||
| 56 | <p> | ||
| 57 | This implies that if an application doesn't start any threads itself, | ||
| 58 | the JVM will exit as soon as <code>main</code> terminates. | ||
| 59 | This is not the case, however, for a simple application | ||
| 60 | that creates and displays a <code>java.awt.Frame</code>: | ||
| 61 | <pre> | ||
| 62 | public static void main(String[] args) { | ||
| 63 | Frame frame = new Frame(); | ||
| 64 | frame.setVisible(true); | ||
| 65 | } | ||
| 66 | </pre> | ||
| 67 | The reason is that AWT encapsulates asynchronous event dispatch | ||
| 68 | machinery to process events AWT or Swing components can fire. The | ||
| 69 | exact behavior of this machinery is implementation-dependent. In | ||
| 70 | particular, it can start non-daemon helper threads for its internal | ||
| 71 | purposes. In fact, these are the threads that prevent the example | ||
| 72 | above from exiting. The only restrictions imposed on the behavior of | ||
| 73 | this machinery are as follows: | ||
| 74 | <ul> | ||
| 75 | <li> <a href="../EventQueue.html#isDispatchThread()"><code>EventQueue.isDispatchThread</code></a> | ||
| 76 | returns <code>true</code> if and only if the calling thread is the | ||
| 77 | event dispatch thread started by the machinery; | ||
| 78 | <li> <code>AWTEvents</code> which were actually enqueued to a | ||
| 79 | particular <code>EventQueue</code> (note that events being | ||
| 80 | posted to the <code>EventQueue</code> can be coalesced) are | ||
| 81 | dispatched: | ||
| 82 | <ul> | ||
| 83 | <li> Sequentially. | ||
| 84 | <dd> That is, it is not permitted that several events from | ||
| 85 | this queue are dispatched simultaneously. | ||
| 86 | <li> In the same order as they are enqueued. | ||
| 87 | <dd> That is, if <code>AWTEvent</code> A is enqueued | ||
| 88 | to the <code>EventQueue</code> before | ||
| 89 | <code>AWTEvent</code> B then event B will not be | ||
| 90 | dispatched before event A. | ||
| 91 | </ul> | ||
| 92 | <li> There is at least one alive non-daemon thread while there is at | ||
| 93 | least one displayable AWT or Swing component within the | ||
| 94 | application (see | ||
| 95 | <a href="../Component.html#isDisplayable()"><code>Component.isDisplayable</code></a>). | ||
| 96 | </ul> | ||
| 97 | The implications of the third restriction are as follows: | ||
| 98 | <ul> | ||
| 99 | <li> The JVM will exit if some thread invokes the <code>exit</code> | ||
| 100 | method of class <code>Runtime</code> or class <code>System</code> | ||
| 101 | regardless of the presence of displayable components; | ||
| 102 | <li> Even if the application terminates all non-daemon threads it | ||
| 103 | started, the JVM will not exit while there is at least one | ||
| 104 | displayable component. | ||
| 105 | </ul> | ||
| 106 | It depends on the implementation if and when the non-daemon helper | ||
| 107 | threads are terminated once all components are made undisplayable. | ||
| 108 | The implementation-specific details are given below. | ||
| 109 | |||
| 110 | <h3> | ||
| 111 | Implementation-dependent behavior. | ||
| 112 | </h3> | ||
| 113 | |||
| 114 | Prior to 1.4, the helper threads were never terminated. | ||
| 115 | <p> | ||
| 116 | Starting with 1.4, the behavior has changed as a result of the fix for | ||
| 117 | <a href="http://bugs.sun.com/view_bug.do?bug_id=4030718"> | ||
| 118 | 4030718</a>. With the current implementation, AWT terminates all its | ||
| 119 | helper threads allowing the application to exit cleanly when the | ||
| 120 | following three conditions are true: | ||
| 121 | <ul> | ||
| 122 | <li> There are no displayable AWT or Swing components. | ||
| 123 | <li> There are no native events in the native event queue. | ||
| 124 | <li> There are no AWT events in java EventQueues. | ||
| 125 | </ul> | ||
| 126 | Therefore, a stand-alone AWT application that wishes to exit | ||
| 127 | cleanly without calling <code>System.exit</code> must: | ||
| 128 | <ul> | ||
| 129 | <li> Make sure that all AWT or Swing components are made | ||
| 130 | undisplayable when the application finishes. This can be done | ||
| 131 | by calling | ||
| 132 | <a href="../Window.html#dispose()"><code>Window.dispose</code></a> | ||
| 133 | on all top-level <code>Windows</code>. See | ||
| 134 | <a href="../Frame.html#getFrames()"><code>Frame.getFrames</code></a>. | ||
| 135 | <li> Make sure that no method of AWT event listeners registered by | ||
| 136 | the application with any AWT or Swing component can run into an | ||
| 137 | infinite loop or hang indefinitely. For example, an AWT listener | ||
| 138 | method triggered by some AWT event can post a new AWT event of | ||
| 139 | the same type to the <code>EventQueue</code>. | ||
| 140 | The argument is that methods | ||
| 141 | of AWT event listeners are typically executed on helper | ||
| 142 | threads. | ||
| 143 | </ul> | ||
| 144 | Note, that while an application following these recommendations will | ||
| 145 | exit cleanly under normal conditions, it is not guaranteed that it | ||
| 146 | will exit cleanly in all cases. Two examples: | ||
| 147 | <ul> | ||
| 148 | <li> Other packages can create displayable components for internal | ||
| 149 | needs and never make them undisplayable. See | ||
| 150 | <a href="http://bugs.sun.com/view_bug.do?bug_id=4515058"> | ||
| 151 | 4515058</a>, | ||
| 152 | <a href="http://bugs.sun.com/view_bug.do?bug_id=4671025"> | ||
| 153 | 4671025</a>, and | ||
| 154 | <a href="http://bugs.sun.com/view_bug.do?bug_id=4465537"> | ||
| 155 | 4465537</a>. | ||
| 156 | <li> Both Microsoft Windows and X11 allow an application to send native | ||
| 157 | events to windows that belong to another application. With this | ||
| 158 | feature it is possible to write a malicious program that will | ||
| 159 | continuously send events to all available windows preventing | ||
| 160 | any AWT application from exiting cleanly. | ||
| 161 | </ul> | ||
| 162 | On the other hand, if you require the JVM to continue running even after | ||
| 163 | the application has made all components undisplayable you should start a | ||
| 164 | non-daemon thread that blocks forever. | ||
| 165 | |||
| 166 | <pre> | ||
| 167 | <...> | ||
| 168 | Runnable r = new Runnable() { | ||
| 169 | public void run() { | ||
| 170 | Object o = new Object(); | ||
| 171 | try { | ||
| 172 | synchronized (o) { | ||
| 173 | o.wait(); | ||
| 174 | } | ||
| 175 | } catch (InterruptedException ie) { | ||
| 176 | } | ||
| 177 | } | ||
| 178 | }; | ||
| 179 | Thread t = new Thread(r); | ||
| 180 | t.setDaemon(false); | ||
| 181 | t.start(); | ||
| 182 | <...> | ||
| 183 | </pre> | ||
| 184 | |||
| 185 | <cite>The Java™ Virtual Machine Specification</cite> | ||
| 186 | guarantees | ||
| 187 | that the JVM doesn't exit until this thread terminates. | ||
| 188 | </body> | ||
| 189 | </html> | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,273 @@ | |||
| 1 | <!-- | ||
| 2 | Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | |||
| 5 | This code is free software; you can redistribute it and/or modify it | ||
| 6 | under the terms of the GNU General Public License version 2 only, as | ||
| 7 | published by the Free Software Foundation. Oracle designates this | ||
| 8 | particular file as subject to the "Classpath" exception as provided | ||
| 9 | by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | |||
| 11 | This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | accompanied this code). | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License version | ||
| 18 | 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | |||
| 21 | Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | or visit www.oracle.com if you need additional information or have any | ||
| 23 | questions. | ||
| 24 | --> | ||
| 25 | |||
| 26 | <html> | ||
| 27 | <body bgcolor=white> | ||
| 28 | |||
| 29 | <h1 align=center>AWT Desktop Properties</h1> | ||
| 30 | |||
| 31 | The following refers to standard AWT desktop properties that | ||
| 32 | may be obtained via the | ||
| 33 | <a href="../Toolkit.html#getDesktopProperty(java.lang.String)"> | ||
| 34 | <code>Toolkit.getDesktopProperty</code></a> method. | ||
| 35 | <p> | ||
| 36 | Each desktop property is named by a unique string, which | ||
| 37 | is the "name" of that property. | ||
| 38 | <p> | ||
| 39 | Desktop properties supported by the AWT but not documented | ||
| 40 | elsewhere - typically because there is no suitable | ||
| 41 | method or class - are documented here. | ||
| 42 | <p> | ||
| 43 | Desktop properties documented elsewhere are those which are | ||
| 44 | tightly coupled with a method or class which documents them. | ||
| 45 | <p> | ||
| 46 | Since desktop properties abstract an underlying platform | ||
| 47 | setting, they may not be available in environments that do | ||
| 48 | not support them. In the event that a desktop property is | ||
| 49 | unavailable for any reason, the implementation will return | ||
| 50 | <code>null</code>. | ||
| 51 | <p> | ||
| 52 | The following table summarizes the desktop properties documented | ||
| 53 | here, and their value types. | ||
| 54 | <p> | ||
| 55 | <table align="center" border="0" cellspacing="0" cellpadding="2" width="%95 | ||
| 56 | summary="Standard AWT Desktop Properties"> | ||
| 57 | <tr bgcolor="#ccccff"> | ||
| 58 | <th valign="TOP" align="LEFT">Property Name</th> | ||
| 59 | <th valign="TOP" align="LEFT">Value Type</th> | ||
| 60 | <th valign="TOP" align="LEFT">Summary Description</th> | ||
| 61 | </tr> | ||
| 62 | <tr> | ||
| 63 | <td valign="TOP"><A href=#awt.font.desktophints>awt.font.desktophints</A</td> | ||
| 64 | <td valign="TOP"><a href="../../util/Map.html">java.util.Map<a/></td> | ||
| 65 | <td valign="TOP">Font smoothing (text antialiasing) settings.<a/></td> | ||
| 66 | </tr> | ||
| 67 | <tr> | ||
| 68 | <td valign="TOP"><A href=#"sun.awt.enableExtraMouseButtons">sun.awt.enableExtraMouseButtons</A</td> | ||
| 69 | <td valign="TOP"><a href="../../lang/Boolean.html">java.lang.Boolean<a/></td> | ||
| 70 | <td valign="TOP">Controls if mouse events from extra buttons are to be generated or not<a/></td> | ||
| 71 | </tr> | ||
| 72 | </table> | ||
| 73 | <p> | ||
| 74 | <h2>Desktop Font Rendering Hints</h2> | ||
| 75 | <b>Desktop Property: <A name="awt.font.desktophints">"awt.font.desktophints"</A></b> | ||
| 76 | <p> | ||
| 77 | Modern desktops support various forms of text antialiasing (font smoothing). | ||
| 78 | <p> | ||
| 79 | These are applied by platform-specific heavyweight components. | ||
| 80 | However an application may want to render text using the same text | ||
| 81 | antialiasing on a drawing surface or lightweight (non-platform) component using | ||
| 82 | <a href="../Graphics2D.html"> <code>Graphics2D</code></a> methods. | ||
| 83 | This is particularly important when creating | ||
| 84 | <a href="../../../javax/swing/JComponent.html"> Swing components</a> which | ||
| 85 | are required to appear consistent with native desktop components or other | ||
| 86 | Swing components. | ||
| 87 | <p> | ||
| 88 | <h3>Basic Usage</h3> | ||
| 89 | The standard desktop property named | ||
| 90 | <b>"awt.font.desktophints"</b> | ||
| 91 | can be used to obtain the rendering hints that best match the desktop settings. | ||
| 92 | |||
| 93 | The return value is a | ||
| 94 | <a href="../../util/Map.html"> Map<a/> of | ||
| 95 | <a href="../RenderingHints.html"> <code>RenderingHints</code></a> which | ||
| 96 | can be directly applied to a <code>Graphics2D</code>. | ||
| 97 | <p> | ||
| 98 | It is a <code>Map</code> as more than one hint may be needed. | ||
| 99 | If non-null this can be directly applied to the <code>Graphics2D</code>. | ||
| 100 | <pre><code> | ||
| 101 | Toolkit tk = Toolkit.getDefaultToolkit(); | ||
| 102 | Map map = (Map)(tk.getDesktopProperty("awt.font.desktophints")); | ||
| 103 | if (map != null) { | ||
| 104 | graphics2D.addRenderingHints(map); | ||
| 105 | } | ||
| 106 | </code></pre> | ||
| 107 | <h3>Advanced Usage Tips</h3> | ||
| 108 | <p> | ||
| 109 | <h4>Listening for changes</h4> | ||
| 110 | <p> | ||
| 111 | An application can listen for changes in the property | ||
| 112 | using a <a href="../../beans/PropertyChangeListener.html"> | ||
| 113 | <code>PropertyChangeListener</code></a> : | ||
| 114 | <pre><code> | ||
| 115 | tk.addPropertyChangeListener("awt.font.desktophints", pcl); | ||
| 116 | </code></pre> | ||
| 117 | Listening for changes is recommended as users can, on rare occasions, | ||
| 118 | reconfigure a desktop environment whilst applications are running | ||
| 119 | in a way that may affect the selection of these hints, and furthermore | ||
| 120 | many desktop environments support dynamic reconfiguration of these | ||
| 121 | running applications to conform to the new settings. | ||
| 122 | <p> | ||
| 123 | There is no direct way to discover if dynamic reconfiguration | ||
| 124 | is expected of running applications but the default assumption | ||
| 125 | should be that it is expected, since most modern desktop environments | ||
| 126 | do provide this capability. | ||
| 127 | <h4>Text Measurement</h4> | ||
| 128 | <p> | ||
| 129 | Text always needs to be measured using the same | ||
| 130 | <a href="../font/FontRenderContext.html"> <code>FontRenderContext</code></a> | ||
| 131 | as used for rendering. The text anti-aliasing hint is a component of | ||
| 132 | the <code>FontRenderContext</code>. | ||
| 133 | A <a href="../FontMetrics.html"> <code>FontMetrics</code></a> | ||
| 134 | obtained from the <code>Graphics</code> object on which the hint | ||
| 135 | has been set will measure text appropriately. | ||
| 136 | This is not a unique requirement for clients that specify this hint | ||
| 137 | directly, since the value of the <code>FontRenderContext</code> should | ||
| 138 | never be assumed, so is discussed here principally as a reminder. | ||
| 139 | <h4>Saving and restoring Graphics State</h4> | ||
| 140 | <p> | ||
| 141 | Sometimes an application may need to apply these hints on a shared | ||
| 142 | Graphics only temporarily, restoring the previous values after they | ||
| 143 | have been applied to text rendering operations. | ||
| 144 | The following sample code shows one way to do this. | ||
| 145 | <pre><code> | ||
| 146 | /** | ||
| 147 | * Get rendering hints from a Graphics instance. | ||
| 148 | * "hintsToSave" is a Map of RenderingHint key-values. | ||
| 149 | * For each hint key present in that map, the value of that | ||
| 150 | * hint is obtained from the Graphics and stored as the value | ||
| 151 | * for the key in savedHints. | ||
| 152 | */ | ||
| 153 | RenderingHints getRenderingHints(Graphics2D g2d, | ||
| 154 | RenderingHints hintsToSave, | ||
| 155 | RenderingHints savedHints) { | ||
| 156 | if (savedHints == null) { | ||
| 157 | savedHints = new RenderingHints(null); | ||
| 158 | } else { | ||
| 159 | savedHints.clear(); | ||
| 160 | } | ||
| 161 | if (hintsToSave.size() == 0) { | ||
| 162 | return savedHints; | ||
| 163 | } | ||
| 164 | /* RenderingHints.keySet() returns Set<Object> */ | ||
| 165 | for (Object o : hintsToSave.keySet()) { | ||
| 166 | RenderingHints.Key key = (RenderingHints.Key)o; | ||
| 167 | Object value = g2d.getRenderingHint(key); | ||
| 168 | savedHints.put(key, value); | ||
| 169 | } | ||
| 170 | return savedHints; | ||
| 171 | } | ||
| 172 | |||
| 173 | |||
| 174 | Toolkit tk = Toolkit.getDefaultToolkit(); | ||
| 175 | Map map = (Map)(tk.getDesktopProperty("awt.font.desktophints")); | ||
| 176 | Map oldHints; | ||
| 177 | if (map != null) { | ||
| 178 | oldHints = getRenderingHints(graphic2D, map, null); | ||
| 179 | graphics2D.addRenderingHints(map); | ||
| 180 | .. | ||
| 181 | graphics2D.addRenderingHints(oldHints); | ||
| 182 | } | ||
| 183 | </code></pre> | ||
| 184 | |||
| 185 | <h3>Details</h3> | ||
| 186 | <ul> | ||
| 187 | <li>The return value will always be null or a <code>Map</code> | ||
| 188 | <p> | ||
| 189 | <li>If the return value is null, then no desktop properties are available, | ||
| 190 | and dynamic updates will not be available. This is a typical behaviour if | ||
| 191 | the JDK does not recognise the desktop environment, or it is one which | ||
| 192 | has no such settings. The <b>Headless</b> toolkit is one such example. | ||
| 193 | Therefore it is important to test against null before using the map. | ||
| 194 | <p> | ||
| 195 | <li>If non-null the value will be a <code>Map</code> of | ||
| 196 | <code>RenderingHints</code> such that every key is an instance of | ||
| 197 | <code>RenderingHints.Key</code> and the value is a legal value for that key. | ||
| 198 | <p> | ||
| 199 | <li>The map may contain the default value for a hint. This is | ||
| 200 | needed in the event there is a previously a non-default value for the hint | ||
| 201 | set on the <code>Graphics2D</code>. If the map did not contain | ||
| 202 | the default value, then <code>addRenderingHints(Map)</code> would leave | ||
| 203 | the previous hint which may not correspond to the desktop setting. | ||
| 204 | <p> | ||
| 205 | An application can use <code>setRenderingHints(Map)</code> to reinitialise | ||
| 206 | all hints, but this would affect unrelated hints too. | ||
| 207 | <p> | ||
| 208 | <li>A multi-screen desktop may support per-screen device settings in which | ||
| 209 | case the returned value is for the default screen of the desktop. | ||
| 210 | An application may want to use the settings for the screen on | ||
| 211 | which they will be applied. | ||
| 212 | The per-screen device hints may be obtained by per-device property names | ||
| 213 | which are constructed as the String concatenation | ||
| 214 | <pre><code> | ||
| 215 | "awt.font.desktophints" + "." + GraphicsDevice.getIDstring(); | ||
| 216 | </code></pre> | ||
| 217 | <p> | ||
| 218 | An application can also listen for changes on these properties. | ||
| 219 | <p> | ||
| 220 | However this is an extremely unlikely configuration, so to help | ||
| 221 | ease of development, if only a single, desktop-wide setting is supported, | ||
| 222 | then querying each of these per-device settings will return null. | ||
| 223 | So to determine if there are per-device settings it is sufficient to | ||
| 224 | determine that there is a non-null return for any screen device using | ||
| 225 | the per-device property name. | ||
| 226 | </ul> | ||
| 227 | <h2>Mouse Functionality</h2> | ||
| 228 | <b>Desktop Property: <A name="sun.awt.enableExtraMouseButtons">"sun.awt.enableExtraMouseButtons"</A></b> | ||
| 229 | <p> | ||
| 230 | This property determines if events from extra mouse buttons (if they are exist and are | ||
| 231 | enabled by the underlying operating system) are allowed to be processed and posted into | ||
| 232 | {@code EventQueue}. | ||
| 233 | <br> | ||
| 234 | The value could be changed by passing "sun.awt.enableExtraMouseButtons" | ||
| 235 | property value into java before application starts. This could be done with the following command: | ||
| 236 | <pre> | ||
| 237 | java -Dsun.awt.enableExtraMouseButtons=false Application | ||
| 238 | </pre> | ||
| 239 | Once set on application startup, it is impossible to change this value after. | ||
| 240 | <br> | ||
| 241 | Current value could also be queried using getDesktopProperty("sun.awt.enableExtraMouseButtons") | ||
| 242 | method. | ||
| 243 | <br> | ||
| 244 | If the property is set to {@code true} then | ||
| 245 | <ul> | ||
| 246 | <li> it is still legal to create {@code MouseEvent} objects with | ||
| 247 | standard buttons and, if the mouse has more | ||
| 248 | then three buttons, it is also legal to use buttons from the range started | ||
| 249 | from 0 up to {@link java.awt.MouseInfo#getNumberOfButtons() getNumberOfButtons()}. | ||
| 250 | |||
| 251 | <li> it is legal to use standard button masks when using {@code Robot.mousePress()} | ||
| 252 | and {@code Robot.mouseRelease()} methods and, if the mouse has more then three buttons, | ||
| 253 | it is also legal to use masks for existing extended mouse buttons. | ||
| 254 | That way, if there are more then three buttons on the mouse then it is allowed to | ||
| 255 | use button masks corresponding to the buttons | ||
| 256 | in the range from 1 up to {@link java.awt.MouseInfo#getNumberOfButtons() getNumberOfButtons()} | ||
| 257 | </ul> | ||
| 258 | <br> | ||
| 259 | If the property is set to {@code false} then | ||
| 260 | <ul> | ||
| 261 | <li> it is legal to create {@code MouseEvent} objects with standard buttons | ||
| 262 | only: {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2} and | ||
| 263 | {@code BUTTON3} | ||
| 264 | <li> it is legal to use standard button masks only: | ||
| 265 | {@code InputEvent.BUTTON1_DOWN_MASK}, {@code InputEvent.BUTTON2_DOWN_MASK}, | ||
| 266 | {@code InputEvent.BUTTON3_DOWN_MASK} | ||
| 267 | </ul> | ||
| 268 | |||
| 269 | This property should be used when there is no need in listening mouse events fired as a result of | ||
| 270 | activity with extra mouse button. | ||
| 271 | By default this property is set to {@code true}. | ||
| 272 | </body> | ||
| 273 | </html> | ||
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,1367 @@ | |||
| 1 | <!-- | ||
| 2 | Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | |||
| 5 | This code is free software; you can redistribute it and/or modify it | ||
| 6 | under the terms of the GNU General Public License version 2 only, as | ||
| 7 | published by the Free Software Foundation. Oracle designates this | ||
| 8 | particular file as subject to the "Classpath" exception as provided | ||
| 9 | by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | |||
| 11 | This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | accompanied this code). | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License version | ||
| 18 | 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | |||
| 21 | Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | or visit www.oracle.com if you need additional information or have any | ||
| 23 | questions. | ||
| 24 | --> | ||
| 25 | |||
| 26 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> | ||
| 27 | |||
| 28 | <html> | ||
| 29 | <head> | ||
| 30 | <title align=center>The AWT Focus Subsystem</title> | ||
| 31 | </head> | ||
| 32 | |||
| 33 | <body bgcolor="white"> | ||
| 34 | <h1 align=center>The AWT Focus Subsystem</h1> | ||
| 35 | |||
| 36 | <p> | ||
| 37 | Prior to Java 2 Standard Edition, JDK 1.4, the AWT focus subsystem | ||
| 38 | was inadequate. It suffered from major design and API problems, | ||
| 39 | as well as over a hundred open bugs. Many of these bugs were caused by | ||
| 40 | platform inconsistencies, or incompatibilities between the native | ||
| 41 | focus system for heavyweights and the Java focus system for | ||
| 42 | lightweights. | ||
| 43 | <p> | ||
| 44 | The single worst problem with the AWT focus implementation was the | ||
| 45 | inability to query for the currently focused Component. Not only was | ||
| 46 | there no API for such a query, but also, because of an insufficient | ||
| 47 | architecture, such information was not even maintained by the code. | ||
| 48 | <p> | ||
| 49 | Almost as bad was the inability of lightweight children of a Window | ||
| 50 | (not a Frame or a Dialog) to receive keyboard input. This problem | ||
| 51 | existed because Windows never received <code>WINDOW_ACTIVATED</code> | ||
| 52 | events and thus could never be activated, and only active Windows | ||
| 53 | could contain focused Components. | ||
| 54 | <p> | ||
| 55 | In addition, many developers noted that the APIs for FocusEvent and | ||
| 56 | WindowEvent were insufficient because they did not provide a way for | ||
| 57 | determining the "opposite" Component involved in the focus or | ||
| 58 | activation change. For example, when a Component received a FOCUS_LOST | ||
| 59 | event, it had no way of knowing which Component was gaining | ||
| 60 | focus. Since Microsoft Windows provides this functionality for free, | ||
| 61 | developers migrating from Microsoft Windows C/C++ or Visual Basic to | ||
| 62 | Java had been frustrated by the omission. | ||
| 63 | <p> | ||
| 64 | To address these and other deficiencies, we have designed a new focus | ||
| 65 | model for the AWT in JDK 1.4. The primary design changes were the | ||
| 66 | construction of a new centralized KeyboardFocusManager class, and a | ||
| 67 | lightweight focus architecture. The amount of focus-related, | ||
| 68 | platform-dependent code has been minimized and replaced by fully | ||
| 69 | pluggable and extensible public APIs in the AWT. While we have | ||
| 70 | attempted to remain backward compatible with the existing | ||
| 71 | implementation, we were forced to make minor incompatible changes in | ||
| 72 | order to reach an elegant and workable conclusion. We anticipate that | ||
| 73 | these incompatibilities will have only a trivial impact on existing | ||
| 74 | applications. | ||
| 75 | <p> | ||
| 76 | This document is a formal specification both of the new APIs and of | ||
| 77 | existing APIs which remain relevant in the new model. Combined with | ||
| 78 | the javadoc for focus-related classes and methods, this document | ||
| 79 | should enable developers to create substantial AWT and Swing | ||
| 80 | applications with a focus behavior that is customized yet consistent | ||
| 81 | across platforms. This document has the following sections: | ||
| 82 | <ul> | ||
| 83 | <li><a href=#Overview>Overview of KeyboardFocusManager</a> | ||
| 84 | <li><a href=#BrowserContexts>KeyboardFocusManager and Browser Contexts</a> | ||
| 85 | <li><a href=#KeyEventDispatcher>KeyEventDispatcher</a> | ||
| 86 | <li><a href=#FocusEventAndWindowEvent>FocusEvent and WindowEvent</a> | ||
| 87 | <li><a href=#EventDelivery>Event Delivery</a> | ||
| 88 | <li><a href=#OppositeComponents>Opposite Components and Windows</a> | ||
| 89 | <li><a href=#TemporaryFocusEvents>Temporary FocusEvents</a> | ||
| 90 | <li><a href=#FocusTraversal>Focus Traversal</a> | ||
| 91 | <li><a href=#FocusTraversalPolicy>Focus Traversal Policy</a> | ||
| 92 | <li><a href=#FocusTraversalPolicyProviders>Focus Traversal Policy Providers</a> | ||
| 93 | <li><a href=#ProgrammaticTraversal>Programmatic Traversal</a> | ||
| 94 | <li><a href=#Focusability>Focusability</a> | ||
| 95 | <li><a href=#FocusableWindows>Focusable Windows</a> | ||
| 96 | <li><a href=#RequestingFocus>Requesting Focus</a> | ||
| 97 | <li><a href=#FocusAndPropertyChangeListener>Focus and PropertyChangeListener</a> | ||
| 98 | <li><a href=#FocusAndVetoableChangeListener>Focus and VetoableChangeListener</a> | ||
| 99 | <li><a href=#ZOrder>Z-Order</a> | ||
| 100 | <li><a href=#ReplacingDefaultKeyboardFocusManager>Replacing DefaultKeyboardFocusManager</a> | ||
| 101 | <li><a href=#Incompatibilities>Incompatibilities with Previous Releases</a> | ||
| 102 | </ul> | ||
| 103 | |||
| 104 | <a name="Overview"></a> | ||
| 105 | <h3>Overview of KeyboardFocusManager</h3> | ||
| 106 | <p> | ||
| 107 | The focus model is centralized around a single class, | ||
| 108 | KeyboardFocusManager, that provides a set of APIs for client code to | ||
| 109 | inquire about the current focus state, initiate focus changes, and | ||
| 110 | replace default focus event dispatching with a custom dispatcher. | ||
| 111 | Clients can inquire about the focus state directly, or can register a | ||
| 112 | PropertyChangeListener that will receive PropertyChangeEvents when a | ||
| 113 | change to the focus state occurs. | ||
| 114 | <p> | ||
| 115 | KeyboardFocusManager introduces the following main concepts and their | ||
| 116 | terminology: | ||
| 117 | <ol> | ||
| 118 | <li>The "focus owner" -- the Component which typically receives | ||
| 119 | keyboard input. | ||
| 120 | <li>The "permanent focus owner" -- the last Component to receive | ||
| 121 | focus permanently. The "focus owner" and the "permanent focus | ||
| 122 | owner" are equivalent unless a temporary focus change is | ||
| 123 | currently in effect. In such a situation, the "permanent focus | ||
| 124 | owner" will again be the "focus owner" when the temporary focus | ||
| 125 | change ends. | ||
| 126 | <li>The "focused Window" -- the Window which contains the "focus | ||
| 127 | owner". | ||
| 128 | <li>The "active Window" -- the Frame or Dialog that is either the | ||
| 129 | "focused Window", or the first Frame or Dialog that is an owner | ||
| 130 | of the "focused Window". | ||
| 131 | <li>"Focus traversal" -- the user's ability to change the "focus | ||
| 132 | owner" without moving the cursor. Typically, this is done using | ||
| 133 | the keyboard (for example, by using the TAB key), or an | ||
| 134 | equivalent device in an accessible environment. Client code can | ||
| 135 | also initiate traversal programmatically. Normal focus traversal | ||
| 136 | can be either "forward" to the "next" Component, or "backward" to | ||
| 137 | the "previous" Component. | ||
| 138 | <li>"Focus traversal cycle" -- a portion of the Component hierarchy, | ||
| 139 | such that normal focus traversal "forward" (or "backward") will | ||
| 140 | traverse through all of the Components in the focus cycle, but no | ||
| 141 | other Components. This cycle provides a mapping from an arbitrary | ||
| 142 | Component in the cycle to its "next" (forward traversal) and | ||
| 143 | "previous" (backward traversal) Components. | ||
| 144 | <li>"Traversable Component" -- Component that is in the focus traversal | ||
| 145 | cycle. | ||
| 146 | <li>"Non-traversable Component" -- Component that is not in the focus | ||
| 147 | traversal cycle. Note that a non-traversable Component can nevertheless | ||
| 148 | be focused in other way (e.g. by direct focus request). | ||
| 149 | <li>"Focus cycle root" -- Container that is the root of the Component | ||
| 150 | hierarchy for a particular "focus traversal cycle". When the | ||
| 151 | "focus owner" is a Component inside a particular cycle, normal | ||
| 152 | forward and backward focus traversal cannot move the "focus | ||
| 153 | owner" above the focus cycle root in the Component hierarchy. | ||
| 154 | Instead, two additional traversal operations, "up cycle" and | ||
| 155 | "down cycle", are defined to allow keyboard and programmatic | ||
| 156 | navigation up and down the focus traversal cycle hierarchy. </li> | ||
| 157 | <li>"Focus traversal policy provider" - Container which has | ||
| 158 | "FocusTraversalPolicyProvider" property as true. This Container will | ||
| 159 | be used to acquire focus traversal policy. This container doesn't | ||
| 160 | define new focus cycle but only modifies the order by which its | ||
| 161 | children are traversed "forward" and "backward". Focus traversal | ||
| 162 | policy provider can be set using | ||
| 163 | <code>setFocusTraversalPolicyProvider</code> on the Container. | ||
| 164 | </ol> | ||
| 165 | |||
| 166 | <p> | ||
| 167 | Every Window and JInternalFrame is, by default, a "focus cycle | ||
| 168 | root". If it's the only focus cycle root, then all of its | ||
| 169 | focusable descendants should be in its focus cycle, and its focus | ||
| 170 | traversal policy should enforce that they are by making sure that | ||
| 171 | all will be reached during normal forward (or backward) | ||
| 172 | traversal. If, on the other hand, the Window or JInternalFrame | ||
| 173 | has descendants that are also focus cycle roots, then each such | ||
| 174 | descendant is a member of two focus cycles: the one that it is | ||
| 175 | the root of, and the one of its nearest focus-cycle-root | ||
| 176 | ancestor. In order to traverse the focusable components belonging | ||
| 177 | to the focus cycle of such a "descendant" focus cycle root, one | ||
| 178 | first traverses (forward or backward) to reach the descendant, | ||
| 179 | and then uses the "down cycle" operation to reach, in turn, its | ||
| 180 | descendants. | ||
| 181 | |||
| 182 | <p> | ||
| 183 | Here is an example:<br> <img src="FocusCycle.gif" align=middle | ||
| 184 | alt="Three groups as described below: ABCF BDE and DGH. "><br> | ||
| 185 | |||
| 186 | <p>Assume the following: | ||
| 187 | <ul> | ||
| 188 | <li><b>A</b> is a <code>Window</code>, which means that it | ||
| 189 | must be a focus cycle root. | ||
| 190 | <li><b>B</b> and <b>D</b> are <code>Container</code>s that | ||
| 191 | are focus cycle roots. | ||
| 192 | <li><b>C</b> is a <code>Container</code> that is not a focus cycle root. | ||
| 193 | <li><b>G</b>, <b>H</b>, <b>E</b>, and <b>F</b> are all | ||
| 194 | <code>Component</code>s. | ||
| 195 | </ul> | ||
| 196 | |||
| 197 | There are a total of three focus cycle roots in this example: | ||
| 198 | |||
| 199 | <ol> | ||
| 200 | <li><b>A</b> is a root, and <b>A</b>, <b>B</b>, <b>C</b>, | ||
| 201 | and <b>F</b> are members of <b>A</b>'s cycle. | ||
| 202 | <li><b>B</b> is a root, and <b>B</b>, <b>D</b>, and | ||
| 203 | <b>E</b> are members of <b>B</b>'s cycle. | ||
| 204 | <li><b>D</b> is a root, and <b>D</b>, <b>G</b>, | ||
| 205 | and <b>H</b> are members of <b>D</b>'s cycle. | ||
| 206 | </ol> | ||
| 207 | |||
| 208 | Windows are the only Containers which, by default, are focus cycle | ||
| 209 | roots. | ||
| 210 | |||
| 211 | |||
| 212 | <code>KeyboardFocusManager</code> is an abstract class. AWT provides a default | ||
| 213 | implementation in the <code>DefaultKeyboardFocusManager</code> class. | ||
| 214 | |||
| 215 | |||
| 216 | <a name="BrowserContexts"></a> | ||
| 217 | <h3>KeyboardFocusManager and Browser Contexts</h3> | ||
| 218 | <p> | ||
| 219 | Some browsers partition applets in different code bases into separate | ||
| 220 | contexts, and establish walls between these contexts. Each thread and | ||
| 221 | each Component is associated with a particular context and cannot | ||
| 222 | interfere with threads or access Components in other contexts. In such | ||
| 223 | a scenario, there will be one KeyboardFocusManager per context. Other | ||
| 224 | browsers place all applets into the same context, implying that there | ||
| 225 | will be only a single, global KeyboardFocusManager for all | ||
| 226 | applets. This behavior is implementation-dependent. Consult your | ||
| 227 | browser's documentation for more information. No matter how many | ||
| 228 | contexts there may be, however, there can never be more than one focus | ||
| 229 | owner, focused Window, or active Window, per ClassLoader. | ||
| 230 | |||
| 231 | |||
| 232 | <a name="KeyEventDispatcher"></a> | ||
| 233 | <h3>KeyEventDispatcher and KeyEventPostProcessor</h3> | ||
| 234 | <p> | ||
| 235 | While the user's KeyEvents should generally be delivered to the focus | ||
| 236 | owner, there are rare cases where this is not desirable. An input | ||
| 237 | method is an example of a specialized Component that should receive | ||
| 238 | KeyEvents even though its associated text Component is and should | ||
| 239 | remain the focus owner. | ||
| 240 | <p> | ||
| 241 | A KeyEventDispatcher is a lightweight interface that allows client | ||
| 242 | code to pre-listen to all KeyEvents in a particular context. Instances | ||
| 243 | of classes that implement the interface and are registered with the | ||
| 244 | current KeyboardFocusManager will receive KeyEvents before they are | ||
| 245 | dispatched to the focus owner, allowing the KeyEventDispatcher to | ||
| 246 | retarget the event, consume it, dispatch it itself, or make other | ||
| 247 | changes. | ||
| 248 | <p> | ||
| 249 | For consistency, KeyboardFocusManager itself is a | ||
| 250 | KeyEventDispatcher. By default, the current KeyboardFocusManager will | ||
| 251 | be the sink for all KeyEvents not dispatched by the registered | ||
| 252 | KeyEventDispatchers. The current KeyboardFocusManager cannot be | ||
| 253 | completely deregistered as a KeyEventDispatcher. However, if a | ||
| 254 | KeyEventDispatcher reports that it dispatched the KeyEvent, regardless | ||
| 255 | of whether it actually did so, the KeyboardFocusManager will take no | ||
| 256 | further action with regard to the KeyEvent. (While it is possible for | ||
| 257 | client code to register the current KeyboardFocusManager as a | ||
| 258 | KeyEventDispatcher one or more times, there is no obvious reason why | ||
| 259 | this would be necessary, and therefore it is not recommended.) | ||
| 260 | <p> | ||
| 261 | Client-code may also post-listen to KeyEvents in a particular context | ||
| 262 | using the KeyEventPostProcessor interface. KeyEventPostProcessors | ||
| 263 | registered with the current KeyboardFocusManager will receive | ||
| 264 | KeyEvents after the KeyEvents have been dispatched to and handled by | ||
| 265 | the focus owner. The KeyEventPostProcessors will also receive | ||
| 266 | KeyEvents that would have been otherwise discarded because no | ||
| 267 | Component in the application currently owns the focus. This will allow | ||
| 268 | applications to implement features that require global KeyEvent post- | ||
| 269 | handling, such as menu shortcuts. | ||
| 270 | <p> | ||
| 271 | Like KeyEventDispatcher, KeyboardFocusManager also implements | ||
| 272 | KeyEventPostProcessor, and similar restrictions apply to its use in | ||
| 273 | that capacity. | ||
| 274 | |||
| 275 | <a name="FocusEventAndWindowEvent"></a> | ||
| 276 | <h3>FocusEvent and WindowEvent</h3> | ||
| 277 | <p> | ||
| 278 | The AWT defines the following six event types central to the focus | ||
| 279 | model in two different <code>java.awt.event</code> classes: | ||
| 280 | <ol> | ||
| 281 | <li><code>WindowEvent.WINDOW_ACTIVATED</code>: This event is | ||
| 282 | dispatched to a Frame or Dialog (but never a Window which | ||
| 283 | is not a Frame or Dialog) when it becomes the active Window. | ||
| 284 | <li><code>WindowEvent.WINDOW_GAINED_FOCUS</code>: This event is | ||
| 285 | dispatched to a Window when it becomes the focused Window. | ||
| 286 | Only focusable Windows can receive this event. | ||
| 287 | <li><code>FocusEvent.FOCUS_GAINED</code>: This event is dispatched | ||
| 288 | to a Component when it becomes the focus owner. Only focusable | ||
| 289 | Components can receive this event. | ||
| 290 | <li><code>FocusEvent.FOCUS_LOST</code>: This event is dispatched | ||
| 291 | to a Component when it is no longer the focus owner. | ||
| 292 | <li><code>WindowEvent.WINDOW_LOST_FOCUS</code>: This event is | ||
| 293 | dispatched to a Window when it is no longer the focused Window. | ||
| 294 | <li><code>WindowEvent.WINDOW_DEACTIVATED</code>: This event is | ||
| 295 | dispatched to a Frame or Dialog (but never a Window which is | ||
| 296 | not a Frame or Dialog) when it is no longer the active Window. | ||
| 297 | </ol> | ||
| 298 | |||
| 299 | <a name="EventDelivery"></a> | ||
| 300 | <h3>Event Delivery</h3> | ||
| 301 | <p> | ||
| 302 | If the focus is not in java application and the user clicks on a focusable | ||
| 303 | child Component<b>a</b> of an inactive Frame <b>b</b>, the following events | ||
| 304 | will be dispatched and handled in order: | ||
| 305 | |||
| 306 | <ol> | ||
| 307 | <li><b>b</b> will receive a <code>WINDOW_ACTIVATED</code> event. | ||
| 308 | <li>Next, <b>b</b> will receive a <code>WINDOW_GAINED_FOCUS</code> event. | ||
| 309 | <li>Finally, <b>a</b> will receive a <code>FOCUS_GAINED</code> event. | ||
| 310 | </ol> | ||
| 311 | |||
| 312 | If the user later clicks on a focusable child Component <b>c</b> of another | ||
| 313 | Frame <b>d</b>, the following events will be dispatched and handled in | ||
| 314 | order: | ||
| 315 | <ol> | ||
| 316 | <li><b>a</b> will receive a <code>FOCUS_LOST</code> event. | ||
| 317 | <li><b>b</b> will receive a <code>WINDOW_LOST_FOCUS</code> event. | ||
| 318 | <li><b>b</b> will receive a <code>WINDOW_DEACTIVATED</code> event. | ||
| 319 | <li><b>d</b> will receive a <code>WINDOW_ACTIVATED</code> event. | ||
| 320 | <li><b>d</b> will receive a <code>WINDOW_GAINED_FOCUS</code> event. | ||
| 321 | <li><b>c</b> will receive a <code>FOCUS_GAINED</code> event. | ||
| 322 | </ol> | ||
| 323 | |||
| 324 | Note that each event will be fully handled before the next event is | ||
| 325 | dispatched. This restriction will be enforced even if the Components | ||
| 326 | are in different contexts and are handled on different event | ||
| 327 | dispatching threads. | ||
| 328 | <p> | ||
| 329 | In addition, each event type will be dispatched in 1-to-1 | ||
| 330 | correspondence with its opposite event type. For example, if a | ||
| 331 | Component receives a <code>FOCUS_GAINED</code> event, under no | ||
| 332 | circumstances can it ever receive another <code>FOCUS_GAINED</code> | ||
| 333 | event without an intervening <code>FOCUS_LOST</code> event. | ||
| 334 | <p> | ||
| 335 | Finally, it is important to note that these events are delivered for | ||
| 336 | informational purposes only. It is impossible, for example, to prevent | ||
| 337 | the delivery of a pending <code>FOCUS_GAINED</code> event by requesting | ||
| 338 | focus back to the Component losing focus while handling the preceding | ||
| 339 | <code>FOCUS_LOST</code> event. While client code may make such a request, | ||
| 340 | the pending <code>FOCUS_GAINED</code> will still be delivered, | ||
| 341 | followed later by the events transferring focus back to the original | ||
| 342 | focus owner. | ||
| 343 | <p> | ||
| 344 | If it is absolutely necessary to suppress the <code>FOCUS_GAINED</code> event, | ||
| 345 | client code can install a <code>VetoableChangeListener</code> which | ||
| 346 | rejects the focus change. See <a href="#FocusAndVetoableChangeListener">Focus | ||
| 347 | and VetoableChangeListener</a>. | ||
| 348 | |||
| 349 | |||
| 350 | <a name="OppositeComponents"></a> | ||
| 351 | <h3>Opposite Components and Windows</h3> | ||
| 352 | <p> | ||
| 353 | Each event includes information about the "opposite" Component or | ||
| 354 | Window involved in the focus or activation change. For example, for a | ||
| 355 | <code>FOCUS_GAINED</code> event, the opposite Component is the Component | ||
| 356 | that lost focus. If the focus or activation change occurs with a native | ||
| 357 | application, with a Java application in a different VM or context, or | ||
| 358 | with no other Component, then the opposite Component or Window is | ||
| 359 | null. This information is accessible using | ||
| 360 | <code>FocusEvent.getOppositeComponent</code> or | ||
| 361 | <code>WindowEvent.getOppositeWindow</code>. | ||
| 362 | <p> | ||
| 363 | On some platforms, it is not possible to discern the opposite | ||
| 364 | Component or Window when the focus or activation change occurs between | ||
| 365 | two different heavyweight Components. In these cases, the opposite | ||
| 366 | Component or Window may be set to null on some platforms, and to a | ||
| 367 | valid non-null value on other platforms. However, for a focus change | ||
| 368 | between two lightweight Components which share the same heavyweight | ||
| 369 | Container, the opposite Component will always be set correctly. Thus, | ||
| 370 | a pure Swing application can ignore this platform restriction when | ||
| 371 | using the opposite Component of a focus change that occurred within a | ||
| 372 | top-level Window. | ||
| 373 | |||
| 374 | <a name="TemporaryFocusEvents"></a> | ||
| 375 | <h3>Temporary FocusEvents</h3> | ||
| 376 | <p> | ||
| 377 | <code>FOCUS_GAINED</code> and <code>FOCUS_LOST</code> events are | ||
| 378 | marked as either temporary or permanent. | ||
| 379 | <p> | ||
| 380 | Temporary <code>FOCUS_LOST</code> events are sent when a Component is | ||
| 381 | losing the focus, but will regain the focus shortly. These events | ||
| 382 | can be useful when focus changes are used as triggers for validation | ||
| 383 | of data. For instance, a text Component may want to commit its | ||
| 384 | contents when the user begins interacting with another Component, | ||
| 385 | and can accomplish this by responding to <code>FOCUS_LOST</code> events. | ||
| 386 | However, if the <code>FocusEvent</code> received is temporary, | ||
| 387 | the commit should not be done, since the text field will be receiving | ||
| 388 | the focus again shortly. | ||
| 389 | <p> | ||
| 390 | A permanent focus transfer typically occurs as the result of a user | ||
| 391 | clicking on a selectable, heavyweight Component, focus traversal with | ||
| 392 | the keyboard or an equivalent input device, or from a call to | ||
| 393 | <code>requestFocus()</code> or <code>requestFocusInWindow()</code>. | ||
| 394 | <p> | ||
| 395 | A temporary focus transfer typically occurs as the result of showing a | ||
| 396 | Menu or PopupMenu, clicking or dragging a Scrollbar, moving a Window | ||
| 397 | by dragging the title bar, or making another Window the focused | ||
| 398 | Window. Note that on some platforms, these actions may not generate | ||
| 399 | any FocusEvents at all. On others, temporary focus transfers will | ||
| 400 | occur. | ||
| 401 | <p> | ||
| 402 | When a Component receives a temporary <code>FOCUS_LOST</code> event, | ||
| 403 | the event's opposite Component (if any) may receive a temporary | ||
| 404 | <code>FOCUS_GAINED</code> event, but could also receive a permanent | ||
| 405 | <code>FOCUS_GAINED</code> event. Showing a Menu or PopupMenu, or | ||
| 406 | clicking or dragging a Scrollbar, should generate a temporary | ||
| 407 | <code>FOCUS_GAINED</code> event. Changing the focused Window, | ||
| 408 | however, will yield a permanent <code>FOCUS_GAINED</code> event | ||
| 409 | for the new focus owner. | ||
| 410 | <p> | ||
| 411 | The Component class includes variants of <code>requestFocus</code> and | ||
| 412 | <code>requestFocusInWindow</code> which take a desired temporary state as a | ||
| 413 | parameter. However, because specifying an arbitrary temporary state | ||
| 414 | may not be implementable on all native windowing systems, correct | ||
| 415 | behavior for this method can be guaranteed only for lightweight | ||
| 416 | Components. This method is not intended for general use, but exists | ||
| 417 | instead as a hook for lightweight Component libraries, such as Swing. | ||
| 418 | |||
| 419 | <a name="FocusTraversal"></a> | ||
| 420 | <h3>Focus Traversal</h3> | ||
| 421 | <p> | ||
| 422 | Each Component defines its own Set of focus traversal keys for a given | ||
| 423 | focus traversal operation. Components support separate Sets of keys | ||
| 424 | for forward and backward traversal, and also for traversal up one | ||
| 425 | focus traversal cycle. Containers which are focus cycle roots also | ||
| 426 | support a Set of keys for traversal down one focus traversal cycle. If | ||
| 427 | a Set is not explicitly defined for a Component, that Component | ||
| 428 | recursively inherits a Set from its parent, and ultimately from a | ||
| 429 | context-wide default set on the current <code>KeyboardFocusManager</code>. | ||
| 430 | <p> | ||
| 431 | Using the <code>AWTKeyStroke</code> API, client code can specify | ||
| 432 | on which of two specific KeyEvents, <code>KEY_PRESSED</code> or | ||
| 433 | <code>KEY_RELEASED</code>, the focus traversal operation will occur. | ||
| 434 | Regardless of which KeyEvent is specified, however, all KeyEvents | ||
| 435 | related to the focus traversal key, including the associated | ||
| 436 | <code>KEY_TYPED</code> event, will be consumed, and will not be | ||
| 437 | dispatched to any Component. It is a runtime error to specify a | ||
| 438 | <code>KEY_TYPED</code> event as mapping to a focus traversal operation, | ||
| 439 | or to map the same event to multiple focus traversal operations for any | ||
| 440 | particular Component or for a <code>KeyboardFocusManager</code>'s defaults. | ||
| 441 | <p> | ||
| 442 | The default focus traversal keys are implementation-dependent. Sun | ||
| 443 | recommends that the all implementations for a particular native | ||
| 444 | platform use the same keys. For Windows and Unix, the recommendations | ||
| 445 | are: | ||
| 446 | |||
| 447 | <ul> | ||
| 448 | <li>traverse forward to the next Component: | ||
| 449 | <br><i>TextAreas</i>: <code>CTRL-TAB</code> on <code>KEY_PRESSED</code> | ||
| 450 | <br><i>All others</i>: <code>TAB</code> on <code>KEY_PRESSED</code> and | ||
| 451 | <code>CTRL-TAB</code> on <code>KEY_PRESSED</code> | ||
| 452 | <li>traverse backward to the previous Component: | ||
| 453 | <br><i>TextAreas</i>: <code>CTRL-SHIFT-TAB</code> on | ||
| 454 | <code>KEY_PRESSED</code> | ||
| 455 | <br><i>All others</i>: <code>SHIFT-TAB</code> on <code>KEY_PRESSED</code> | ||
| 456 | and <code>CTRL-SHIFT-TAB</code> on | ||
| 457 | <code>KEY_PRESSED</code> | ||
| 458 | <li>traverse up one focus traversal cycle : <none> | ||
| 459 | <li>traverse down one focus traversal cycle : <none> | ||
| 460 | </ul> | ||
| 461 | <p> | ||
| 462 | Components can enable and disable all of their focus traversal keys en | ||
| 463 | masse using <code>Component.setFocusTraversalKeysEnabled</code>. When focus | ||
| 464 | traversal keys are disabled, the Component receives all KeyEvents for | ||
| 465 | those keys. When focus traversal keys are enabled, the Component never | ||
| 466 | receives KeyEvents for traversal keys; instead, the KeyEvents are | ||
| 467 | automatically mapped to focus traversal operations. | ||
| 468 | <p> | ||
| 469 | For normal forward and backward traversal, the AWT focus | ||
| 470 | implementation determines which Component to focus next based on the | ||
| 471 | <a href=#FocusTraversalPolicy><code>FocusTraversalPolicy</code></a> of | ||
| 472 | the focus owner's focus cycle root or focus traversal policy provider. If the | ||
| 473 | focus owner is a focus cycle root, then it may be ambiguous as to which | ||
| 474 | Components represent the next and previous Components to focus during | ||
| 475 | normal focus traversal. Thus, the current | ||
| 476 | <code>KeyboardFocusManager</code> maintains a reference to the | ||
| 477 | "current" focus cycle root, which is global across all contexts. The | ||
| 478 | current focus cycle root is used to resolve the ambiguity. | ||
| 479 | <p> | ||
| 480 | For up-cycle traversal, the focus owner is set to the current focus | ||
| 481 | owner's focus cycle root, and the current focus cycle root is set to | ||
| 482 | the new focus owner's focus cycle root. If, however, the current focus | ||
| 483 | owner's focus cycle root is a top-level window, then the focus owner | ||
| 484 | is set to the focus cycle root's default component to focus, and the | ||
| 485 | current focus cycle root is unchanged. | ||
| 486 | <p> | ||
| 487 | For down-cycle traversal, if the current focus owner is a focus cycle | ||
| 488 | root, then the focus owner is set to the current focus owner's default | ||
| 489 | component to focus, and the current focus cycle root is set to the | ||
| 490 | current focus owner. If the current focus owner is not a focus cycle | ||
| 491 | root, then no focus traversal operation occurs. | ||
| 492 | |||
| 493 | |||
| 494 | <a name="FocusTraversalPolicy"></a> | ||
| 495 | <h3>FocusTraversalPolicy</h3> | ||
| 496 | <p> | ||
| 497 | |||
| 498 | A <code>FocusTraversalPolicy</code> defines the order in which Components within | ||
| 499 | a particular focus cycle root or focus traversal policy provider are | ||
| 500 | traversed. Instances of <code>FocusTraversalPolicy</code> can be shared across | ||
| 501 | Containers, allowing those Containers to implement the same traversal policy. | ||
| 502 | FocusTraversalPolicies do not need to be reinitialized when the | ||
| 503 | focus-traversal-cycle hierarchy changes. | ||
| 504 | |||
| 505 | <p> | ||
| 506 | Each <code>FocusTraversalPolicy</code> must define the following | ||
| 507 | five algorithms: | ||
| 508 | |||
| 509 | <ol> | ||
| 510 | <li>Given a focus cycle root and a Component <b>a</b> in that cycle, the | ||
| 511 | next Component after <b>a</b>. | ||
| 512 | <li>Given a focus cycle root and a Component <b>a</b> in that cycle, the | ||
| 513 | previous Component before <b>a</b>. | ||
| 514 | <li>Given a focus cycle root, the "first" Component in that cycle. | ||
| 515 | The "first" Component is the Component to focus when traversal | ||
| 516 | wraps in the forward direction. | ||
| 517 | <li>Given a focus cycle root, the "last" Component in that cycle. | ||
| 518 | The "last" Component is the Component to focus when traversal | ||
| 519 | wraps in the reverse direction. | ||
| 520 | <li>Given a focus cycle root, the "default" Component in that cycle. | ||
| 521 | The "default" Component will be the first to receive focus when | ||
| 522 | traversing down into a new focus traversal cycle. This may be the | ||
| 523 | same as the "first" Component, but need not be. | ||
| 524 | </ol> | ||
| 525 | |||
| 526 | <p> | ||
| 527 | A <code>FocusTraversalPolicy</code> may optionally provide an | ||
| 528 | algorithm for the following: | ||
| 529 | <blockquote> | ||
| 530 | Given a Window, the "initial" Component in that Window. The initial | ||
| 531 | Component will be the first to receive focus when the Window is | ||
| 532 | first made visible. By default, this is the same as the "default" | ||
| 533 | Component. | ||
| 534 | </blockquote> | ||
| 535 | |||
| 536 | In addition, Swing provides a subclass of <code>FocusTraversalPolicy</code>, | ||
| 537 | <code>InternalFrameFocusTraversalPolicy</code>, which allows developers | ||
| 538 | to provide an algorithm for the following: | ||
| 539 | |||
| 540 | <blockquote> | ||
| 541 | Given a <code>JInternalFrame</code>, the "initial" Component in that | ||
| 542 | <code>JInternalFrame</code>. The initial Component is the first to | ||
| 543 | receive focus when the <code>JInternalFrame</code> is first selected. | ||
| 544 | By default, this is the same as the <code>JInternalFrame</code>'s | ||
| 545 | default Component to focus. | ||
| 546 | </blockquote> | ||
| 547 | |||
| 548 | A <code>FocusTraversalPolicy</code> is installed on a Container using | ||
| 549 | Container.<code>setFocusTraversalPolicy</code>. If a policy is not explicitly | ||
| 550 | set, then a Container inherits its policy from its nearest focus-cycle-root | ||
| 551 | ancestor. Top-levels initialize their focus traversal policies using the context | ||
| 552 | default policy. The context default policy is established by using | ||
| 553 | KeyboardFocusManager. <code>setDefaultFocusTraversalPolicy</code>. | ||
| 554 | |||
| 555 | <p> | ||
| 556 | AWT provides two standard <code>FocusTraversalPolicy</code> | ||
| 557 | implementations for use by client code. | ||
| 558 | |||
| 559 | <ol> | ||
| 560 | <li><code>ContainerOrderFocusTraversalPolicy</code>: Iterates across the | ||
| 561 | Components in a focus traversal cycle in the order they were added | ||
| 562 | to their Containers. Each Component is tested for fitness using the | ||
| 563 | accept(Component) method. By default, a Component is fit only if it | ||
| 564 | is visible, displayable, enabled, and focusable. | ||
| 565 | <li>By default, ContainerOrderFocusTraversalPolicy implicitly transfers | ||
| 566 | focus down-cycle. That is, during normal forward focus traversal, | ||
| 567 | the Component traversed after a focus cycle root will be the | ||
| 568 | focus-cycle-root's default Component to focus, regardless of whether | ||
| 569 | the focus cycle root is a traversable or non-traversable Container | ||
| 570 | (see the pic.1,2 below). Such behavior provides backward compatibility | ||
| 571 | with applications designed without the concepts of up- and down-cycle | ||
| 572 | traversal. | ||
| 573 | <li><code>DefaultFocusTraversalPolicy</code>: A subclass of | ||
| 574 | <code>ContainerOrderFocusTraversalPolicy</code> which redefines | ||
| 575 | the fitness test. If client code has explicitly set the | ||
| 576 | focusability of a Component by either overriding | ||
| 577 | <code>Component.isFocusTraversable()</code> or | ||
| 578 | <code>Component.isFocusable()</code>, or by calling | ||
| 579 | <code>Component.setFocusable(boolean)</code>, then a | ||
| 580 | <code>DefaultFocusTraversalPolicy</code> behaves exactly | ||
| 581 | like a <code>ContainerOrderFocusTraversalPolicy</code>. If, | ||
| 582 | however, the Component is relying on default focusability, then a | ||
| 583 | <code>DefaultFocusTraversalPolicy</code> will reject all | ||
| 584 | Components with non-focusable peers. | ||
| 585 | <br> | ||
| 586 | The focusability of a peer is implementation-dependent. Sun | ||
| 587 | recommends that all implementations for a particular native platform | ||
| 588 | construct peers with the same focusability. The recommendations for | ||
| 589 | Windows and Unix are that Canvases, Labels, Panels, Scrollbars, | ||
| 590 | ScrollPanes, Windows, and lightweight Components have non-focusable | ||
| 591 | peers, and all other Components have focusable peers. These | ||
| 592 | recommendations are used in the Sun AWT implementations. Note that | ||
| 593 | the focusability of a Component's peer is different from, and does | ||
| 594 | not impact, the focusability of the Component itself. | ||
| 595 | </ol> | ||
| 596 | <p> | ||
| 597 | Swing provides two additional, standard FocusTraversalPolicy | ||
| 598 | implementations for use by client code. Each implementation is an | ||
| 599 | InternalFrameFocusTraversalPolicy. | ||
| 600 | |||
| 601 | <ol> | ||
| 602 | <li>SortingFocusTraversalPolicy: Determines traversal order by | ||
| 603 | sorting the Components of a focus traversal cycle based on a given | ||
| 604 | Comparator. Each Component is tested for fitness using the | ||
| 605 | accept(Component) method. By default, a Component is fit only if it | ||
| 606 | is visible, displayable, enabled, and focusable. | ||
| 607 | <li>By default, SortingFocusTraversalPolicy implicitly transfers focus | ||
| 608 | down-cycle. That is, during normal forward focus traversal, the | ||
| 609 | Component traversed after a focus cycle root will be the | ||
| 610 | focus-cycle-root's default Component to focus, regardless of | ||
| 611 | whether the focus cycle root is a traversable or non-traversable | ||
| 612 | Container (see the pic.1,2 below). Such behavior provides backward | ||
| 613 | compatibility with applications designed without the concepts of | ||
| 614 | up- and down-cycle traversal. | ||
| 615 | <li>LayoutFocusTraversalPolicy: A subclass of | ||
| 616 | SortingFocusTraversalPolicy which sorts Components based on their | ||
| 617 | size, position, and orientation. Based on their size and position, | ||
| 618 | Components are roughly categorized into rows and columns. For a | ||
| 619 | Container with horizontal orientation, columns run left-to-right or | ||
| 620 | right-to-left, and rows run top-to-bottom. For a Container with | ||
| 621 | vertical orientation, columns run top-to-bottom and rows run | ||
| 622 | left-to-right or right-to-left. All columns in a row are fully | ||
| 623 | traversed before proceeding to the next row. | ||
| 624 | <br> | ||
| 625 | In addition, the fitness test is extended to exclude JComponents | ||
| 626 | that have or inherit empty InputMaps. | ||
| 627 | </ol> | ||
| 628 | <p> | ||
| 629 | The figure below shows an implicit focus transfer: | ||
| 630 | <br><img src="ImplicitFocusTransfer.gif" align=middle alt="Implicit focus transfer."><br> | ||
| 631 | |||
| 632 | Assume the following: | ||
| 633 | <ul> | ||
| 634 | <li><b>A</b>, <b>B</b> and <b>C</b> are components in some window (a container) | ||
| 635 | <li><b>R</b> is a container in the window and it is a parent of <b>B</b> and <b>C</b>. | ||
| 636 | Besides, <b>R</b> is a focus cycle root. | ||
| 637 | <li><b>B</b> is the default component in the focul traversal cycle of <b>R</b> | ||
| 638 | <li><b>R</b> is a traversable Container in the pic.1, and it is a non-traversable | ||
| 639 | Container in the pic.2. | ||
| 640 | <li>In such a case a forward traversal will look as follows: | ||
| 641 | <ul> | ||
| 642 | <li> pic.1 : <b>A</b> -> <b>R</b> -> <b>B</b> -> <b>C</b> | ||
| 643 | <li> pic.2 : <b>A</b> -> <b>B</b> -> <b>C</b> | ||
| 644 | </ul> | ||
| 645 | </ul> | ||
| 646 | |||
| 647 | <p> | ||
| 648 | Swing applications, or mixed Swing/AWT applications, that use one of | ||
| 649 | the standard look and feels, or any other look and feel derived from | ||
| 650 | BasicLookAndFeel, will use LayoutFocusTraversalPolicy for all | ||
| 651 | Containers by default. | ||
| 652 | <p> | ||
| 653 | All other applications, including pure AWT applications, will use | ||
| 654 | <code>DefaultFocusTraversalPolicy</code> by default. | ||
| 655 | |||
| 656 | <a name="FocusTraversalPolicyProviders"></a> | ||
| 657 | <h3>Focus Traversal Policy Providers</h3> | ||
| 658 | <p> | ||
| 659 | A Container that isn't a focus cycle root has an option to provide a | ||
| 660 | FocusTraversalPolicy of its own. To do so, one needs to set Container's focus | ||
| 661 | traversal policy provider property to <code>true</code> with the call to | ||
| 662 | |||
| 663 | <ul> | ||
| 664 | <code>Container.setFocusTraversalPolicyProvider(boolean)</code> | ||
| 665 | </ul> | ||
| 666 | |||
| 667 | To determine whether a Container is a focus traversal policy provider, the | ||
| 668 | following method should be used: | ||
| 669 | |||
| 670 | <ul> | ||
| 671 | <code>Container.isFocusTraversalPolicyProvider()</code> | ||
| 672 | </ul> | ||
| 673 | |||
| 674 | If focus traversal policy provider property is set on a focus cycle root, it | ||
| 675 | isn't considered a focus traversal policy provider and behaves just like any | ||
| 676 | other focus cycle root. | ||
| 677 | |||
| 678 | <p> | ||
| 679 | The main difference between focus cycle roots and focus traversal policy | ||
| 680 | providers is that the latter allow focus to enter and leave them just as all other | ||
| 681 | Containers. However, children inside focus traversal policy provider are | ||
| 682 | traversed in the order determined by provider's FocusTraversalPolicy. In order | ||
| 683 | to enable focus traversal policy providers to behave this way, | ||
| 684 | FocusTraversalPolicies treat them in the following manner: | ||
| 685 | |||
| 686 | <ul> | ||
| 687 | <li> Focus traversal policy providers can be passed to FocusTraversalPolicy | ||
| 688 | methods instead of focus cycle roots. | ||
| 689 | <li> When calculating next or previous Component in | ||
| 690 | <code>FocusTraversalPolicy.getComponentAfter</code> or | ||
| 691 | <code>FocusTraversalPolicy.getComponentBefore</code>, | ||
| 692 | <ul> | ||
| 693 | <li>if a Component is a child of a focus traversal policy provider, | ||
| 694 | the next and previous for this Component are determined using this | ||
| 695 | focus traversal policy provider's FocusTraversalPolicy. However, | ||
| 696 | in order for focus to leave the provider, the following rules are | ||
| 697 | applied: | ||
| 698 | <ul> | ||
| 699 | <li> if at some point the <code>next</code> found Component is | ||
| 700 | the <code>first</code> Component of focus traversal policy | ||
| 701 | provider, the Component after the focus traversal policy | ||
| 702 | provider is returned | ||
| 703 | <li> if at some point the <code>previous</code> found Component is | ||
| 704 | the <code>last</code> Component of focus traversal policy | ||
| 705 | provider, the Component before the focus traversal policy | ||
| 706 | provider is returned | ||
| 707 | </ul> | ||
| 708 | <li> When calculating the next Component in | ||
| 709 | <code>FocusTraversalPolicy.getComponentAfter</code>, | ||
| 710 | <ul> | ||
| 711 | <li> if an obtained Component is a non-traversable Container and | ||
| 712 | it is a focus traversal policy provider, then the default Component | ||
| 713 | of that provider is returned | ||
| 714 | <li> if the Component passed to the <code>FocusTraversalPolicy.getComponentAfter</code> | ||
| 715 | method is a traversable Container and it is a focus | ||
| 716 | traversal policy provider, then the default Component of this provider | ||
| 717 | is returned | ||
| 718 | </ul> | ||
| 719 | <li> When calculating the previous Component in | ||
| 720 | <code>FocusTraversalPolicy.getComponentBefore</code>, | ||
| 721 | <ul> | ||
| 722 | <li> if an obtained Component is a Container (traversable or | ||
| 723 | non-traversable) and it is a focus traversal policy provider, then | ||
| 724 | the last Component of that provider is returned | ||
| 725 | </ul> | ||
| 726 | </ul> | ||
| 727 | <li> When calculating the first Component in FocusTraversalPolicy.getFirstComponent, | ||
| 728 | <ul> | ||
| 729 | <li> if an obtained Component is a non-traversable Container and it is a focus | ||
| 730 | traversal policy provider, then the default Component of that provider is | ||
| 731 | returned | ||
| 732 | <li> if an obtained Component is a traversable Container and it is a focus traversal | ||
| 733 | policy provider, then that Container itself is returned | ||
| 734 | </ul> | ||
| 735 | <li> When calculating the last Component in FocusTraversalPolicy.getLastComponent, | ||
| 736 | <ul> | ||
| 737 | <li> if an obtained Component is a Container (traversable or non-traversable) | ||
| 738 | and it is a focus traversal policy provider, then the last Component of | ||
| 739 | that provider is returned | ||
| 740 | </ul> | ||
| 741 | </ul> | ||
| 742 | |||
| 743 | <a name="ProgrammaticTraversal"></a> | ||
| 744 | <h3>Programmatic Traversal</h3> | ||
| 745 | <p> | ||
| 746 | In addition to user-initiated focus traversal, client code can | ||
| 747 | initiate a focus traversal operation programmatically. To client code, | ||
| 748 | programmatic traversals are indistinguishable from user-initiated | ||
| 749 | traversals. The preferred way to initiate a programmatic traversal is | ||
| 750 | to use one of the following methods on <code>KeyboardFocusManager</code>: | ||
| 751 | |||
| 752 | <ul> | ||
| 753 | <code>KeyboardFocusManager.focusNextComponent()</code> | ||
| 754 | <code>KeyboardFocusManager.focusPreviousComponent()</code> | ||
| 755 | <code>KeyboardFocusManager.upFocusCycle()</code> | ||
| 756 | <code>KeyboardFocusManager.downFocusCycle()</code> | ||
| 757 | </ul> | ||
| 758 | |||
| 759 | <p> | ||
| 760 | Each of these methods initiates the traversal operation with the | ||
| 761 | current focus owner. If there is currently no focus owner, then no | ||
| 762 | traversal operation occurs. In addition, if the focus owner is not a | ||
| 763 | focus cycle root, then downFocusCycle() performs no traversal | ||
| 764 | operation. | ||
| 765 | <p> | ||
| 766 | <code>KeyboardFocusManager</code> also supports the following variants | ||
| 767 | of these methods: | ||
| 768 | |||
| 769 | <ul> | ||
| 770 | <li><code>KeyboardFocusManager.focusNextComponent(Component)</code> | ||
| 771 | <li><code>KeyboardFocusManager.focusPreviousComponent(Component)</code> | ||
| 772 | <li><code>KeyboardFocusManager.upFocusCycle(Component)</code> | ||
| 773 | <li><code>KeyboardFocusManager.downFocusCycle(Container)</code> | ||
| 774 | </ul> | ||
| 775 | |||
| 776 | Each of these methods initiates the traversal operation with the | ||
| 777 | specified Component rather than the focus owner. That is, the | ||
| 778 | traversal occurs as though the specified Component is the focus owner, | ||
| 779 | though it need not be. | ||
| 780 | <p> | ||
| 781 | Alternate, but equivalent, APIs are defined on the Component and | ||
| 782 | Container classes themselves: | ||
| 783 | |||
| 784 | <ul> | ||
| 785 | <li><code>Component.transferFocus()</code> | ||
| 786 | <li><code>Component.transferFocusBackward()</code> | ||
| 787 | <li><code>Component.transferFocusUpCycle()</code> | ||
| 788 | <li><code>Container.transferFocusDownCycle()</code> | ||
| 789 | </ul> | ||
| 790 | |||
| 791 | As with the <code>KeyboardFocusManager</code> variants, each of these methods | ||
| 792 | initiates the traversal operation as though the Component is the focus | ||
| 793 | owner, though it need not be. | ||
| 794 | <p> | ||
| 795 | Also note that hiding or disabling the focus owner, directly or | ||
| 796 | indirectly via an ancestor, or making the focus owner non-displayable | ||
| 797 | or non-focusable, initiates an automatic, forward focus traversal. | ||
| 798 | While hiding any ancestor, lightweight or heavyweight, will always | ||
| 799 | indirectly hide its children, only disabling a heavyweight ancestor | ||
| 800 | will disable its children. Thus, disabling a lightweight ancestor of | ||
| 801 | the focus owner does not automatically initiate a focus traversal. | ||
| 802 | <p> | ||
| 803 | If client code initiates a focus traversal, and there is no other | ||
| 804 | Component to focus, then the focus owner remains unchanged. If client | ||
| 805 | code initiates an automatic focus traversal by hiding the focus owner, | ||
| 806 | directly or indirectly, or by making the focus owner non-displayable or | ||
| 807 | non-focusable, and there is no other Component to focus, then the | ||
| 808 | global focus owner is cleared. If client code initiates an automatic | ||
| 809 | focus traversal by disabling the focus owner, directly or indirectly, | ||
| 810 | and there is no other Component to focus, then the focus owner remains | ||
| 811 | unchanged. | ||
| 812 | |||
| 813 | |||
| 814 | <a name="Focusability"></a> | ||
| 815 | <h3>Focusability</h3> | ||
| 816 | <p> | ||
| 817 | A focusable Component can become the focus owner ("focusability") and | ||
| 818 | participates in keyboard focus traversal ("focus traversability") with | ||
| 819 | a FocusTraversalPolicy. There is no separation of these two concepts; | ||
| 820 | a Component must either be both focusable and focus traversable, or | ||
| 821 | neither. | ||
| 822 | |||
| 823 | A Component expresses this state via the isFocusable() method. By | ||
| 824 | default, all Components return true from this method. Client code can | ||
| 825 | change this default by calling Component.setFocusable(boolean). | ||
| 826 | |||
| 827 | |||
| 828 | <a name="FocusableWindows"></a> | ||
| 829 | <h3>Focusable Windows</h3> | ||
| 830 | <p> | ||
| 831 | To support palette windows and input methods, client code can prevent | ||
| 832 | a Window from becoming the focused Window. By transitivity, this | ||
| 833 | prevents the Window or any of its descendants from becoming the focus | ||
| 834 | owner. Non-focusable Windows may still own Windows that are | ||
| 835 | focusable. By default, every Frame and Dialog is focusable. Every | ||
| 836 | Window which is not a Frame or Dialog, but whose nearest owning Frame | ||
| 837 | or Dialog is showing on the screen, and which has at least one | ||
| 838 | Component in its focus traversal cycle, is also focusable by | ||
| 839 | default. To make a Window non-focusable, use | ||
| 840 | Window.setFocusableWindowState(false). | ||
| 841 | <p> | ||
| 842 | If a Window is non-focusable, this restriction is enforced when the | ||
| 843 | <code>KeyboardFocusManager</code> sees a <code>WINDOW_GAINED_FOCUS</code> | ||
| 844 | event for the Window. At this point, the focus change is rejected and | ||
| 845 | focus is reset to a different Window. The rejection recovery scheme | ||
| 846 | is the same as if a <code>VetoableChangeListener</code> rejected the | ||
| 847 | focus change. See <a href="#FocusAndVetoableChangeListener">Focus | ||
| 848 | and VetoableChangeListener</a>. | ||
| 849 | <p> | ||
| 850 | Because the new focus implementation requires that KeyEvents intended | ||
| 851 | for a Window or its descendants be proxied through a child of the | ||
| 852 | Window's owner, and because this proxy must be mapped on X11 in order | ||
| 853 | to receive events, a Window whose nearest owning Frame or Dialog is | ||
| 854 | not showing could never receive KeyEvents on X11. To support this | ||
| 855 | restriction, we have made a distinction between a Window's "window | ||
| 856 | focusability" and its "window focusability state". A Window's | ||
| 857 | focusability state is combined with the showing state of the Window's | ||
| 858 | nearest owning Frame or Dialog to determine the Window's focusability. | ||
| 859 | By default, all Windows have a focusability state of true. Setting a | ||
| 860 | Window's focusability state to false ensures that it will not become | ||
| 861 | the focused Window regardless of the showing state of its nearest | ||
| 862 | owning Frame or Dialog. | ||
| 863 | <p> | ||
| 864 | Swing allows applications to create JWindows with null owners. Swing | ||
| 865 | constructs all such JWindows so that they are owned by a private, | ||
| 866 | hidden Frame. Because the showing state of this Frame will always be | ||
| 867 | false, a JWindow constructed will a null owner can never be the | ||
| 868 | focused Window, even if it has a Window focusability state of true. | ||
| 869 | <p> | ||
| 870 | If the focused Window is made non-focusable, then the AWT will attempt | ||
| 871 | to focus the most recently focused Component of the Window's | ||
| 872 | owner. The Window's owner will thus become the new focused Window. If | ||
| 873 | the Window's owner is also a non-focusable Window, then the focus | ||
| 874 | change request will proceed up the ownership hierarchy recursively. | ||
| 875 | Since not all platforms support cross-Window focus changes (see | ||
| 876 | <a href=#RequestingFocus>Requesting Focus</a>), it is possible that | ||
| 877 | all such focus change requests will fail. In this case, the global | ||
| 878 | focus owner will be cleared and the focused Window will remain unchanged. | ||
| 879 | |||
| 880 | <a name="RequestingFocus"></a> | ||
| 881 | <h3>Requesting Focus</h3> | ||
| 882 | |||
| 883 | <p> | ||
| 884 | A Component can request that it become the focus owner by calling | ||
| 885 | <code>Component.requestFocus()</code>. This initiates a permanent | ||
| 886 | focus transfer to the Component only if the Component is displayable, | ||
| 887 | focusable, visible and all of its ancestors (with the exception of the | ||
| 888 | top-level Window) are visible. The request will be immediately denied if | ||
| 889 | any of these conditions is not met. A disabled Component may be | ||
| 890 | the focus owner; however, in this case, all KeyEvents will be discarded. | ||
| 891 | <p> | ||
| 892 | The request will also be denied if the Component's top-level Window is | ||
| 893 | not the focused Window and the platform does not support requesting | ||
| 894 | focus across Windows. If the request is denied for this reason, the | ||
| 895 | request is remembered and will be granted when the Window is later | ||
| 896 | focused by the user. Otherwise, the focus change request changes the | ||
| 897 | focused Window as well. | ||
| 898 | <p> | ||
| 899 | There is no way to determine synchronously whether a focus change | ||
| 900 | request has been granted. Instead, client code must install a | ||
| 901 | FocusListener on the Component and watch for the delivery of a | ||
| 902 | <code>FOCUS_GAINED</code> event. Client code must not assume that | ||
| 903 | the Component is the focus owner until it receives this event. | ||
| 904 | The event may or may not be delivered before <code>requestFocus()</code> | ||
| 905 | returns. Developers must not assume one behavior or the other. | ||
| 906 | <p> | ||
| 907 | The AWT supports type-ahead if all focus change requests are made on | ||
| 908 | the EventDispatchThread. If client code requests a focus change, and | ||
| 909 | the AWT determines that this request might be granted by the native | ||
| 910 | windowing system, then the AWT will notify the current | ||
| 911 | KeyboardFocusManager that is should enqueue all KeyEvents with a | ||
| 912 | timestamp later than the that of the event currently being handled. | ||
| 913 | These KeyEvents will not be dispatched until the new Component becomes | ||
| 914 | the focus owner. The AWT will cancel the delayed dispatching request | ||
| 915 | if the focus change does not succeed at the native level, if the | ||
| 916 | Component's peer is disposed, or if the focus change is vetoed by a | ||
| 917 | VetoableChangeListener. KeyboardFocusManagers are not required to | ||
| 918 | support type-ahead if a focus change request is made from a thread | ||
| 919 | other than the EventDispatchThread. | ||
| 920 | <p> | ||
| 921 | Because <code>Component.requestFocus()</code> cannot be implemented | ||
| 922 | consistently across platforms, developers are encouraged to use | ||
| 923 | <code>Component.requestFocusInWindow()</code> instead. This method | ||
| 924 | denies cross-Window focus transfers on all platforms automatically. | ||
| 925 | By eliminating the only platform-specific element of the focus transfer, | ||
| 926 | this method achieves consistent cross-platform behavior. | ||
| 927 | <p> | ||
| 928 | In addition, <code>requestFocusInWindow()</code> returns a boolean value. | ||
| 929 | If 'false' is returned, the request is guaranteed to fail. If 'true' is | ||
| 930 | returned, the request will succeed unless it is vetoed, or an | ||
| 931 | extraordinary event, such as disposal of the Component's peer, occurs | ||
| 932 | before the request can be granted by the native windowing | ||
| 933 | system. Again, while a return value of 'true' indicates that the | ||
| 934 | request is likely to succeed, developers must never assume that this | ||
| 935 | Component is the focus owner until this Component receives a | ||
| 936 | <code>FOCUS_GAINED</code> event. | ||
| 937 | <p> | ||
| 938 | If client code wants no Component in the application to be the focus | ||
| 939 | owner, it can call the method <code>KeyboardFocusManager</code>. | ||
| 940 | <code>clearGlobalFocusOwner()</code> on the current | ||
| 941 | <code>KeyboardFocusManager</code>. If there exists a focus owner | ||
| 942 | when this method is called, the focus owner will receive a permanent | ||
| 943 | <code>FOCUS_LOST</code> event. After this point, the AWT | ||
| 944 | focus implementation will discard all KeyEvents until the user or | ||
| 945 | client code explicitly sets focus to a Component. | ||
| 946 | <p> | ||
| 947 | The Component class also supports variants of <code>requestFocus</code> and | ||
| 948 | <code>requestFocusInWindow</code> that allow client code to specify | ||
| 949 | a temporary state. | ||
| 950 | See <a href="#TemporaryFocusEvents">Temporary FocusEvents</a> | ||
| 951 | |||
| 952 | <a name="FocusAndPropertyChangeListener"></a> | ||
| 953 | <h3>Focus and PropertyChangeListener</h3> | ||
| 954 | <p> | ||
| 955 | Client code can listen to changes in context-wide focus state, or to | ||
| 956 | changes in focus-related state in Components, via | ||
| 957 | PropertyChangeListeners. | ||
| 958 | <p> | ||
| 959 | The <code>KeyboardFocusManager</code> supports the following properties: | ||
| 960 | |||
| 961 | <ol> | ||
| 962 | <li><code>focusOwner</code>: the focus owner | ||
| 963 | <li><code>focusedWindow</code>: the focused Window | ||
| 964 | <li><code>activeWindow</code>: the active Window | ||
| 965 | <li><code>defaultFocusTraversalPolicy</code>: the default focus | ||
| 966 | traversal policy | ||
| 967 | <li><code>forwardDefaultFocusTraversalKeys</code>: the Set of default | ||
| 968 | <code>FORWARD_TRAVERSAL_KEYS</code> | ||
| 969 | <li><code>backwardDefaultFocusTraversalKeys</code>: the Set of default | ||
| 970 | <code>BACKWARD_TRAVERSAL_KEYS</code> | ||
| 971 | <li><code>upCycleDefaultFocusTraversalKeys</code>: the Set of default | ||
| 972 | <code>UP_CYCLE_TRAVERSAL_KEYS</code> | ||
| 973 | <li><code>downCycleDefaultFocusTraversalKeys</code>: the Set of default | ||
| 974 | <code>DOWN_CYCLE_TRAVERSAL_KEYS</code> | ||
| 975 | <li><code>currentFocusCycleRoot</code>: the current focus cycle root | ||
| 976 | </ol> | ||
| 977 | <p> | ||
| 978 | A <code>PropertyChangeListener</code> installed on the current | ||
| 979 | <code>KeyboardFocusManager</code> will only see these changes within | ||
| 980 | the <code>KeyboardFocusManager</code>'s context, even though the | ||
| 981 | focus owner, focused Window, active Window, and current focus cycle | ||
| 982 | root comprise the global focus state shared by all contexts. | ||
| 983 | We believe this is less intrusive than requiring client code to pass | ||
| 984 | a security check before installing a <code>PropertyChangeListener</code>. | ||
| 985 | <p> | ||
| 986 | Component supports the following focus-related properties: | ||
| 987 | |||
| 988 | <ol> | ||
| 989 | <li><code>focusable</code>: the Component's focusability | ||
| 990 | <li><code>focusTraversalKeysEnabled</code>: the Component's | ||
| 991 | focus traversal keys enabled state | ||
| 992 | <li><code>forwardFocusTraversalKeys</code>: the Component's Set of | ||
| 993 | <code>FORWARD_TRAVERSAL_KEYS</code> | ||
| 994 | <li><code>backwardFocusTraversalKeys</code>: the Component's Set of | ||
| 995 | <code>BACKWARD_TRAVERSAL_KEYS</code> | ||
| 996 | <li><code>upCycleFocusTraversalKeys</code>: the Component's Set of | ||
| 997 | <code>UP_CYCLE_TRAVERSAL_KEYS</code> | ||
| 998 | </ol> | ||
| 999 | <p> | ||
| 1000 | In addition to the Component properties, Container supports the | ||
| 1001 | following focus-related properties: | ||
| 1002 | |||
| 1003 | <ol> | ||
| 1004 | <li><code>downCycleFocusTraversalKeys</code>: the Container's Set of | ||
| 1005 | <code>DOWN_CYCLE_TRAVERSAL_KEYS</code> | ||
| 1006 | <li><code>focusTraversalPolicy</code>: the Container's focus | ||
| 1007 | traversal policy | ||
| 1008 | <li><code>focusCycleRoot</code>: the Container's focus-cycle-root state | ||
| 1009 | </ol> | ||
| 1010 | <p> | ||
| 1011 | In addition to the Container properties, Window supports the following | ||
| 1012 | focus-related property: | ||
| 1013 | |||
| 1014 | <ol> | ||
| 1015 | <li><code>focusableWindow</code>: the Window's focusable Window state | ||
| 1016 | </ol> | ||
| 1017 | <p> | ||
| 1018 | Also note that a <code>PropertyChangeListener</code> installed on a | ||
| 1019 | Window will never see a <code>PropertyChangeEvent</code> for the | ||
| 1020 | <code>focusCycleRoot</code> property. | ||
| 1021 | A Window is always a focus cycle root; this property cannot change. | ||
| 1022 | <p> | ||
| 1023 | <a name="FocusAndVetoableChangeListener"></a> | ||
| 1024 | <h3>Focus and VetoableChangeListener</h3> | ||
| 1025 | <p> | ||
| 1026 | The <code>KeyboardFocusManager</code> also supports | ||
| 1027 | <code>VetoableChangeListener</code>s for the following properties: | ||
| 1028 | |||
| 1029 | <ol> | ||
| 1030 | <li>"focusOwner": the focus owner | ||
| 1031 | <li>"focusedWindow": the focused Window | ||
| 1032 | <li>"activeWindow": the active Window | ||
| 1033 | </ol> | ||
| 1034 | |||
| 1035 | If a VetoableChangeListener vetoes a focus or activation change by | ||
| 1036 | throwing a PropertyVetoException, the change is aborted. Any | ||
| 1037 | VetoableChangeListeners which had already approved the change will | ||
| 1038 | asynchronously receive PropertyChangeEvents indicating a reversion of | ||
| 1039 | state to the previous value. | ||
| 1040 | <p> | ||
| 1041 | VetoableChangeListeners are notified of the state change before the | ||
| 1042 | change is reflected in the KeyboardFocusManager. Conversely, | ||
| 1043 | PropertyChangeListeners are notified after the change is reflected. | ||
| 1044 | It follows that all VetoableChangeListeners will be notified before | ||
| 1045 | any PropertyChangeListener. | ||
| 1046 | <p> | ||
| 1047 | VetoableChangeListeners must be idempotent, and must veto both loss | ||
| 1048 | and gain events for a particular focus change (e.g., both | ||
| 1049 | <code>FOCUS_LOST</code> and <code>FOCUS_GAINED</code>). For example, | ||
| 1050 | if a <code>VetoableChangeListener</code> vetoes a <code>FOCUS_LOST</code> | ||
| 1051 | event, a <code>KeyboardFocusManager</code> is not required to search the | ||
| 1052 | <code>EventQueue</code> and remove the associated pending | ||
| 1053 | <code>FOCUS_GAINED</code> event. Instead, the | ||
| 1054 | <code>KeyboardFocusManager</code> is free to attempt to | ||
| 1055 | dispatch this event and it is the responsibility of the | ||
| 1056 | <code>VetoableChangeListener</code> to veto it as well. In addition, | ||
| 1057 | during processing of the <code>FOCUS_GAINED</code> event, the | ||
| 1058 | <code>KeyboardFocusManager</code> may attempt to resync the global | ||
| 1059 | focus state by synthesizing another <code>FOCUS_LOST</code> event. | ||
| 1060 | This event must be vetoed just as the first <code>FOCUS_LOST</code> event was. | ||
| 1061 | <p> | ||
| 1062 | A <code>KeyboardFocusManager</code> may not hold any locks while | ||
| 1063 | notifying <code>PropertyChangeListener</code>s of a state change. | ||
| 1064 | This requirement is relaxed for <code>VetoableChangeListeners</code>, | ||
| 1065 | however. Therefore, client-definied <code>VetoableChangeListener</code>s | ||
| 1066 | should avoid acquiring additional locks inside | ||
| 1067 | <code>vetoableChange(PropertyChangeEvent)</code> as this may lead to deadlock. | ||
| 1068 | |||
| 1069 | If a focus or activation change is rejected, the KeyboardFocusManager | ||
| 1070 | will initiate rejection recovery as follows: | ||
| 1071 | |||
| 1072 | <ul> | ||
| 1073 | <li>If a focused or active Window change was rejected, then the | ||
| 1074 | focused or active Window will be reset to the Window which was | ||
| 1075 | previously the focused or active Window. If there is no such | ||
| 1076 | Window, then the <code>KeyboardFocusManager</code> will clear | ||
| 1077 | the global focus owner. | ||
| 1078 | <li>If a focus owner change was rejected, then the focus owner will be | ||
| 1079 | reset to the Component which was previously the focus owner. If | ||
| 1080 | that is not possible, then it will be reset to the next Component | ||
| 1081 | in the focus traversal cycle after the previous focus owner. If | ||
| 1082 | that is also not possible, then the <code>KeyboardFocusManager</code> | ||
| 1083 | will clear the global focus owner. | ||
| 1084 | </ul> | ||
| 1085 | |||
| 1086 | <code>VetoableChangeListener</code>s must be careful to avoid vetoing focus | ||
| 1087 | changes initiated as a result of veto rejection recovery. Failure | ||
| 1088 | to anticipate this situation could lead to an infinite cycle of | ||
| 1089 | vetoed focus changes and recovery attempts. | ||
| 1090 | |||
| 1091 | |||
| 1092 | <a name="ZOrder"></a> | ||
| 1093 | <h3>Z-Order</h3> | ||
| 1094 | <p> | ||
| 1095 | On some native windowing systems, the Z-order of a Window can affect | ||
| 1096 | its focused or active (if applicable) state. On Microsoft Windows, the | ||
| 1097 | top-most Window is naturally the focused Window as well. However, on | ||
| 1098 | Solaris, many window managers use a point-to-focus model that ignores | ||
| 1099 | Z-order in determining the focused Window. | ||
| 1100 | |||
| 1101 | When focusing or activating Windows, the AWT adheres to the UI | ||
| 1102 | requirements of the native platform. Therefore, the focus behavior of | ||
| 1103 | Z-order-related methods such as: | ||
| 1104 | <ul> | ||
| 1105 | <li><code>Window.toFront()</code> | ||
| 1106 | <li><code>Window.toBack()</code> | ||
| 1107 | <li><code>Window.show()</code> | ||
| 1108 | <li><code>Window.hide()</code> | ||
| 1109 | <li><code>Window.setVisible(boolean)</code> | ||
| 1110 | <li><code>Window.dispose()</code> | ||
| 1111 | <li><code>Frame.setState(int)</code> | ||
| 1112 | </ul> | ||
| 1113 | is platform-dependent. In JDK 1.4, the behavior of these methods on | ||
| 1114 | Microsoft Windows and Solaris is as follows: | ||
| 1115 | <ul> | ||
| 1116 | <li><code>Window.toFront()</code>:<br> | ||
| 1117 | <b>Microsoft Windows</b>: The Window is moved to front, if possible. | ||
| 1118 | While we will always be able to move this Window in front of other | ||
| 1119 | Windows in the same VM, Windows 98 and Windows 2000 do not allow an | ||
| 1120 | application to bring any of its windows to the front unless one | ||
| 1121 | of that application's windows is already in the foreground. In | ||
| 1122 | this case, Windows will instead flash the Window's icon in the | ||
| 1123 | taskbar. If the Window is moved to the front, it will be made | ||
| 1124 | the focused and (if applicable) active Window. | ||
| 1125 | <br> | ||
| 1126 | <b>Solaris</b>: The Window is moved to front. In a point-to-focus | ||
| 1127 | window manager, the Window will become the focused Window if it | ||
| 1128 | is the top-most Window underneath the cursor. In a click-to-focus | ||
| 1129 | window manager, the focused Window will remain unchanged. | ||
| 1130 | |||
| 1131 | <li><code>Window.toBack()</code>:<br> | ||
| 1132 | <b>Microsoft Windows</b>: The Window is moved to back. Note however | ||
| 1133 | that Microsoft Windows insists that an owned Window always be in | ||
| 1134 | front of all of its recursive owners. Thus, after the completion of | ||
| 1135 | this operation, the Window may not be the lowest Java Window in the | ||
| 1136 | Z-order. If the Window, or any of its owners, was the focused Window, | ||
| 1137 | then the focused Window is reset to the top-most Window in the VM. | ||
| 1138 | <br> | ||
| 1139 | <b>Solaris</b>: The Window is moved to back. Like Microsoft Windows, | ||
| 1140 | some window managers insist than an owned Window always be in front | ||
| 1141 | of all of its recursive owners. Thus, after the completion of this | ||
| 1142 | operation, the Window may not be the lowest Java Window in the | ||
| 1143 | Z-order. If the Window was the focused Window, it will lose | ||
| 1144 | focus in a point-to-focus window manager if it is no longer the | ||
| 1145 | top-most Window under the cursor. In a click-to-focus window | ||
| 1146 | manager, the focused Window will remain unchanged. | ||
| 1147 | |||
| 1148 | <li><code>Window.show()/Window.setVisible(true)/Frame.setState(NORMAL)</code>:<br> | ||
| 1149 | <b>Microsoft Windows</b>: The Window is moved to front and becomes the focused | ||
| 1150 | Window. | ||
| 1151 | <br> | ||
| 1152 | </b>Solaris</b>: The Window is moved to front. In a point-to-focus focus | ||
| 1153 | window manager, the Window will be focused if it is now the | ||
| 1154 | top-most Window under the cursor. In a click-to-focus window | ||
| 1155 | manager, the Window will become the focused Window. | ||
| 1156 | |||
| 1157 | <li><code>Window.hide()/Window.setVisible(false)/Window.dispose()/ | ||
| 1158 | Frame.setState(ICONIFIED)</code>:<br> | ||
| 1159 | <b>Microsoft Windows</b>: If the Window was the focused Window, the focused | ||
| 1160 | Window is reset to a window chosen by the OS, or to no window. The | ||
| 1161 | window may be in a native application, or a Java application in | ||
| 1162 | another VM. | ||
| 1163 | <br> | ||
| 1164 | <b>Solaris</b>: If the Window was the focused Window, in a point-to- | ||
| 1165 | focus window manager, the top-most Window under the cursor will | ||
| 1166 | become the focused Window. In a click-to-focus window manager, | ||
| 1167 | the focused Window is reset to a window chosen by the window | ||
| 1168 | manager. The window may be in a native application, or a Java | ||
| 1169 | application in another VM. | ||
| 1170 | </ul> | ||
| 1171 | |||
| 1172 | <a name="ReplacingDefaultKeyboardFocusManager"></a> | ||
| 1173 | <h3>Replacing DefaultKeyboardFocusManager</h3> | ||
| 1174 | <p> | ||
| 1175 | <code>KeyboardFocusManager</code>s are pluggable at the browser context | ||
| 1176 | level. Client code can subclass <code>KeyboardFocusManager</code> or | ||
| 1177 | <code>DefaultKeyboardFocusManager</code> to modify the way that WindowEvents | ||
| 1178 | related to focus, FocusEvents, and KeyEvents are handled and | ||
| 1179 | dispatched, and to examine and modify the global focus state. A custom | ||
| 1180 | <code>KeyboardFocusManager</code> can also reject focus changes at a more | ||
| 1181 | fundamental level then a FocusListener or WindowListener ever could. | ||
| 1182 | <p> | ||
| 1183 | While giving a developer ultimate control over the focus model, | ||
| 1184 | replacing the entire <code>KeyboardFocusManager</code> is a difficult process | ||
| 1185 | requiring a thorough understanding of the peer focus layer. | ||
| 1186 | Fortunately, most applications do not need this much control. | ||
| 1187 | Developers are encouraged to use KeyEventDispatchers, | ||
| 1188 | KeyEventPostProcessors, FocusTraversalPolicies, | ||
| 1189 | VetoableChangeListeners, and other concepts discussed in this document | ||
| 1190 | before resorting to a full replacement of the <code>KeyboardFocusManager</code>. | ||
| 1191 | <p> | ||
| 1192 | First note that, because unhindered access to Components in other | ||
| 1193 | contexts represents a security hole, the SecurityManager must grant a | ||
| 1194 | new permission, "replaceKeyboardFocusManager", before client code is | ||
| 1195 | permitted to replace the <code>KeyboardFocusManager</code> with an arbitrary | ||
| 1196 | subclass instance. Because of the security check, replacing the | ||
| 1197 | <code>KeyboardFocusManager</code> is not an option for applications that will be | ||
| 1198 | deployed in environments with a SecurityManager, such as applets in a | ||
| 1199 | browser. | ||
| 1200 | <p> | ||
| 1201 | Once installed, a <code>KeyboardFocusManager</code> instance has | ||
| 1202 | access to the global focus state via a set of protected functions. | ||
| 1203 | The <code>KeyboardFocusManager</code> can only call these functions | ||
| 1204 | if it is installed in the calling thread's context. This ensures | ||
| 1205 | that malicious code cannot circumvent the security check in | ||
| 1206 | <code>KeyboardFocusManager.setCurrentFocusManager</code>. | ||
| 1207 | A <code>KeyboardFocusManager</code> should always work with | ||
| 1208 | the global focus state instead of the context focus state. | ||
| 1209 | Failure to do this will lead to incorrect behavior of the | ||
| 1210 | <code>KeyboardFocusManager</code>. | ||
| 1211 | <p> | ||
| 1212 | The primary responsibility of a <code>KeyboardFocusManager</code> | ||
| 1213 | is the dispatch of the following events: | ||
| 1214 | |||
| 1215 | <ul> | ||
| 1216 | <li>all <code>KeyEvent</code>s | ||
| 1217 | <li>all <code>FocusEvent</code>s | ||
| 1218 | <li><code>WindowEvent.WINDOW_GAINED_FOCUS</code> | ||
| 1219 | <li><code>WindowEvent.WINDOW_LOST_FOCUS</code> | ||
| 1220 | <li><code>WindowEvent.WINDOW_ACTIVATED</code> | ||
| 1221 | <li><code>WindowEvent.WINDOW_DEACTIVATED</code> | ||
| 1222 | </ul> | ||
| 1223 | |||
| 1224 | The peer layer will provide the <code>KeyboardFocusManager</code> | ||
| 1225 | with all of the above events except <code>WINDOW_ACTIVATED</code> | ||
| 1226 | and <code>WINDOW_DEACTIVATED</code>. The <code>KeyboardFocusManager</code> | ||
| 1227 | must synthesize <code>WINDOW_ACTIVATED</code> and | ||
| 1228 | <code>WINDOW_DEACTIVATED</code> events when appropriate and target them | ||
| 1229 | accordingly. | ||
| 1230 | <p> | ||
| 1231 | The <code>KeyboardFocusManager</code> may need to retarget the events | ||
| 1232 | provided by the peer layer to its own notion of the focus owner or | ||
| 1233 | focused Window: | ||
| 1234 | <ul> | ||
| 1235 | <li>A KeyEvent must be retargeted to the focus owner. Because the peer | ||
| 1236 | layer is unaware of any lightweight Components, KeyEvents will | ||
| 1237 | arrive from the peer layer targeted to the focus owner's | ||
| 1238 | heavyweight Container, not the focus owner. | ||
| 1239 | <li>A <code>FOCUS_LOST</code> event must be retargeted to the focus | ||
| 1240 | owner. Again, this is necessary because the peer layer is | ||
| 1241 | unaware of lightweight Components. | ||
| 1242 | <li>A <code>WINDOW_LOST_FOCUS</code> event must be retargeted to | ||
| 1243 | the focused Window. The implementation of the Window class | ||
| 1244 | may cause the native focused Window to differ from the Java | ||
| 1245 | focused Window. | ||
| 1246 | </ul> | ||
| 1247 | <p> | ||
| 1248 | A <code>KeyboardFocusManager</code> must ensure proper event ordering, | ||
| 1249 | and a 1-to-1 correspondence between an event and its opposite event type. | ||
| 1250 | The peer layer does not make any of these guarantees. For example, it is | ||
| 1251 | possible for the peer layer to send a <code>FOCUS_GAINED</code> | ||
| 1252 | event before a <code>WINDOW_GAINED_FOCUS</code> event. | ||
| 1253 | The <code>KeyboardFocusManager</code> is responsible for | ||
| 1254 | ensuring that the <code>WINDOW_GAINED_FOCUS</code> event is dispatched | ||
| 1255 | before the <code>FOCUS_GAINED</code> event. | ||
| 1256 | <p> | ||
| 1257 | Before redispatching an event via <code>KeyboardFocusManager</code>. | ||
| 1258 | <code>redispatchEvent</code>, a <code>KeyboardFocusManager</code> | ||
| 1259 | must attempt to update the global focus state. Typically, this | ||
| 1260 | is done using one of the <code>KeyboardFocusManager.setGlobal*</code> | ||
| 1261 | methods; however, an implementation is free to implement its own methods. | ||
| 1262 | After attempting an update, the <code>KeyboardFocusManager</code> | ||
| 1263 | must verify that the global focus state change | ||
| 1264 | was not rejected. A rejection is detected when a call to the | ||
| 1265 | corresponding <code>getGlobal*</code> method returns a value different than the | ||
| 1266 | value just set. Rejections occur in three standard cases: | ||
| 1267 | <ul> | ||
| 1268 | <li>If the <code>KeyboardFocusManager</code> attempts | ||
| 1269 | to set the global focus owner to a non-focusable Component. | ||
| 1270 | <li>If the <code>KeyboardFocusManager</code> attempts | ||
| 1271 | to set the global focused Window to a non-focusable Window. | ||
| 1272 | <li>If the change is rejected by an installed | ||
| 1273 | <code>VetoableChangeListener</code>. | ||
| 1274 | </ul> | ||
| 1275 | <p> | ||
| 1276 | Client-defined implementations of <code>KeyboardFocusManager</code> | ||
| 1277 | can adjust the set of focus transfers which are rejected by overriding the | ||
| 1278 | accessor and mutator methods for the global focus state. | ||
| 1279 | <p> | ||
| 1280 | If a request to change the global focus state is rejected, the | ||
| 1281 | <code>KeyboardFocusManager</code> must discard the event which prompted | ||
| 1282 | the focus change request. The Component to which the event was targeted | ||
| 1283 | must not receive the event. | ||
| 1284 | <p> | ||
| 1285 | The <code>KeyboardFocusManager</code> is also expected to initiate rejection | ||
| 1286 | recovery as outlined in <a href="#FocusAndVetoableChangeListener">Focus | ||
| 1287 | and VetoableChangeListener</a>. | ||
| 1288 | <p> | ||
| 1289 | Finally, a KeyboardFocusManager must handle the following set of | ||
| 1290 | special cases: | ||
| 1291 | <ul> | ||
| 1292 | <li>When handling a <code>WINDOW_GAINED_FOCUS</code> event, the | ||
| 1293 | <code>KeyboardFocusManager</code> must set focus to the | ||
| 1294 | appropriate child Component of the Window. If a child | ||
| 1295 | Component of the Window previously requested focus, | ||
| 1296 | but the focus change was rejected because the platform | ||
| 1297 | does not support cross-Window focus change requests, | ||
| 1298 | then focus should be set to that child Component. | ||
| 1299 | Otherwise, if the Window has never been focused, focus should be | ||
| 1300 | set to the Window's initial Component to focus. If the Window was | ||
| 1301 | previously focused, focus should be set to the Window's most | ||
| 1302 | recent focus owner. | ||
| 1303 | <li>The <code>KeyboardFocusManager</code> must ensure that the | ||
| 1304 | opposite Component or Window are as accurate as the native | ||
| 1305 | windowing platform permits. For example, the | ||
| 1306 | <code>KeyboardFocusManager</code> may need to | ||
| 1307 | retarget the opposite Component to a lightweight child of the | ||
| 1308 | heavyweight initially specified by the peer layer. | ||
| 1309 | <br> | ||
| 1310 | If the peer layer states that the opposite Component or Window is | ||
| 1311 | <code>null</code>, it is acceptable for the | ||
| 1312 | <code>KeyboardFocusManager</code> to propagate | ||
| 1313 | this value. <code>null</code> indicates that it is highly | ||
| 1314 | probably that no other Component or Window was involved | ||
| 1315 | in the focus or activation change. Because of platform | ||
| 1316 | limitations, this computation may be | ||
| 1317 | subject to a heuristic and could be incorrect. Nevertheless, this | ||
| 1318 | heuristic will be the best possible guess which the peer layer | ||
| 1319 | could make. | ||
| 1320 | <li>Focus and activation changes in which a Component or Window loses | ||
| 1321 | focus or activation to itself must be discarded. | ||
| 1322 | <li>Events posted by the peer layer claiming that the active Window | ||
| 1323 | has lost focus to the focused Window must be discarded. The peer | ||
| 1324 | implementation of the Window class may generate these spurious | ||
| 1325 | events. | ||
| 1326 | </ul> | ||
| 1327 | |||
| 1328 | <a name="Incompatibilities"></a> | ||
| 1329 | <h3>Incompatibilities with Previous Releases</h3> | ||
| 1330 | <p><b>Cross-platform changes:</b> | ||
| 1331 | <ol> | ||
| 1332 | <li>The default focus traversability for all Components is now | ||
| 1333 | 'true'. Previously, some Components (in particular, all | ||
| 1334 | lightweights), had a default focus traversability of 'false'. Note | ||
| 1335 | that despite this change, however, the | ||
| 1336 | <code>DefaultFocusTraversalPolicy</code> for all AWT Containers | ||
| 1337 | will preserve the traversal order of previous releases. | ||
| 1338 | <li>A request to focus a non-focus traversable (i.e., non-focusable) | ||
| 1339 | Component will be denied. Previously, such requests were granted. | ||
| 1340 | <li><code>Window.toFront()</code> and <code>Window.toBack()</code> | ||
| 1341 | now perform no operation if the Window is not visible. | ||
| 1342 | Previously, the behavior was platform-dependent. | ||
| 1343 | <li>KeyListeners installed on <code>Component</code>s | ||
| 1344 | will no longer see <code>KeyEvent</code>s that map to focus | ||
| 1345 | traversal operations, and | ||
| 1346 | <code>Component.handleEvent()</code> will no longer be invoked | ||
| 1347 | for such events. Previously, AWT Components saw these events | ||
| 1348 | and had an opportunity to consume them before AWT | ||
| 1349 | initiated focus traversal. Code that requires this | ||
| 1350 | functionality should instead disable focus traversal keys on | ||
| 1351 | its <code>Component</code>s and handle focus traversal | ||
| 1352 | itself. Alternately, the code can use an | ||
| 1353 | <code>AWTEventListener</code> or | ||
| 1354 | <code>KeyEventDispatcher</code> to pre-listen to all | ||
| 1355 | <code>KeyEvent</code>s. | ||
| 1356 | </ol> | ||
| 1357 | <p><b>Changes specific to Microsoft Windows:</b> | ||
| 1358 | <ol> | ||
| 1359 | <li><code>Window.toBack()</code> changes the focused Window to | ||
| 1360 | the top-most Window after the Z-order change. | ||
| 1361 | <li><code>requestFocus()</code> now allows cross-Window focus | ||
| 1362 | change requests in all cases. Previously, requests were granted | ||
| 1363 | for heavyweights, but denied for lightweights. | ||
| 1364 | </ol> | ||
| 1365 | |||
| 1366 | </body> | ||
| 1367 | </html> | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,472 @@ | |||
| 1 | <!-- | ||
| 2 | Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | |||
| 5 | This code is free software; you can redistribute it and/or modify it | ||
| 6 | under the terms of the GNU General Public License version 2 only, as | ||
| 7 | published by the Free Software Foundation. Oracle designates this | ||
| 8 | particular file as subject to the "Classpath" exception as provided | ||
| 9 | by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | |||
| 11 | This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | accompanied this code). | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License version | ||
| 18 | 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | |||
| 21 | Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | or visit www.oracle.com if you need additional information or have any | ||
| 23 | questions. | ||
| 24 | --> | ||
| 25 | |||
| 26 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> | ||
| 27 | |||
| 28 | <html> | ||
| 29 | |||
| 30 | <head> | ||
| 31 | |||
| 32 | <title>The AWT Modality</title> | ||
| 33 | |||
| 34 | </head> | ||
| 35 | |||
| 36 | <body bgcolor="white"> | ||
| 37 | |||
| 38 | <h1 align="center">The AWT Modality</h1> | ||
| 39 | |||
| 40 | <p> | ||
| 41 | This document, together with the API documentation for modality-related | ||
| 42 | classes (such as <code>java.awt.Dialog</code>), briefly describes the new | ||
| 43 | modality features and how to use them. It contains the following sections: | ||
| 44 | </p><ul> | ||
| 45 | <li><a href="#Definitions">Definitions</a></li> | ||
| 46 | </li><li><a href="#ModalityTypes">Modality types</a></li> | ||
| 47 | <li><a href="#ShowHideBlocking">Show/hide blocking</a></li> | ||
| 48 | <li><a href="#ModalExclusion">Modal exclusion</a></li> | ||
| 49 | <li><a href="#Related">Related AWT features</a></li> | ||
| 50 | <li><a href="#Security">Security</a></li> | ||
| 51 | <li><a href="#PlatformSupport">Platform support</a></li> | ||
| 52 | <li><a href="#Compatibility">Compatibility</a></li> | ||
| 53 | <li><a href="#Examples">Examples</a></li> | ||
| 54 | </ul> | ||
| 55 | |||
| 56 | <a name="Definitions"></a> | ||
| 57 | </p><h3>Definitions</h3> | ||
| 58 | |||
| 59 | <p> | ||
| 60 | <u>Document</u> - a window without an owner that, together with | ||
| 61 | all its child hierarchy, may be operated on as a single self-contained | ||
| 62 | document. | ||
| 63 | Every window belongs to some document — its root can be found as | ||
| 64 | the closest ancestor window without an owner. | ||
| 65 | </p><p> | ||
| 66 | <a name="ModalBlocked"></a> | ||
| 67 | <u>Modal blocked window</u> - a window, that: | ||
| 68 | </p><ul> | ||
| 69 | <li>doesn't receive any user input events | ||
| 70 | </li><li>doesn't receive input focus | ||
| 71 | </li><li>keeps its Z-order below the modal dialog that blocks it | ||
| 72 | </li></ul> | ||
| 73 | <blockquote> | ||
| 74 | <hr> | ||
| 75 | <b>Warning!</b> Some window managers allow users to change the window | ||
| 76 | Z-order in an arbitrary way — in that case the last requirement | ||
| 77 | may not be met. | ||
| 78 | <hr> | ||
| 79 | </blockquote> | ||
| 80 | <p> | ||
| 81 | <u>Modal dialog</u> - a dialog that blocks some windows while it is | ||
| 82 | visible. The blocked windows are determined according to the dialog's | ||
| 83 | scope of blocking. | ||
| 84 | </p><p> | ||
| 85 | <u>Modal excluded window</u> - a window that stays unblocked | ||
| 86 | while the modal dialog is visible. If a window is modal excluded | ||
| 87 | then all its owned windows and child components are also excluded. | ||
| 88 | </p><p> | ||
| 89 | <u>Scope of blocking (SB)</u> - the set of windows (instances of | ||
| 90 | <code>java.awt.Window</code> and all derived classes) that are blocked by | ||
| 91 | the modal dialog while it is visible. | ||
| 92 | </p><p> | ||
| 93 | <blockquote><hr> | ||
| 94 | <b>Note</b>: Everywhere in this document the notion of "window" is equal | ||
| 95 | to a top-level window in the Java programming language — in other words | ||
| 96 | an instance of <code>java.awt.Window</code> or any descendant class. | ||
| 97 | <hr></blockquote> | ||
| 98 | |||
| 99 | <a name="ModalityTypes"></a> | ||
| 100 | </p><h3>Modality types</h3> | ||
| 101 | |||
| 102 | <p> | ||
| 103 | There are four supported modality types : | ||
| 104 | </p><ul> | ||
| 105 | <li>toolkit | ||
| 106 | </li><li>application | ||
| 107 | </li><li>document | ||
| 108 | </li><li>modeless | ||
| 109 | </li></ul> | ||
| 110 | A dialog is, by default, modeless. A modal dialog is, by default, | ||
| 111 | application-modal. | ||
| 112 | <p> | ||
| 113 | </p><ol> | ||
| 114 | <li><u>Modeless dialogs</u><br> | ||
| 115 | A modeless dialog doesn't block any windows while visible. | ||
| 116 | </li><li><u>Document-modal dialogs</u><br> | ||
| 117 | A document-modal dialog blocks all windows from the same | ||
| 118 | document except those from its child hierarchy. The document root | ||
| 119 | is determined as the closest ancestor window without an | ||
| 120 | owner. | ||
| 121 | </li><li><u>Application-modal dialogs</u><br> | ||
| 122 | An application-modal dialog blocks all windows from the same | ||
| 123 | application except for those from its child hierarchy. | ||
| 124 | If there are several applets launched in a browser, they can be | ||
| 125 | treated either as separate applications or a single application. | ||
| 126 | This behavior is implementation-dependent. | ||
| 127 | </li><li><u>Toolkit-modal dialogs</u><br> | ||
| 128 | A toolkit-modal dialog blocks all windows that run in the same | ||
| 129 | toolkit except those from its child hierarchy. If there | ||
| 130 | are several applets launched all of them run with the same toolkit, | ||
| 131 | so a toolkit-modal dialog shown from an applet may affect other | ||
| 132 | applets and all windows of the browser instance which embeds the | ||
| 133 | Java runtime environment for this toolkit. | ||
| 134 | See the security section below. | ||
| 135 | </li></ol> | ||
| 136 | <p> | ||
| 137 | Modality priority is arranged by the strength of blocking: modeless, | ||
| 138 | document-modal, application-modal and toolkit-modal. This arrangement | ||
| 139 | is used when determining what dialog should remain unblocked if two | ||
| 140 | are visible and block each other. It naturally reflects the nesting | ||
| 141 | of a dialog's scope of blocking (SB): a modeless dialog has an empty SB, | ||
| 142 | a document-modal dialog's SB is complete in some applications, | ||
| 143 | and all the applications are run in one toolkit. </p><p> | ||
| 144 | Notes about owners: | ||
| 145 | </p><ul> | ||
| 146 | <li>Creating a document-modal dialog without an owner:<br> | ||
| 147 | Since <code>Dialog</code> is a class derived from | ||
| 148 | <code>Window</code>, a <code>Dialog</code> instance automatically | ||
| 149 | becomes the root of the document if it has no owner. Thus, if | ||
| 150 | such a dialog is document-modal, its scope of blocking is empty | ||
| 151 | and it behaves the same way as a modeless dialog. | ||
| 152 | </li><li>Creating an application-modal or toolkit-modal dialog with an | ||
| 153 | owner:<br> | ||
| 154 | The scope of blocking for an application- or toolkit-modal | ||
| 155 | dialog, as opposed to a document-modal dialog, doesn't depend on | ||
| 156 | its owner. Thus, in this case the only thing that the owner | ||
| 157 | affects is the Z-order: the dialog always stays on top of its owner. | ||
| 158 | </li></ul> | ||
| 159 | <p> | ||
| 160 | <blockquote><hr> | ||
| 161 | <b>Implementation note</b>: Changing the modality type for a visible | ||
| 162 | dialog may have no effect until it is hidden and then shown again. | ||
| 163 | <hr></blockquote> | ||
| 164 | |||
| 165 | <a name="ShowHideBlocking"></a> | ||
| 166 | </p><h3>Show/hide blocking</h3> | ||
| 167 | |||
| 168 | <p> | ||
| 169 | <u>Showing the window or modeless dialog: "F"</u><br> | ||
| 170 | All the visible modal dialogs are looked through — if F is from the SB | ||
| 171 | of one of them, it becomes blocked by it. If there are several such | ||
| 172 | dialogs, the first shown is used. If no such dialogs exist, F remains | ||
| 173 | unblocked. | ||
| 174 | </p><p> | ||
| 175 | <u>Showing the modal dialog: "M"</u><br> | ||
| 176 | When modal dialog M is shown, all the visible windows fall into one of | ||
| 177 | three distinct groups: | ||
| 178 | <ul> | ||
| 179 | <li>Blockers of M (modal dialogs that block M and | ||
| 180 | either are in M's child hierarchy, or are not blocked by M, or have | ||
| 181 | a greater mode of modality, or block some other blocker of M) | ||
| 182 | <li>Blocked by M (windows from M's SB that are not blockers and are | ||
| 183 | not in child hierarchy of any blocker) | ||
| 184 | <li>All other windows (windows or modeless | ||
| 185 | dialogs outside M's SB and modal dialogs outside M's SB that do not | ||
| 186 | block M). | ||
| 187 | </ul> | ||
| 188 | </p><p> | ||
| 189 | After the modal dialog M is shown, it becomes blocked by the first shown | ||
| 190 | dialog from the first group (if there are any), all the windows from the | ||
| 191 | second one become blocked by M, and all the windows from the third group | ||
| 192 | remain untouched. | ||
| 193 | </p><p> | ||
| 194 | <u>In typical cases</u>, when no child dialogs are shown before their owners, | ||
| 195 | this rule can be simplified. (The following, simplified case, may | ||
| 196 | leave out some details). | ||
| 197 | </p><p> | ||
| 198 | <u>Showing the document-modal dialog: "M"</u><br> | ||
| 199 | All the visible application- and toolkit-modal dialogs are looked | ||
| 200 | through — if M is from the SB of one of them, | ||
| 201 | it becomes blocked by it. If there are several such dialogs, | ||
| 202 | the first shown is used. If no such dialogs exist, M remains unblocked. | ||
| 203 | </p><p> | ||
| 204 | <u>Showing the application-modal dialog: "M"</u><br> | ||
| 205 | All the visible toolkit-modal dialogs are looked through — | ||
| 206 | if M is from the SB of one of them, it becomes blocked by it. | ||
| 207 | If there are several such dialogs, the first shown is used. | ||
| 208 | If no such dialogs exist, M remains unblocked. | ||
| 209 | </p><p> | ||
| 210 | <u>Showing the toolkit-modal dialog: "M"</u><br> | ||
| 211 | M remains unblocked. | ||
| 212 | </p><p> | ||
| 213 | <!-- <center> --> | ||
| 214 | </p> | ||
| 215 | <table border="1" cols="5" rows="5"> | ||
| 216 | <caption>The Standard Blocking Matrix</caption> | ||
| 217 | <tbody><tr align="center"> | ||
| 218 | <td align="center">current/shown</td> | ||
| 219 | <td align="center">frame & modeless</td> | ||
| 220 | <td align="center">document</td> | ||
| 221 | <td align="center">application</td> | ||
| 222 | <td align="center">toolkit</td> | ||
| 223 | </tr> | ||
| 224 | <tr align="center"> | ||
| 225 | <td align="center">-</td> | ||
| 226 | <td align="center">-</td> | ||
| 227 | <td align="center">-</td> | ||
| 228 | <td align="center">-</td> | ||
| 229 | <td align="center">-</td> | ||
| 230 | </tr> | ||
| 231 | <tr align="center"> | ||
| 232 | <td align="center">document</td> | ||
| 233 | <td align="center">blocked</td> | ||
| 234 | <td align="center">-</td> | ||
| 235 | <td align="center">-</td> | ||
| 236 | <td align="center">-</td> | ||
| 237 | </tr> | ||
| 238 | <tr align="center"> | ||
| 239 | <td align="center">application</td> | ||
| 240 | <td align="center">blocked</td> | ||
| 241 | <td align="center">blocked</td> | ||
| 242 | <td align="center">-</td> | ||
| 243 | <td align="center">-</td> | ||
| 244 | </tr> | ||
| 245 | <tr align="center"> | ||
| 246 | <td align="center">toolkit</td> | ||
| 247 | <td align="center">blocked</td> | ||
| 248 | <td align="center">blocked</td> | ||
| 249 | <td align="center">blocked</td> | ||
| 250 | <td align="center">-</td> | ||
| 251 | </tr> | ||
| 252 | </tbody></table> | ||
| 253 | <!-- </center> --> | ||
| 254 | <p> | ||
| 255 | After the modal dialog is shown, all the windows from its SB are blocked, | ||
| 256 | except those that block this modal dialog. | ||
| 257 | </p><p> | ||
| 258 | <u>Hiding the window or modeless dialog: "F"</u><br> | ||
| 259 | If F was blocked by any modal dialog M, it becomes unblocked and is | ||
| 260 | removed from M's blocked windows list. | ||
| 261 | </p><p> | ||
| 262 | <u>Hiding the modal dialog: "M"</u><br> | ||
| 263 | If M was blocked by any other modal dialog, for example, "N", | ||
| 264 | it becomes unblocked and | ||
| 265 | is removed from N's blocked windows list. Then, all the windows and dialogs | ||
| 266 | blocked by M become unblocked, and after that the same checks | ||
| 267 | (as in Showing the modal dialog: "M") | ||
| 268 | are performed for each of them in the order they were initially shown. | ||
| 269 | |||
| 270 | <a name="ModalExclusion"></a> | ||
| 271 | </p><h3>Modal exclusion</h3> | ||
| 272 | |||
| 273 | <p> | ||
| 274 | There are two modal exclusion types introduced as of JDK 6 | ||
| 275 | </p><ul> | ||
| 276 | <li>Exclusion from blocking of toolkit-modal dialogs | ||
| 277 | </li><li>Exclusion from blocking of application-modal dialogs | ||
| 278 | </li></ul> | ||
| 279 | By default, a window's modal exclusion property is turned off. | ||
| 280 | <p> | ||
| 281 | </p><ol> | ||
| 282 | <li><u>Application-modal exclusion</u><br> | ||
| 283 | If a window is application-modal excluded, it is not blocked by any | ||
| 284 | application-modal dialogs. Also, it is not blocked by document-modal | ||
| 285 | dialogs from outside of its child hierarchy. | ||
| 286 | </li><li><u>Toolkit-modal exclusion</u><br> | ||
| 287 | If a window is toolkit-modal excluded, it is not blocked | ||
| 288 | by any application- or toolkit-modal dialogs. Also, it is not | ||
| 289 | blocked by document-modal dialogs from outside of their child hierarchy. | ||
| 290 | </li></ol> | ||
| 291 | <p> | ||
| 292 | <blockquote> | ||
| 293 | <hr> | ||
| 294 | <b>Implementation note</b>: Changing the modal exclusion type for a visible window | ||
| 295 | may have no effect until it is hidden and then shown again. | ||
| 296 | </hr> | ||
| 297 | </blockquote> | ||
| 298 | |||
| 299 | <a name="Related"</a> | ||
| 300 | </p><h3>Related AWT features</h3> | ||
| 301 | |||
| 302 | <p> | ||
| 303 | <u>Always-On-Top</u><br> | ||
| 304 | When a modal dialog that is not always-on-top blocks an always-on-top window, | ||
| 305 | their relative Z-order is unspecified and platform-dependent. | ||
| 306 | </p> | ||
| 307 | <p> | ||
| 308 | <u>The <code>toFront()</code> and <code>toBack()</code> methods</u><br> | ||
| 309 | A modal dialog should always be above all its blocked windows. Thus, if a blocked | ||
| 310 | window is brought to the front, its blocking dialog, if any, is also brought to the | ||
| 311 | front and remains above the blocked window. Likewise, if a modal dialog is sent to | ||
| 312 | the back, all of its blocked windows are sent to the back to keep them below the | ||
| 313 | blocking dialog. | ||
| 314 | </p> | ||
| 315 | <p> | ||
| 316 | <u>Minimizing, maximizing and closing blocked windows</u><br> | ||
| 317 | When a modal dialog blocks a window, the user may not be able to maximize or | ||
| 318 | minimize the blocked window— however, the actual behavior is unspecified | ||
| 319 | and platform-dependent. In any case, the user can't close the blocked window | ||
| 320 | interactively— but it can be closed programmatically by calling the | ||
| 321 | <code>setVisible(false)</code> or <code>dispose()</code> methods on the blocked | ||
| 322 | window. | ||
| 323 | </p> | ||
| 324 | <p> | ||
| 325 | <u>Blocked windows activations</u><br> | ||
| 326 | When the user selects a blocked window, it may be brought to the front, along | ||
| 327 | with the blocking modal dialog which would then become the active window— | ||
| 328 | however, the actual behavior is unspecified and platform-dependent. | ||
| 329 | </p> | ||
| 330 | <p> | ||
| 331 | <u>Hiding a modal dialog</u><br> | ||
| 332 | When the modal dialog that currently has focus is hidden, it is unspecified | ||
| 333 | and platform-dependent, which other window will become the active window. | ||
| 334 | Any of the following may become the active window: | ||
| 335 | <ol> | ||
| 336 | <li>The owner of the modal dialog - if the owner is unblocked. | ||
| 337 | </li><li>The <code>Window</code>, which was active before this modal dialog gained | ||
| 338 | focus - if the owner of the modal dialog is absent or is blocked. | ||
| 339 | </li></ol> | ||
| 340 | If the modal dialog to be hidden does not have focus, the active window remains | ||
| 341 | unchanged. | ||
| 342 | </p> | ||
| 343 | <a name="Security"></a> | ||
| 344 | </p><h3>Security</h3> | ||
| 345 | |||
| 346 | <p> | ||
| 347 | A special <code>AWTPermission</code>, <code>"toolkitModality"</code>, | ||
| 348 | is required to show toolkit-modal | ||
| 349 | dialogs. This would prevent, for example, blocking a browser or | ||
| 350 | Java Web Start (JWS) by modal dialogs shown from applets. | ||
| 351 | </p><p> | ||
| 352 | The same permission is required to exclude a window from toolkit modality. | ||
| 353 | This would prevent, for example, a dialog shown from an applet not to be | ||
| 354 | blocked by a browser's or JWS's modal dialog. | ||
| 355 | |||
| 356 | <a name="PlatformSupport"></a> | ||
| 357 | </p><h3>Platform support</h3> | ||
| 358 | |||
| 359 | <p> | ||
| 360 | Two <code>java.awt.Toolkit</code> methods allow you to check whether | ||
| 361 | the current platform supports specific modality features: | ||
| 362 | </p><ul> | ||
| 363 | <li><code>isModalityTypeSupported(modalityType)</code><br> | ||
| 364 | Returns whether the specified modality type is supported on | ||
| 365 | the current platform. | ||
| 366 | If mode "M" is not supported and a dialog is set to M-modal, | ||
| 367 | it behaves as modeless. | ||
| 368 | </li> | ||
| 369 | <li><code>isModalExclusionTypeSupported(modalExclusionType)</code><br> | ||
| 370 | Returns whether the given modal exclusion type is supported on | ||
| 371 | the current platform. If exclusion type "E" is not supported | ||
| 372 | and a window is marked as E-excluded, this has no effect. | ||
| 373 | </li></ul> | ||
| 374 | |||
| 375 | <a name="Compatibility"></a> | ||
| 376 | <h3>Compatibility</h3> | ||
| 377 | |||
| 378 | <p> | ||
| 379 | The default modality type is application-modal. It is used by the API | ||
| 380 | calls: <code>Dialog.setModal(true)</code>, | ||
| 381 | <code>Dialog(owner, true)</code>, etc. Prior to JDK 6 | ||
| 382 | the default type was toolkit-modal, | ||
| 383 | but the only distinction between application- and toolkit-modality is for | ||
| 384 | applets and applications launched from Java Web Start. | ||
| 385 | |||
| 386 | <a name="Examples"></a> | ||
| 387 | </p><h3>Examples</h3> | ||
| 388 | |||
| 389 | <table cols="2" border="0"> | ||
| 390 | <tbody><tr> | ||
| 391 | <td align="left" valign="center"> | ||
| 392 | <ol> | ||
| 393 | <li>Frame "F" is shown<br> | ||
| 394 | <li>Document-modal dialog "D<sub>i</sub>" is shown<br> | ||
| 395 | <li>F becomes blocked by D<sub>i</sub> — it's in the same document<br> | ||
| 396 | <li>Document-modal dialog "D<sub>ii</sub>" is shown<br> | ||
| 397 | <li>D<sub>i</sub> becomes blocked by D<sub>ii</sub> — it's in the | ||
| 398 | same document<br> | ||
| 399 | </ol> | ||
| 400 | <br> | ||
| 401 | </td> | ||
| 402 | <td align="center" valign="center"> | ||
| 403 | <img src="modal-example1.gif"> | ||
| 404 | <br> | ||
| 405 | </td> | ||
| 406 | </tr> | ||
| 407 | <tr> | ||
| 408 | <td align="left" valign="center"> | ||
| 409 | <ol> | ||
| 410 | <li>Frame "F" is shown<br> | ||
| 411 | <li>Document-modal dialog "D<sub>i</sub>" is shown<br> | ||
| 412 | <li>F becomes blocked by D<sub>i</sub> — it's in the same document<br> | ||
| 413 | <li>Document-modal dialog "D<sub>ii</sub>" is shown<br> | ||
| 414 | <li>D<sub>i</sub> becomes blocked by D<sub>ii</sub> — | ||
| 415 | it's in the same document<br> | ||
| 416 | <li>D<sub>i</sub> is hidden<br> | ||
| 417 | <li>F becomes blocked by D<sub>ii</sub> — it's in the same document<br> | ||
| 418 | </ol> | ||
| 419 | <br> | ||
| 420 | </td> | ||
| 421 | <td align="center"> | ||
| 422 | <img src="modal-example2.gif"> | ||
| 423 | <br> | ||
| 424 | </td> | ||
| 425 | </tr> | ||
| 426 | <tr> | ||
| 427 | <td align="left" valign="center"> | ||
| 428 | <ol> | ||
| 429 | <li>Frame "F" is shown<br> | ||
| 430 | <li>Toolkit-modal dialog "D<sub>i</sub>" is created, but not shown<br> | ||
| 431 | <li>Document-modal dialog "D<sub>ii</sub>" is shown<br> | ||
| 432 | <li>F becomes blocked by D<sub>ii</sub> — it's in the same document<br> | ||
| 433 | <li>Application-modal dialog "D<sub>iii</sub>" is shown<br> | ||
| 434 | <li>D<sub>ii</sub> becomes blocked by D<sub>iii</sub> — | ||
| 435 | it's in the same application<br> | ||
| 436 | <li>D<sub>i</sub> is shown<br> | ||
| 437 | <li>D<sub>i</sub> becomes blocked by D<sub>ii</sub> — it's its owner<br> | ||
| 438 | <li>D<sub>iii</sub> remains unblocked — it blocks D<sub>ii</sub> and | ||
| 439 | D<sub>ii</sub> blocks D<sub>i</sub><br> | ||
| 440 | </ol> | ||
| 441 | <br> | ||
| 442 | </td> | ||
| 443 | <td align="center" valign="center"> | ||
| 444 | <img src="modal-example3.gif"> | ||
| 445 | <br> | ||
| 446 | </td> | ||
| 447 | </tr> | ||
| 448 | <tr> | ||
| 449 | <td align="left" valign="center"> | ||
| 450 | <ol> | ||
| 451 | <li>Frame "F" is shown<br> | ||
| 452 | <li>Toolkit-modal dialog "D<sub>i</sub>" is created, but not shown<br> | ||
| 453 | <li>Document-modal dialog "D<sub>ii</sub>" is shown<br> | ||
| 454 | <li>F becomes blocked by D<sub>ii</sub> — it's in the same document<br> | ||
| 455 | <li>Application-modal dialog "D<sub>iii</sub>" is shown<br> | ||
| 456 | <li>D<sub>ii</sub> becomes blocked by D<sub>iii</sub> — it's in the | ||
| 457 | same application<br> | ||
| 458 | <li>D<sub>i</sub> is shown<br> | ||
| 459 | <li>D<sub>iii</sub> becomes blocked by D<sub>i</sub> — D<sub>i</sub> | ||
| 460 | is not blocked<br> | ||
| 461 | <li>D<sub>i</sub> remains unblocked<br> | ||
| 462 | </ol> | ||
| 463 | <br> | ||
| 464 | </td> | ||
| 465 | <td align="center" valign="center"> | ||
| 466 | <img src="modal-example4.gif"> | ||
| 467 | <br> | ||
| 468 | </td> | ||
| 469 | </tr> | ||
| 470 | </tbody></table> | ||
| 471 | |||
| 472 | </body></html> | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,2 @@ | |||
| 1 | <../../../../../mkconfig | ||
| 2 | |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.