1 /* 2 * Copyright (c) 2003, 2009, 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 package sun.awt; 26 27 import java.awt.Component; 28 import java.awt.KeyboardFocusManager; 29 import java.awt.Window; 30 import java.awt.Canvas; 31 import java.awt.Scrollbar; 32 import java.awt.Panel; 33 34 import java.awt.event.FocusEvent; 35 36 import java.awt.peer.KeyboardFocusManagerPeer; 37 import java.awt.peer.ComponentPeer; 38 39 import java.lang.reflect.InvocationTargetException; 40 import java.lang.reflect.Method; 41 42 import sun.util.logging.PlatformLogger; 43 44 public abstract class KeyboardFocusManagerPeerImpl implements KeyboardFocusManagerPeer { 45 46 private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.focus.KeyboardFocusManagerPeerImpl"); 47 48 private static AWTAccessor.KeyboardFocusManagerAccessor kfmAccessor = 49 AWTAccessor.getKeyboardFocusManagerAccessor(); 50 51 // The constants are copied from java.awt.KeyboardFocusManager 52 public static final int SNFH_FAILURE = 0; 53 public static final int SNFH_SUCCESS_HANDLED = 1; 54 public static final int SNFH_SUCCESS_PROCEED = 2; 55 56 protected KeyboardFocusManager manager; 57 58 public KeyboardFocusManagerPeerImpl(KeyboardFocusManager manager) { 59 this.manager = manager; 60 } 61 62 @Override 63 public void clearGlobalFocusOwner(Window activeWindow) { 64 if (activeWindow != null) { 65 Component focusOwner = activeWindow.getFocusOwner(); 66 if (focusLog.isLoggable(PlatformLogger.FINE)) 67 focusLog.fine("Clearing global focus owner " + focusOwner); 68 if (focusOwner != null) { 69 FocusEvent fl = new CausedFocusEvent(focusOwner, FocusEvent.FOCUS_LOST, false, null, 70 CausedFocusEvent.Cause.CLEAR_GLOBAL_FOCUS_OWNER); 71 SunToolkit.postPriorityEvent(fl); 72 } 73 } 74 } 75 76 /* 77 * WARNING: Don't call it on the Toolkit thread. 78 * 79 * Checks if the component: 80 * 1) accepts focus on click (in general) 81 * 2) may be a focus owner (in particular) 82 */ 83 @SuppressWarnings("deprecation") 84 public static boolean shouldFocusOnClick(Component component) { 85 boolean acceptFocusOnClick = false; 86 87 // A component is generally allowed to accept focus on click 88 // if its peer is focusable. There're some exceptions though. 89 90 91 // CANVAS & SCROLLBAR accept focus on click 92 if (component instanceof Canvas || 93 component instanceof Scrollbar) 94 { 95 acceptFocusOnClick = true; 96 97 // PANEL, empty only, accepts focus on click 98 } else if (component instanceof Panel) { 99 acceptFocusOnClick = (((Panel)component).getComponentCount() == 0); 100 101 102 // Other components 103 } else { 104 ComponentPeer peer = (component != null ? component.getPeer() : null); 105 acceptFocusOnClick = (peer != null ? peer.isFocusable() : false); 106 } 107 return acceptFocusOnClick && 108 AWTAccessor.getComponentAccessor().canBeFocusOwner(component); 109 } 110 111 /* 112 * Posts proper lost/gain focus events to the event queue. 113 */ 114 @SuppressWarnings("deprecation") 115 public static boolean deliverFocus(Component lightweightChild, 116 Component target, 117 boolean temporary, 118 boolean focusedWindowChangeAllowed, 119 long time, 120 CausedFocusEvent.Cause cause, 121 Component currentFocusOwner) // provided by the descendant peers 122 { 123 if (lightweightChild == null) { 124 lightweightChild = target; 125 } 126 127 Component currentOwner = currentFocusOwner; 128 if (currentOwner != null && currentOwner.getPeer() == null) { 129 currentOwner = null; 130 } 131 if (currentOwner != null) { 132 FocusEvent fl = new CausedFocusEvent(currentOwner, FocusEvent.FOCUS_LOST, 133 false, lightweightChild, cause); 134 135 if (focusLog.isLoggable(PlatformLogger.FINER)) 136 focusLog.finer("Posting focus event: " + fl); 137 SunToolkit.postPriorityEvent(fl); 138 } 139 140 FocusEvent fg = new CausedFocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED, 141 false, currentOwner, cause); 142 143 if (focusLog.isLoggable(PlatformLogger.FINER)) 144 focusLog.finer("Posting focus event: " + fg); 145 SunToolkit.postPriorityEvent(fg); 146 return true; 147 } 148 149 // WARNING: Don't call it on the Toolkit thread. 150 public static boolean requestFocusFor(Component target, CausedFocusEvent.Cause cause) { 151 return AWTAccessor.getComponentAccessor().requestFocus(target, cause); 152 } 153 154 // WARNING: Don't call it on the Toolkit thread. 155 public static int shouldNativelyFocusHeavyweight(Component heavyweight, 156 Component descendant, 157 boolean temporary, 158 boolean focusedWindowChangeAllowed, 159 long time, 160 CausedFocusEvent.Cause cause) 161 { 162 return kfmAccessor.shouldNativelyFocusHeavyweight( 163 heavyweight, descendant, temporary, focusedWindowChangeAllowed, time, cause); 164 } 165 166 public static void removeLastFocusRequest(Component heavyweight) { 167 kfmAccessor.removeLastFocusRequest(heavyweight); 168 } 169 170 // WARNING: Don't call it on the Toolkit thread. 171 public static boolean processSynchronousLightweightTransfer(Component heavyweight, 172 Component descendant, 173 boolean temporary, 174 boolean focusedWindowChangeAllowed, 175 long time) 176 { 177 return kfmAccessor.processSynchronousLightweightTransfer( 178 heavyweight, descendant, temporary, focusedWindowChangeAllowed, time); 179 } 180 }