提交 4a6c6b7b 编写于 作者: A ant

7110683: Issues with some KeyboardFocusManager method

Reviewed-by: ahgross
上级 b30e1bc2
...@@ -7833,7 +7833,7 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -7833,7 +7833,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
if (focusLog.isLoggable(PlatformLogger.FINER)) { if (focusLog.isLoggable(PlatformLogger.FINER)) {
focusLog.finer("clear global focus owner"); focusLog.finer("clear global focus owner");
} }
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();
} }
if (focusLog.isLoggable(PlatformLogger.FINER)) { if (focusLog.isLoggable(PlatformLogger.FINER)) {
focusLog.finer("returning result: " + res); focusLog.finer("returning result: " + res);
...@@ -7914,7 +7914,7 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -7914,7 +7914,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
if (focusLog.isLoggable(PlatformLogger.FINER)) { if (focusLog.isLoggable(PlatformLogger.FINER)) {
focusLog.finer("clear global focus owner"); focusLog.finer("clear global focus owner");
} }
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();
} }
if (focusLog.isLoggable(PlatformLogger.FINER)) { if (focusLog.isLoggable(PlatformLogger.FINER)) {
focusLog.finer("returning result: " + res); focusLog.finer("returning result: " + res);
...@@ -7947,21 +7947,32 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -7947,21 +7947,32 @@ public abstract class Component implements ImageObserver, MenuContainer,
if (rootAncestor != null) { if (rootAncestor != null) {
Container rootAncestorRootAncestor = Container rootAncestorRootAncestor =
rootAncestor.getFocusCycleRootAncestor(); rootAncestor.getFocusCycleRootAncestor();
KeyboardFocusManager.getCurrentKeyboardFocusManager().
setGlobalCurrentFocusCycleRoot( final Container fcr = (rootAncestorRootAncestor != null) ?
(rootAncestorRootAncestor != null) rootAncestorRootAncestor : rootAncestor;
? rootAncestorRootAncestor
: rootAncestor); AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
KeyboardFocusManager.getCurrentKeyboardFocusManager().
setGlobalCurrentFocusCycleRoot(fcr);
return null;
}
});
rootAncestor.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP); rootAncestor.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
} else { } else {
Window window = getContainingWindow(); final Window window = getContainingWindow();
if (window != null) { if (window != null) {
Component toFocus = window.getFocusTraversalPolicy(). Component toFocus = window.getFocusTraversalPolicy().
getDefaultComponent(window); getDefaultComponent(window);
if (toFocus != null) { if (toFocus != null) {
KeyboardFocusManager.getCurrentKeyboardFocusManager(). AccessController.doPrivileged(new PrivilegedAction() {
setGlobalCurrentFocusCycleRoot(window); public Object run() {
KeyboardFocusManager.getCurrentKeyboardFocusManager().
setGlobalCurrentFocusCycleRoot(window);
return null;
}
});
toFocus.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP); toFocus.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
} }
} }
......
...@@ -116,7 +116,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { ...@@ -116,7 +116,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
} else if (fe.getOppositeComponent() != null && } else if (fe.getOppositeComponent() != null &&
doRestoreFocus(fe.getOppositeComponent(), vetoedComponent, false)) { doRestoreFocus(fe.getOppositeComponent(), vetoedComponent, false)) {
} else { } else {
clearGlobalFocusOwner(); clearGlobalFocusOwnerPriv();
} }
} }
private void restoreFocus(WindowEvent we) { private void restoreFocus(WindowEvent we) {
...@@ -130,7 +130,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { ...@@ -130,7 +130,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
{ {
// do nothing, everything is done in restoreFocus() // do nothing, everything is done in restoreFocus()
} else { } else {
clearGlobalFocusOwner(); clearGlobalFocusOwnerPriv();
} }
} }
private boolean restoreFocus(Window aWindow, Component vetoedComponent, private boolean restoreFocus(Window aWindow, Component vetoedComponent,
...@@ -141,7 +141,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { ...@@ -141,7 +141,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
if (toFocus != null && toFocus != vetoedComponent && doRestoreFocus(toFocus, vetoedComponent, false)) { if (toFocus != null && toFocus != vetoedComponent && doRestoreFocus(toFocus, vetoedComponent, false)) {
return true; return true;
} else if (clearOnFailure) { } else if (clearOnFailure) {
clearGlobalFocusOwner(); clearGlobalFocusOwnerPriv();
return true; return true;
} else { } else {
return false; return false;
...@@ -164,7 +164,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { ...@@ -164,7 +164,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
{ {
return true; return true;
} else if (clearOnFailure) { } else if (clearOnFailure) {
clearGlobalFocusOwner(); clearGlobalFocusOwnerPriv();
return true; return true;
} else { } else {
return false; return false;
......
/* /*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -246,15 +246,7 @@ public abstract class KeyboardFocusManager ...@@ -246,15 +246,7 @@ public abstract class KeyboardFocusManager
public static void setCurrentKeyboardFocusManager( public static void setCurrentKeyboardFocusManager(
KeyboardFocusManager newManager) throws SecurityException KeyboardFocusManager newManager) throws SecurityException
{ {
SecurityManager security = System.getSecurityManager(); checkReplaceKFMPermission();
if (security != null) {
if (replaceKeyboardFocusManagerPermission == null) {
replaceKeyboardFocusManagerPermission =
new AWTPermission("replaceKeyboardFocusManager");
}
security.
checkPermission(replaceKeyboardFocusManagerPermission);
}
KeyboardFocusManager oldManager = null; KeyboardFocusManager oldManager = null;
...@@ -398,11 +390,6 @@ public abstract class KeyboardFocusManager ...@@ -398,11 +390,6 @@ public abstract class KeyboardFocusManager
*/ */
private static java.util.Map mostRecentFocusOwners = new WeakHashMap(); private static java.util.Map mostRecentFocusOwners = new WeakHashMap();
/**
* Error String for initializing SecurityExceptions.
*/
private static final String notPrivileged = "this KeyboardFocusManager is not installed in the current thread's context";
/** /**
* We cache the permission used to verify that the calling thread is * We cache the permission used to verify that the calling thread is
* permitted to access the global focus state. * permitted to access the global focus state.
...@@ -503,17 +490,13 @@ public abstract class KeyboardFocusManager ...@@ -503,17 +490,13 @@ public abstract class KeyboardFocusManager
* @see #setGlobalFocusOwner * @see #setGlobalFocusOwner
* @throws SecurityException if this KeyboardFocusManager is not the * @throws SecurityException if this KeyboardFocusManager is not the
* current KeyboardFocusManager for the calling thread's context * current KeyboardFocusManager for the calling thread's context
* and if the calling thread does not have "replaceKeyboardFocusManager"
* permission
*/ */
protected Component getGlobalFocusOwner() throws SecurityException { protected Component getGlobalFocusOwner() throws SecurityException {
synchronized (KeyboardFocusManager.class) { synchronized (KeyboardFocusManager.class) {
if (this == getCurrentKeyboardFocusManager()) { checkKFMSecurity();
return focusOwner; return focusOwner;
} else {
if (focusLog.isLoggable(PlatformLogger.FINER)) {
focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
}
throw new SecurityException(notPrivileged);
}
} }
} }
...@@ -538,15 +521,23 @@ public abstract class KeyboardFocusManager ...@@ -538,15 +521,23 @@ public abstract class KeyboardFocusManager
* @see Component#requestFocus() * @see Component#requestFocus()
* @see Component#requestFocusInWindow() * @see Component#requestFocusInWindow()
* @see Component#isFocusable * @see Component#isFocusable
* @throws SecurityException if this KeyboardFocusManager is not the
* current KeyboardFocusManager for the calling thread's context
* and if the calling thread does not have "replaceKeyboardFocusManager"
* permission
* @beaninfo * @beaninfo
* bound: true * bound: true
*/ */
protected void setGlobalFocusOwner(Component focusOwner) { protected void setGlobalFocusOwner(Component focusOwner)
throws SecurityException
{
Component oldFocusOwner = null; Component oldFocusOwner = null;
boolean shouldFire = false; boolean shouldFire = false;
if (focusOwner == null || focusOwner.isFocusable()) { if (focusOwner == null || focusOwner.isFocusable()) {
synchronized (KeyboardFocusManager.class) { synchronized (KeyboardFocusManager.class) {
checkKFMSecurity();
oldFocusOwner = getFocusOwner(); oldFocusOwner = getFocusOwner();
try { try {
...@@ -583,6 +574,27 @@ public abstract class KeyboardFocusManager ...@@ -583,6 +574,27 @@ public abstract class KeyboardFocusManager
} }
} }
/**
* Clears the focus owner at both the Java and native levels if the
* focus owner exists and resides in the same context as the calling thread,
* otherwise the method returns silently.
* <p>
* The focus owner component will receive a permanent FOCUS_LOST event.
* After this operation completes, the native windowing system will discard
* all user-generated KeyEvents until the user selects a new Component to
* receive focus, or a Component is given focus explicitly via a call to
* {@code requestFocus()}. This operation does not change the focused or
* active Windows.
*
* @see Component#requestFocus()
* @see java.awt.event.FocusEvent#FOCUS_LOST
*/
public void clearFocusOwner() {
if (getFocusOwner() != null) {
clearGlobalFocusOwner();
}
}
/** /**
* Clears the global focus owner at both the Java and native levels. If * Clears the global focus owner at both the Java and native levels. If
* there exists a focus owner, that Component will receive a permanent * there exists a focus owner, that Component will receive a permanent
...@@ -591,11 +603,26 @@ public abstract class KeyboardFocusManager ...@@ -591,11 +603,26 @@ public abstract class KeyboardFocusManager
* a new Component to receive focus, or a Component is given focus * a new Component to receive focus, or a Component is given focus
* explicitly via a call to <code>requestFocus()</code>. This operation * explicitly via a call to <code>requestFocus()</code>. This operation
* does not change the focused or active Windows. * does not change the focused or active Windows.
* <p>
* If a SecurityManager is installed, the calling thread must be granted
* the "replaceKeyboardFocusManager" AWTPermission. If this permission is
* not granted, this method will throw a SecurityException, and the current
* focus owner will not be cleared.
* <p>
* This method is intended to be used only by KeyboardFocusManager set as
* current KeyboardFocusManager for the calling thread's context. It is not
* for general client use.
* *
* @see KeyboardFocusManager#clearFocusOwner
* @see Component#requestFocus() * @see Component#requestFocus()
* @see java.awt.event.FocusEvent#FOCUS_LOST * @see java.awt.event.FocusEvent#FOCUS_LOST
* @throws SecurityException if the calling thread does not have
* "replaceKeyboardFocusManager" permission
*/ */
public void clearGlobalFocusOwner() { public void clearGlobalFocusOwner()
throws SecurityException
{
checkReplaceKFMPermission();
if (!GraphicsEnvironment.isHeadless()) { if (!GraphicsEnvironment.isHeadless()) {
// Toolkit must be fully initialized, otherwise // Toolkit must be fully initialized, otherwise
// _clearGlobalFocusOwner will crash or throw an exception // _clearGlobalFocusOwner will crash or throw an exception
...@@ -609,6 +636,15 @@ public abstract class KeyboardFocusManager ...@@ -609,6 +636,15 @@ public abstract class KeyboardFocusManager
peer.clearGlobalFocusOwner(activeWindow); peer.clearGlobalFocusOwner(activeWindow);
} }
void clearGlobalFocusOwnerPriv() {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
clearGlobalFocusOwner();
return null;
}
});
}
Component getNativeFocusOwner() { Component getNativeFocusOwner() {
return peer.getCurrentFocusOwner(); return peer.getCurrentFocusOwner();
} }
...@@ -660,29 +696,21 @@ public abstract class KeyboardFocusManager ...@@ -660,29 +696,21 @@ public abstract class KeyboardFocusManager
* are equivalent unless a temporary focus change is currently in effect. * are equivalent unless a temporary focus change is currently in effect.
* In such a situation, the permanent focus owner will again be the focus * In such a situation, the permanent focus owner will again be the focus
* owner when the temporary focus change ends. * owner when the temporary focus change ends.
* <p>
* This method will throw a SecurityException if this KeyboardFocusManager
* is not the current KeyboardFocusManager for the calling thread's
* context.
* *
* @return the permanent focus owner * @return the permanent focus owner
* @see #getPermanentFocusOwner * @see #getPermanentFocusOwner
* @see #setGlobalPermanentFocusOwner * @see #setGlobalPermanentFocusOwner
* @throws SecurityException if this KeyboardFocusManager is not the * @throws SecurityException if this KeyboardFocusManager is not the
* current KeyboardFocusManager for the calling thread's context * current KeyboardFocusManager for the calling thread's context
* and if the calling thread does not have "replaceKeyboardFocusManager"
* permission
*/ */
protected Component getGlobalPermanentFocusOwner() protected Component getGlobalPermanentFocusOwner()
throws SecurityException throws SecurityException
{ {
synchronized (KeyboardFocusManager.class) { synchronized (KeyboardFocusManager.class) {
if (this == getCurrentKeyboardFocusManager()) { checkKFMSecurity();
return permanentFocusOwner; return permanentFocusOwner;
} else {
if (focusLog.isLoggable(PlatformLogger.FINER)) {
focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
}
throw new SecurityException(notPrivileged);
}
} }
} }
...@@ -708,16 +736,23 @@ public abstract class KeyboardFocusManager ...@@ -708,16 +736,23 @@ public abstract class KeyboardFocusManager
* @see Component#requestFocus() * @see Component#requestFocus()
* @see Component#requestFocusInWindow() * @see Component#requestFocusInWindow()
* @see Component#isFocusable * @see Component#isFocusable
* @throws SecurityException if this KeyboardFocusManager is not the
* current KeyboardFocusManager for the calling thread's context
* and if the calling thread does not have "replaceKeyboardFocusManager"
* permission
* @beaninfo * @beaninfo
* bound: true * bound: true
*/ */
protected void setGlobalPermanentFocusOwner(Component permanentFocusOwner) protected void setGlobalPermanentFocusOwner(Component permanentFocusOwner)
throws SecurityException
{ {
Component oldPermanentFocusOwner = null; Component oldPermanentFocusOwner = null;
boolean shouldFire = false; boolean shouldFire = false;
if (permanentFocusOwner == null || permanentFocusOwner.isFocusable()) { if (permanentFocusOwner == null || permanentFocusOwner.isFocusable()) {
synchronized (KeyboardFocusManager.class) { synchronized (KeyboardFocusManager.class) {
checkKFMSecurity();
oldPermanentFocusOwner = getPermanentFocusOwner(); oldPermanentFocusOwner = getPermanentFocusOwner();
try { try {
...@@ -770,27 +805,19 @@ public abstract class KeyboardFocusManager ...@@ -770,27 +805,19 @@ public abstract class KeyboardFocusManager
* Returns the focused Window, even if the calling thread is in a different * Returns the focused Window, even if the calling thread is in a different
* context than the focused Window. The focused Window is the Window that * context than the focused Window. The focused Window is the Window that
* is or contains the focus owner. * is or contains the focus owner.
* <p>
* This method will throw a SecurityException if this KeyboardFocusManager
* is not the current KeyboardFocusManager for the calling thread's
* context.
* *
* @return the focused Window * @return the focused Window
* @see #getFocusedWindow * @see #getFocusedWindow
* @see #setGlobalFocusedWindow * @see #setGlobalFocusedWindow
* @throws SecurityException if this KeyboardFocusManager is not the * @throws SecurityException if this KeyboardFocusManager is not the
* current KeyboardFocusManager for the calling thread's context * current KeyboardFocusManager for the calling thread's context
* and if the calling thread does not have "replaceKeyboardFocusManager"
* permission
*/ */
protected Window getGlobalFocusedWindow() throws SecurityException { protected Window getGlobalFocusedWindow() throws SecurityException {
synchronized (KeyboardFocusManager.class) { synchronized (KeyboardFocusManager.class) {
if (this == getCurrentKeyboardFocusManager()) { checkKFMSecurity();
return focusedWindow; return focusedWindow;
} else {
if (focusLog.isLoggable(PlatformLogger.FINER)) {
focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
}
throw new SecurityException(notPrivileged);
}
} }
} }
...@@ -812,15 +839,23 @@ public abstract class KeyboardFocusManager ...@@ -812,15 +839,23 @@ public abstract class KeyboardFocusManager
* @see Component#requestFocus() * @see Component#requestFocus()
* @see Component#requestFocusInWindow() * @see Component#requestFocusInWindow()
* @see Window#isFocusableWindow * @see Window#isFocusableWindow
* @throws SecurityException if this KeyboardFocusManager is not the
* current KeyboardFocusManager for the calling thread's context
* and if the calling thread does not have "replaceKeyboardFocusManager"
* permission
* @beaninfo * @beaninfo
* bound: true * bound: true
*/ */
protected void setGlobalFocusedWindow(Window focusedWindow) { protected void setGlobalFocusedWindow(Window focusedWindow)
throws SecurityException
{
Window oldFocusedWindow = null; Window oldFocusedWindow = null;
boolean shouldFire = false; boolean shouldFire = false;
if (focusedWindow == null || focusedWindow.isFocusableWindow()) { if (focusedWindow == null || focusedWindow.isFocusableWindow()) {
synchronized (KeyboardFocusManager.class) { synchronized (KeyboardFocusManager.class) {
checkKFMSecurity();
oldFocusedWindow = getFocusedWindow(); oldFocusedWindow = getFocusedWindow();
try { try {
...@@ -874,27 +909,19 @@ public abstract class KeyboardFocusManager ...@@ -874,27 +909,19 @@ public abstract class KeyboardFocusManager
* or its children with special decorations, such as a highlighted title * or its children with special decorations, such as a highlighted title
* bar. The active Window is always either the focused Window, or the first * bar. The active Window is always either the focused Window, or the first
* Frame or Dialog that is an owner of the focused Window. * Frame or Dialog that is an owner of the focused Window.
* <p>
* This method will throw a SecurityException if this KeyboardFocusManager
* is not the current KeyboardFocusManager for the calling thread's
* context.
* *
* @return the active Window * @return the active Window
* @see #getActiveWindow * @see #getActiveWindow
* @see #setGlobalActiveWindow * @see #setGlobalActiveWindow
* @throws SecurityException if this KeyboardFocusManager is not the * @throws SecurityException if this KeyboardFocusManager is not the
* current KeyboardFocusManager for the calling thread's context * current KeyboardFocusManager for the calling thread's context
* and if the calling thread does not have "replaceKeyboardFocusManager"
* permission
*/ */
protected Window getGlobalActiveWindow() throws SecurityException { protected Window getGlobalActiveWindow() throws SecurityException {
synchronized (KeyboardFocusManager.class) { synchronized (KeyboardFocusManager.class) {
if (this == getCurrentKeyboardFocusManager()) { checkKFMSecurity();
return activeWindow; return activeWindow;
} else {
if (focusLog.isLoggable(PlatformLogger.FINER)) {
focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
}
throw new SecurityException(notPrivileged);
}
} }
} }
...@@ -917,12 +944,20 @@ public abstract class KeyboardFocusManager ...@@ -917,12 +944,20 @@ public abstract class KeyboardFocusManager
* @see #getGlobalActiveWindow * @see #getGlobalActiveWindow
* @see Component#requestFocus() * @see Component#requestFocus()
* @see Component#requestFocusInWindow() * @see Component#requestFocusInWindow()
* @throws SecurityException if this KeyboardFocusManager is not the
* current KeyboardFocusManager for the calling thread's context
* and if the calling thread does not have "replaceKeyboardFocusManager"
* permission
* @beaninfo * @beaninfo
* bound: true * bound: true
*/ */
protected void setGlobalActiveWindow(Window activeWindow) { protected void setGlobalActiveWindow(Window activeWindow)
throws SecurityException
{
Window oldActiveWindow; Window oldActiveWindow;
synchronized (KeyboardFocusManager.class) { synchronized (KeyboardFocusManager.class) {
checkKFMSecurity();
oldActiveWindow = getActiveWindow(); oldActiveWindow = getActiveWindow();
if (focusLog.isLoggable(PlatformLogger.FINER)) { if (focusLog.isLoggable(PlatformLogger.FINER)) {
focusLog.finer("Setting global active window to " + activeWindow + ", old active " + oldActiveWindow); focusLog.finer("Setting global active window to " + activeWindow + ", old active " + oldActiveWindow);
...@@ -1194,10 +1229,6 @@ public abstract class KeyboardFocusManager ...@@ -1194,10 +1229,6 @@ public abstract class KeyboardFocusManager
* Components represent the next and previous Components to focus during * Components represent the next and previous Components to focus during
* normal focus traversal. In that case, the current focus cycle root is * normal focus traversal. In that case, the current focus cycle root is
* used to differentiate among the possibilities. * used to differentiate among the possibilities.
* <p>
* This method will throw a SecurityException if this KeyboardFocusManager
* is not the current KeyboardFocusManager for the calling thread's
* context.
* *
* @return the current focus cycle root, or null if the current focus cycle * @return the current focus cycle root, or null if the current focus cycle
* root is not a member of the calling thread's context * root is not a member of the calling thread's context
...@@ -1205,19 +1236,15 @@ public abstract class KeyboardFocusManager ...@@ -1205,19 +1236,15 @@ public abstract class KeyboardFocusManager
* @see #setGlobalCurrentFocusCycleRoot * @see #setGlobalCurrentFocusCycleRoot
* @throws SecurityException if this KeyboardFocusManager is not the * @throws SecurityException if this KeyboardFocusManager is not the
* current KeyboardFocusManager for the calling thread's context * current KeyboardFocusManager for the calling thread's context
* and if the calling thread does not have "replaceKeyboardFocusManager"
* permission
*/ */
protected Container getGlobalCurrentFocusCycleRoot() protected Container getGlobalCurrentFocusCycleRoot()
throws SecurityException throws SecurityException
{ {
synchronized (KeyboardFocusManager.class) { synchronized (KeyboardFocusManager.class) {
if (this == getCurrentKeyboardFocusManager()) { checkKFMSecurity();
return currentFocusCycleRoot; return currentFocusCycleRoot;
} else {
if (focusLog.isLoggable(PlatformLogger.FINER)) {
focusLog.finer("This manager is " + this + ", current is " + getCurrentKeyboardFocusManager());
}
throw new SecurityException(notPrivileged);
}
} }
} }
...@@ -1228,16 +1255,27 @@ public abstract class KeyboardFocusManager ...@@ -1228,16 +1255,27 @@ public abstract class KeyboardFocusManager
* In that case, the current focus cycle root is used to differentiate * In that case, the current focus cycle root is used to differentiate
* among the possibilities. * among the possibilities.
* <p> * <p>
* If a SecurityManager is installed, the calling thread must be granted
* the "replaceKeyboardFocusManager" AWTPermission. If this permission is
* not granted, this method will throw a SecurityException, and the current
* focus cycle root will not be changed.
* <p>
* This method is intended to be used only by KeyboardFocusManagers and * This method is intended to be used only by KeyboardFocusManagers and
* focus implementations. It is not for general client use. * focus implementations. It is not for general client use.
* *
* @param newFocusCycleRoot the new focus cycle root * @param newFocusCycleRoot the new focus cycle root
* @see #getCurrentFocusCycleRoot * @see #getCurrentFocusCycleRoot
* @see #getGlobalCurrentFocusCycleRoot * @see #getGlobalCurrentFocusCycleRoot
* @throws SecurityException if the calling thread does not have
* "replaceKeyboardFocusManager" permission
* @beaninfo * @beaninfo
* bound: true * bound: true
*/ */
public void setGlobalCurrentFocusCycleRoot(Container newFocusCycleRoot) { public void setGlobalCurrentFocusCycleRoot(Container newFocusCycleRoot)
throws SecurityException
{
checkReplaceKFMPermission();
Container oldFocusCycleRoot; Container oldFocusCycleRoot;
synchronized (KeyboardFocusManager.class) { synchronized (KeyboardFocusManager.class) {
...@@ -3058,4 +3096,39 @@ public abstract class KeyboardFocusManager ...@@ -3058,4 +3096,39 @@ public abstract class KeyboardFocusManager
: null; : null;
} }
} }
private static void checkReplaceKFMPermission()
throws SecurityException
{
SecurityManager security = System.getSecurityManager();
if (security != null) {
if (replaceKeyboardFocusManagerPermission == null) {
replaceKeyboardFocusManagerPermission =
new AWTPermission("replaceKeyboardFocusManager");
}
security.
checkPermission(replaceKeyboardFocusManagerPermission);
}
}
// Checks if this KeyboardFocusManager instance is the current KFM,
// or otherwise checks if the calling thread has "replaceKeyboardFocusManager"
// permission. Here's the reasoning to do so:
//
// A system KFM instance (which is the current KFM by default) may have no
// "replaceKFM" permission when a client code is on the call stack beneath,
// but still it should be able to execute the methods protected by this check
// due to the system KFM is trusted (and so it does like "privileged").
//
// If this KFM instance is not the current KFM but the client code has all
// permissions we can't throw SecurityException because it would contradict
// the security concepts. In this case the trusted client code is responsible
// for calling the secured methods from KFM instance which is not current.
private void checkKFMSecurity()
throws SecurityException
{
if (this != getCurrentKeyboardFocusManager()) {
checkReplaceKFMPermission();
}
}
} }
...@@ -2568,7 +2568,7 @@ public class Window extends Container implements Accessible { ...@@ -2568,7 +2568,7 @@ public class Window extends Container implements Accessible {
} }
} }
KeyboardFocusManager.getCurrentKeyboardFocusManager(). KeyboardFocusManager.getCurrentKeyboardFocusManager().
clearGlobalFocusOwner(); clearGlobalFocusOwnerPriv();
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册