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