mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-25 09:40:10 +00:00
Merge
This commit is contained in:
commit
29f70d33d7
@ -40,6 +40,7 @@ import java.awt.image.VolatileImage;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
import java.awt.peer.ContainerPeer;
|
||||
|
||||
import java.awt.peer.KeyboardFocusManagerPeer;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.AccessController;
|
||||
@ -894,15 +895,15 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
|
||||
", focusedWindowChangeAllowed=" + focusedWindowChangeAllowed +
|
||||
", time= " + time + ", cause=" + cause);
|
||||
}
|
||||
if (LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
|
||||
processSynchronousLightweightTransfer(getTarget(), lightweightChild, temporary,
|
||||
focusedWindowChangeAllowed, time)) {
|
||||
if (LWKeyboardFocusManagerPeer.processSynchronousLightweightTransfer(
|
||||
getTarget(), lightweightChild, temporary,
|
||||
focusedWindowChangeAllowed, time)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int result = LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
|
||||
shouldNativelyFocusHeavyweight(getTarget(), lightweightChild, temporary,
|
||||
focusedWindowChangeAllowed, time, cause);
|
||||
int result = LWKeyboardFocusManagerPeer.shouldNativelyFocusHeavyweight(
|
||||
getTarget(), lightweightChild, temporary,
|
||||
focusedWindowChangeAllowed, time, cause);
|
||||
switch (result) {
|
||||
case LWKeyboardFocusManagerPeer.SNFH_FAILURE:
|
||||
return false;
|
||||
@ -951,14 +952,13 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
|
||||
return false;
|
||||
}
|
||||
|
||||
LWComponentPeer focusOwnerPeer =
|
||||
LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
|
||||
getFocusOwner();
|
||||
Component focusOwner = (focusOwnerPeer != null) ? focusOwnerPeer.getTarget() : null;
|
||||
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
|
||||
Component focusOwner = kfmPeer.getCurrentFocusOwner();
|
||||
return LWKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
|
||||
getTarget(), temporary,
|
||||
focusedWindowChangeAllowed,
|
||||
time, cause, focusOwner);
|
||||
|
||||
case LWKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
|
||||
return true;
|
||||
}
|
||||
@ -1251,9 +1251,6 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
|
||||
|
||||
if (!target.isFocusOwner() && LWKeyboardFocusManagerPeer.shouldFocusOnClick(target)) {
|
||||
LWKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT);
|
||||
} else {
|
||||
// Anyway request focus to the toplevel.
|
||||
getWindowPeerOrSelf().requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1263,8 +1260,8 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
|
||||
protected void handleJavaFocusEvent(FocusEvent e) {
|
||||
// Note that the peer receives all the FocusEvents from
|
||||
// its lightweight children as well
|
||||
LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
|
||||
setFocusOwner(e.getID() == FocusEvent.FOCUS_GAINED ? this : null);
|
||||
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
|
||||
kfmPeer.setCurrentFocusOwner(e.getID() == FocusEvent.FOCUS_GAINED ? getTarget() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -26,85 +26,47 @@
|
||||
package sun.lwawt;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Window;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.awt.AppContext;
|
||||
import sun.awt.KeyboardFocusManagerPeerImpl;
|
||||
|
||||
public class LWKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
|
||||
private static final LWKeyboardFocusManagerPeer inst = new LWKeyboardFocusManagerPeer();
|
||||
|
||||
private Object lock = new Object();
|
||||
private LWWindowPeer focusedWindow;
|
||||
private LWComponentPeer focusOwner;
|
||||
private Window focusedWindow;
|
||||
private Component focusOwner;
|
||||
|
||||
private static Map<KeyboardFocusManager, LWKeyboardFocusManagerPeer> instances =
|
||||
new HashMap<KeyboardFocusManager, LWKeyboardFocusManagerPeer>();
|
||||
|
||||
public static synchronized LWKeyboardFocusManagerPeer getInstance(AppContext ctx) {
|
||||
return getInstance(AWTAccessor.getKeyboardFocusManagerAccessor().
|
||||
getCurrentKeyboardFocusManager(ctx));
|
||||
public static LWKeyboardFocusManagerPeer getInstance() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
public static synchronized LWKeyboardFocusManagerPeer getInstance(KeyboardFocusManager manager) {
|
||||
LWKeyboardFocusManagerPeer instance = instances.get(manager);
|
||||
if (instance == null) {
|
||||
instance = new LWKeyboardFocusManagerPeer(manager);
|
||||
instances.put(manager, instance);
|
||||
private LWKeyboardFocusManagerPeer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentFocusedWindow(Window win) {
|
||||
synchronized (this) {
|
||||
focusedWindow = win;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public LWKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
|
||||
super(manager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Window getCurrentFocusedWindow() {
|
||||
synchronized (lock) {
|
||||
return (focusedWindow != null) ? (Window)focusedWindow.getTarget() : null;
|
||||
synchronized (this) {
|
||||
return focusedWindow;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getCurrentFocusOwner() {
|
||||
synchronized (lock) {
|
||||
return (focusOwner != null) ? focusOwner.getTarget() : null;
|
||||
synchronized (this) {
|
||||
return focusOwner;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentFocusOwner(Component comp) {
|
||||
synchronized (lock) {
|
||||
focusOwner = (comp != null) ? (LWComponentPeer)comp.getPeer() : null;
|
||||
}
|
||||
}
|
||||
|
||||
void setFocusedWindow(LWWindowPeer peer) {
|
||||
synchronized (lock) {
|
||||
focusedWindow = peer;
|
||||
}
|
||||
}
|
||||
|
||||
LWWindowPeer getFocusedWindow() {
|
||||
synchronized (lock) {
|
||||
return focusedWindow;
|
||||
}
|
||||
}
|
||||
|
||||
void setFocusOwner(LWComponentPeer peer) {
|
||||
synchronized (lock) {
|
||||
focusOwner = peer;
|
||||
}
|
||||
}
|
||||
|
||||
LWComponentPeer getFocusOwner() {
|
||||
synchronized (lock) {
|
||||
return focusOwner;
|
||||
synchronized (this) {
|
||||
focusOwner = comp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -415,8 +415,8 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
|
||||
return LWKeyboardFocusManagerPeer.getInstance(manager);
|
||||
public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
|
||||
return LWKeyboardFocusManagerPeer.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -88,10 +88,16 @@ public class LWWindowPeer
|
||||
|
||||
private volatile int windowState = Frame.NORMAL;
|
||||
|
||||
// A peer where the last mouse event came to. Used to generate
|
||||
// MOUSE_ENTERED/EXITED notifications and by cursor manager to
|
||||
// check that the mouse is over the window
|
||||
private volatile boolean isMouseOver = false;
|
||||
|
||||
// A peer where the last mouse event came to. Used by cursor manager to
|
||||
// find the component under cursor
|
||||
private static volatile LWComponentPeer lastMouseEventPeer = null;
|
||||
private static volatile LWComponentPeer lastCommonMouseEventPeer = null;
|
||||
|
||||
// A peer where the last mouse event came to. Used to generate
|
||||
// MOUSE_ENTERED/EXITED notifications
|
||||
private volatile LWComponentPeer lastMouseEventPeer;
|
||||
|
||||
// Peers where all dragged/released events should come to,
|
||||
// depending on what mouse button is being dragged according to Cocoa
|
||||
@ -232,8 +238,7 @@ public class LWWindowPeer
|
||||
// TODO: update graphicsConfig, see 4868278
|
||||
platformWindow.setVisible(visible);
|
||||
if (isSimpleWindow()) {
|
||||
LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer.
|
||||
getInstance(getAppContext());
|
||||
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
|
||||
|
||||
if (visible) {
|
||||
if (!getTarget().isAutoRequestFocus()) {
|
||||
@ -242,7 +247,7 @@ public class LWWindowPeer
|
||||
requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
|
||||
}
|
||||
// Focus the owner in case this window is focused.
|
||||
} else if (manager.getCurrentFocusedWindow() == getTarget()) {
|
||||
} else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) {
|
||||
// Transfer focus to the owner.
|
||||
LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
|
||||
if (owner != null) {
|
||||
@ -707,66 +712,65 @@ public class LWWindowPeer
|
||||
Rectangle r = getBounds();
|
||||
// findPeerAt() expects parent coordinates
|
||||
LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
|
||||
LWWindowPeer lastWindowPeer =
|
||||
(lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
|
||||
LWWindowPeer curWindowPeer =
|
||||
(targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null;
|
||||
|
||||
if (id == MouseEvent.MOUSE_EXITED) {
|
||||
// Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched
|
||||
// to a peer from another window. So we must first check if this peer is
|
||||
// the same as lastWindowPeer
|
||||
if (lastWindowPeer == this) {
|
||||
if (isEnabled()) {
|
||||
isMouseOver = false;
|
||||
if (lastMouseEventPeer != null) {
|
||||
if (lastMouseEventPeer.isEnabled()) {
|
||||
Point lp = lastMouseEventPeer.windowToLocal(x, y,
|
||||
lastWindowPeer);
|
||||
this);
|
||||
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
|
||||
MouseEvent.MOUSE_EXITED, when,
|
||||
modifiers, lp.x, lp.y, screenX,
|
||||
screenY, clickCount, popupTrigger,
|
||||
button));
|
||||
MouseEvent.MOUSE_EXITED, when,
|
||||
modifiers, lp.x, lp.y, screenX,
|
||||
screenY, clickCount, popupTrigger,
|
||||
button));
|
||||
}
|
||||
|
||||
// Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched
|
||||
// to a peer from another window. So we must first check if this peer is
|
||||
// the same as lastWindowPeer
|
||||
if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) {
|
||||
lastCommonMouseEventPeer = null;
|
||||
}
|
||||
lastMouseEventPeer = null;
|
||||
}
|
||||
} else {
|
||||
if (targetPeer != lastMouseEventPeer) {
|
||||
|
||||
if (id != MouseEvent.MOUSE_DRAGGED || lastMouseEventPeer == null) {
|
||||
// lastMouseEventPeer may be null if mouse was out of Java windows
|
||||
if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
|
||||
// Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit
|
||||
// later), in which case lastWindowPeer is another window
|
||||
if (lastWindowPeer != this) {
|
||||
Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
|
||||
// Additionally translate from this to lastWindowPeer coordinates
|
||||
Rectangle lr = lastWindowPeer.getBounds();
|
||||
oldp.x += r.x - lr.x;
|
||||
oldp.y += r.y - lr.y;
|
||||
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
|
||||
MouseEvent.MOUSE_EXITED,
|
||||
when, modifiers,
|
||||
oldp.x, oldp.y, screenX, screenY,
|
||||
clickCount, popupTrigger, button));
|
||||
} else {
|
||||
Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
|
||||
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
|
||||
MouseEvent.MOUSE_EXITED,
|
||||
when, modifiers,
|
||||
oldp.x, oldp.y, screenX, screenY,
|
||||
clickCount, popupTrigger, button));
|
||||
}
|
||||
}
|
||||
if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
|
||||
Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
|
||||
} else if(id == MouseEvent.MOUSE_ENTERED) {
|
||||
isMouseOver = true;
|
||||
if (targetPeer != null) {
|
||||
if (targetPeer.isEnabled()) {
|
||||
Point lp = targetPeer.windowToLocal(x, y, this);
|
||||
postEvent(new MouseEvent(targetPeer.getTarget(),
|
||||
MouseEvent.MOUSE_ENTERED,
|
||||
when, modifiers,
|
||||
newp.x, newp.y, screenX, screenY,
|
||||
clickCount, popupTrigger, button));
|
||||
}
|
||||
MouseEvent.MOUSE_ENTERED, when,
|
||||
modifiers, lp.x, lp.y, screenX,
|
||||
screenY, clickCount, popupTrigger,
|
||||
button));
|
||||
}
|
||||
lastCommonMouseEventPeer = targetPeer;
|
||||
lastMouseEventPeer = targetPeer;
|
||||
}
|
||||
} else {
|
||||
PlatformWindow topmostPlatforWindow =
|
||||
platformWindow.getTopmostPlatformWindowUnderMouse();
|
||||
|
||||
LWWindowPeer topmostWindowPeer =
|
||||
topmostPlatforWindow != null ? topmostPlatforWindow.getPeer() : null;
|
||||
|
||||
// topmostWindowPeer == null condition is added for the backward
|
||||
// compatibility with applets. It can be removed when the
|
||||
// getTopmostPlatformWindowUnderMouse() method will be properly
|
||||
// implemented in CPlatformEmbeddedFrame class
|
||||
if (topmostWindowPeer == this || topmostWindowPeer == null) {
|
||||
generateMouseEnterExitEventsForComponents(when, button, x, y,
|
||||
screenX, screenY, modifiers, clickCount, popupTrigger,
|
||||
targetPeer);
|
||||
} else {
|
||||
LWComponentPeer topmostTargetPeer =
|
||||
topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null;
|
||||
topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y,
|
||||
screenX, screenY, modifiers, clickCount, popupTrigger,
|
||||
topmostTargetPeer);
|
||||
}
|
||||
|
||||
// TODO: fill "bdata" member of AWTEvent
|
||||
|
||||
int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
|
||||
@ -794,6 +798,14 @@ public class LWWindowPeer
|
||||
mouseClickButtons |= eventButtonMask;
|
||||
}
|
||||
|
||||
// The window should be focused on mouse click. If it gets activated by the native platform,
|
||||
// this request will be no op. It will take effect when:
|
||||
// 1. A simple not focused window is clicked.
|
||||
// 2. An active but not focused owner frame/dialog is clicked.
|
||||
// The mouse event then will trigger a focus request "in window" to the component, so the window
|
||||
// should gain focus before.
|
||||
requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
|
||||
|
||||
mouseDownTarget[targetIdx] = targetPeer;
|
||||
} else if (id == MouseEvent.MOUSE_DRAGGED) {
|
||||
// Cocoa dragged event has the information about which mouse
|
||||
@ -816,19 +828,13 @@ public class LWWindowPeer
|
||||
// mouseClickButtons is updated below, after MOUSE_CLICK is sent
|
||||
}
|
||||
|
||||
// check if we receive mouseEvent from outside the window's bounds
|
||||
// it can be either mouseDragged or mouseReleased
|
||||
if (curWindowPeer == null) {
|
||||
//TODO This can happen if this window is invisible. this is correct behavior in this case?
|
||||
curWindowPeer = this;
|
||||
}
|
||||
if (targetPeer == null) {
|
||||
//TODO This can happen if this window is invisible. this is correct behavior in this case?
|
||||
targetPeer = this;
|
||||
}
|
||||
|
||||
|
||||
Point lp = targetPeer.windowToLocal(x, y, curWindowPeer);
|
||||
Point lp = targetPeer.windowToLocal(x, y, this);
|
||||
if (targetPeer.isEnabled()) {
|
||||
MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
|
||||
when, modifiers, lp.x, lp.y,
|
||||
@ -852,6 +858,38 @@ public class LWWindowPeer
|
||||
notifyUpdateCursor();
|
||||
}
|
||||
|
||||
private void generateMouseEnterExitEventsForComponents(long when,
|
||||
int button, int x, int y, int screenX, int screenY,
|
||||
int modifiers, int clickCount, boolean popupTrigger,
|
||||
LWComponentPeer targetPeer) {
|
||||
|
||||
if (!isMouseOver || targetPeer == lastMouseEventPeer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate Mouse Exit for components
|
||||
if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
|
||||
Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
|
||||
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
|
||||
MouseEvent.MOUSE_EXITED,
|
||||
when, modifiers,
|
||||
oldp.x, oldp.y, screenX, screenY,
|
||||
clickCount, popupTrigger, button));
|
||||
}
|
||||
lastCommonMouseEventPeer = targetPeer;
|
||||
lastMouseEventPeer = targetPeer;
|
||||
|
||||
// Generate Mouse Enter for components
|
||||
if (targetPeer != null && targetPeer.isEnabled()) {
|
||||
Point newp = targetPeer.windowToLocal(x, y, this);
|
||||
postEvent(new MouseEvent(targetPeer.getTarget(),
|
||||
MouseEvent.MOUSE_ENTERED,
|
||||
when, modifiers,
|
||||
newp.x, newp.y, screenX, screenY,
|
||||
clickCount, popupTrigger, button));
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchMouseWheelEvent(long when, int x, int y, int modifiers,
|
||||
int scrollType, int scrollAmount,
|
||||
int wheelRotation, double preciseWheelRotation,
|
||||
@ -884,20 +922,16 @@ public class LWWindowPeer
|
||||
public void dispatchKeyEvent(int id, long when, int modifiers,
|
||||
int keyCode, char keyChar, int keyLocation)
|
||||
{
|
||||
LWComponentPeer focusOwner =
|
||||
LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
|
||||
getFocusOwner();
|
||||
LWKeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
|
||||
Component focusOwner = kfmPeer.getCurrentFocusOwner();
|
||||
|
||||
// Null focus owner may receive key event when
|
||||
// application hides the focused window upon ESC press
|
||||
// (AWT transfers/clears the focus owner) and pending ESC release
|
||||
// may come to already hidden window. This check eliminates NPE.
|
||||
if (focusOwner != null) {
|
||||
KeyEvent event =
|
||||
new KeyEvent(focusOwner.getTarget(), id, when, modifiers,
|
||||
keyCode, keyChar, keyLocation);
|
||||
focusOwner.postEvent(event);
|
||||
if (focusOwner == null) {
|
||||
focusOwner = kfmPeer.getCurrentFocusedWindow();
|
||||
if (focusOwner == null) {
|
||||
focusOwner = this.getTarget();
|
||||
}
|
||||
}
|
||||
postEvent(new KeyEvent(focusOwner, id, when, modifiers, keyCode, keyChar, keyLocation));
|
||||
}
|
||||
|
||||
|
||||
@ -1096,11 +1130,11 @@ public class LWWindowPeer
|
||||
}
|
||||
|
||||
public static LWWindowPeer getWindowUnderCursor() {
|
||||
return lastMouseEventPeer != null ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
|
||||
return lastCommonMouseEventPeer != null ? lastCommonMouseEventPeer.getWindowPeerOrSelf() : null;
|
||||
}
|
||||
|
||||
public static LWComponentPeer<?, ?> getPeerUnderCursor() {
|
||||
return lastMouseEventPeer;
|
||||
return lastCommonMouseEventPeer;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1213,10 +1247,8 @@ public class LWWindowPeer
|
||||
}
|
||||
}
|
||||
|
||||
LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer.
|
||||
getInstance(getAppContext());
|
||||
|
||||
Window oppositeWindow = becomesFocused ? manager.getCurrentFocusedWindow() : null;
|
||||
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
|
||||
Window oppositeWindow = becomesFocused ? kfmPeer.getCurrentFocusedWindow() : null;
|
||||
|
||||
// Note, the method is not called:
|
||||
// - when the opposite (gaining focus) window is an owned/owner window.
|
||||
@ -1229,10 +1261,10 @@ public class LWWindowPeer
|
||||
grabbingWindow.ungrab();
|
||||
}
|
||||
|
||||
manager.setFocusedWindow(becomesFocused ? LWWindowPeer.this : null);
|
||||
kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
|
||||
|
||||
int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
|
||||
WindowEvent windowEvent = new WindowEvent(getTarget(), eventID, oppositeWindow);
|
||||
WindowEvent windowEvent = new TimedWindowEvent(getTarget(), eventID, oppositeWindow, System.currentTimeMillis());
|
||||
|
||||
// TODO: wrap in SequencedEvent
|
||||
postEvent(windowEvent);
|
||||
|
||||
@ -118,6 +118,8 @@ public interface PlatformWindow {
|
||||
|
||||
public void setAlwaysOnTop(boolean value);
|
||||
|
||||
public PlatformWindow getTopmostPlatformWindowUnderMouse();
|
||||
|
||||
public void updateFocusableWindowState();
|
||||
|
||||
public boolean rejectFocusRequest(CausedFocusEvent.Cause cause);
|
||||
|
||||
@ -151,6 +151,10 @@ public class CPlatformEmbeddedFrame implements PlatformWindow {
|
||||
@Override
|
||||
public void setAlwaysOnTop(boolean value) {}
|
||||
|
||||
// This method should be properly implemented for applets.
|
||||
// It returns null just as a stub.
|
||||
public PlatformWindow getTopmostPlatformWindowUnderMouse() { return null; }
|
||||
|
||||
@Override
|
||||
public void updateFocusableWindowState() {}
|
||||
|
||||
|
||||
@ -61,8 +61,9 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);
|
||||
private static native void nativeSetNSWindowSecurityWarningPositioning(long nsWindowPtr, double x, double y, float biasX, float biasY);
|
||||
private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled);
|
||||
private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr);
|
||||
private static native void nativeSynthesizeMouseEnteredExitedEvents();
|
||||
private static native void nativeDispose(long nsWindowPtr);
|
||||
private static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse();
|
||||
|
||||
private static native int nativeGetNSWindowDisplayID_AppKitThread(long nsWindowPtr);
|
||||
|
||||
@ -588,7 +589,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
}
|
||||
}
|
||||
|
||||
nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
|
||||
nativeSynthesizeMouseEnteredExitedEvents();
|
||||
|
||||
// Configure stuff #2
|
||||
updateFocusabilityForAutoRequestFocus(true);
|
||||
@ -729,6 +730,10 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop);
|
||||
}
|
||||
|
||||
public PlatformWindow getTopmostPlatformWindowUnderMouse(){
|
||||
return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOpacity(float opacity) {
|
||||
CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity);
|
||||
@ -803,7 +808,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
throw new RuntimeException("Unknown window state: " + windowState);
|
||||
}
|
||||
|
||||
nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
|
||||
nativeSynthesizeMouseEnteredExitedEvents();
|
||||
|
||||
// NOTE: the SWP.windowState field gets updated to the newWindowState
|
||||
// value when the native notification comes to us
|
||||
|
||||
@ -33,8 +33,8 @@
|
||||
@private
|
||||
jobject m_cPlatformView;
|
||||
|
||||
// Handler for the tracking rect needed for Enter/Exit events management.
|
||||
NSTrackingRectTag rolloverTrackingRectTag;
|
||||
// Handler for the tracking area needed for Enter/Exit events management.
|
||||
NSTrackingArea* rolloverTrackingArea;
|
||||
|
||||
// TODO: NSMenu *contextualMenu;
|
||||
|
||||
@ -61,7 +61,7 @@
|
||||
|
||||
- (id) initWithRect:(NSRect) rect platformView:(jobject)cPlatformView windowLayer:(CALayer*)windowLayer;
|
||||
- (void) deliverJavaMouseEvent: (NSEvent *) event;
|
||||
- (void) resetTrackingRect;
|
||||
- (void) resetTrackingArea;
|
||||
- (void) deliverJavaKeyEventHelper: (NSEvent *) event;
|
||||
- (jobject) awtComponent:(JNIEnv *)env;
|
||||
|
||||
|
||||
@ -82,6 +82,7 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
fPAHNeedsToSelect = NO;
|
||||
|
||||
mouseIsOver = NO;
|
||||
[self resetTrackingArea];
|
||||
|
||||
if (windowLayer != nil) {
|
||||
self.cglLayer = windowLayer;
|
||||
@ -146,7 +147,7 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
[[self window] makeFirstResponder: self];
|
||||
}];
|
||||
if ([self window] != NULL) {
|
||||
[self resetTrackingRect];
|
||||
[self resetTrackingArea];
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,30 +369,31 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent);
|
||||
}
|
||||
|
||||
|
||||
- (void) clearTrackingRect {
|
||||
if (rolloverTrackingRectTag > 0) {
|
||||
[self removeTrackingRect:rolloverTrackingRectTag];
|
||||
rolloverTrackingRectTag = 0;
|
||||
- (void) resetTrackingArea {
|
||||
if (rolloverTrackingArea != nil) {
|
||||
[self removeTrackingArea:rolloverTrackingArea];
|
||||
[rolloverTrackingArea release];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) resetTrackingRect {
|
||||
[self clearTrackingRect];
|
||||
rolloverTrackingRectTag = [self addTrackingRect:[self visibleRect]
|
||||
owner:self
|
||||
userData:NULL
|
||||
assumeInside:NO];
|
||||
int options = (NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited |
|
||||
NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag);
|
||||
|
||||
rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect]
|
||||
options: options
|
||||
owner:self
|
||||
userInfo:nil
|
||||
];
|
||||
[self addTrackingArea:rolloverTrackingArea];
|
||||
}
|
||||
|
||||
- (void)updateTrackingAreas {
|
||||
[super updateTrackingAreas];
|
||||
[self resetTrackingRect];
|
||||
[self resetTrackingArea];
|
||||
}
|
||||
|
||||
- (void) resetCursorRects {
|
||||
[super resetCursorRects];
|
||||
[self resetTrackingRect];
|
||||
[self resetTrackingArea];
|
||||
}
|
||||
|
||||
-(void) deliverJavaKeyEventHelper: (NSEvent *) event {
|
||||
@ -402,7 +404,7 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
}
|
||||
[sLastKeyEvent release];
|
||||
sLastKeyEvent = [event retain];
|
||||
|
||||
|
||||
[AWTToolkit eventCountPlusPlus];
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
|
||||
@ -238,10 +238,12 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
return self;
|
||||
}
|
||||
|
||||
// checks that this window is under the mouse cursor and this point is not overlapped by others windows
|
||||
- (BOOL) isTopmostWindowUnderMouse {
|
||||
+ (BOOL) isAWTWindow:(NSWindow *)window {
|
||||
return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];
|
||||
}
|
||||
|
||||
int currentWinID = [self.nsWindow windowNumber];
|
||||
// returns id for the topmost window under mouse
|
||||
+ (NSInteger) getTopmostWindowUnderMouseID {
|
||||
|
||||
NSRect screenRect = [[NSScreen mainScreen] frame];
|
||||
NSPoint nsMouseLocation = [NSEvent mouseLocation];
|
||||
@ -249,53 +251,77 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
|
||||
|
||||
|
||||
for (NSDictionary *window in windows) {
|
||||
int layer = [[window objectForKey:(id)kCGWindowLayer] intValue];
|
||||
NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue];
|
||||
if (layer == 0) {
|
||||
int winID = [[window objectForKey:(id)kCGWindowNumber] intValue];
|
||||
CGRect rect;
|
||||
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
|
||||
if (CGRectContainsPoint(rect, cgMouseLocation)) {
|
||||
return currentWinID == winID;
|
||||
} else if (currentWinID == winID) {
|
||||
return NO;
|
||||
return [[window objectForKey:(id)kCGWindowNumber] integerValue];
|
||||
}
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
- (void) synthesizeMouseEnteredExitedEvents {
|
||||
// checks that this window is under the mouse cursor and this point is not overlapped by others windows
|
||||
- (BOOL) isTopmostWindowUnderMouse {
|
||||
return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];
|
||||
}
|
||||
|
||||
int eventType = 0;
|
||||
BOOL isUnderMouse = [self isTopmostWindowUnderMouse];
|
||||
BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver];
|
||||
+ (AWTWindow *) getTopmostWindowUnderMouse {
|
||||
NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];
|
||||
NSWindow *window;
|
||||
|
||||
if (isUnderMouse && !mouseIsOver) {
|
||||
eventType = NSMouseEntered;
|
||||
} else if (!isUnderMouse && mouseIsOver) {
|
||||
eventType = NSMouseExited;
|
||||
} else {
|
||||
return;
|
||||
NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
|
||||
|
||||
while ((window = [windowEnumerator nextObject]) != nil) {
|
||||
if ([window windowNumber] == topmostWindowUnderMouseID) {
|
||||
BOOL isAWTWindow = [AWTWindow isAWTWindow: window];
|
||||
return isAWTWindow ? (AWTWindow *) [window delegate] : nil;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (void) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType {
|
||||
|
||||
NSPoint screenLocation = [NSEvent mouseLocation];
|
||||
NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation];
|
||||
NSPoint windowLocation = [window convertScreenToBase: screenLocation];
|
||||
int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
|
||||
|
||||
NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
|
||||
location: windowLocation
|
||||
modifierFlags: modifierFlags
|
||||
timestamp: 0
|
||||
windowNumber: [self.nsWindow windowNumber]
|
||||
context: nil
|
||||
eventNumber: 0
|
||||
trackingNumber: 0
|
||||
userData: nil
|
||||
];
|
||||
location: windowLocation
|
||||
modifierFlags: modifierFlags
|
||||
timestamp: 0
|
||||
windowNumber: [window windowNumber]
|
||||
context: nil
|
||||
eventNumber: 0
|
||||
trackingNumber: 0
|
||||
userData: nil
|
||||
];
|
||||
|
||||
[[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];
|
||||
[[window contentView] deliverJavaMouseEvent: mouseEvent];
|
||||
}
|
||||
|
||||
+ (void) synthesizeMouseEnteredExitedEventsForAllWindows {
|
||||
|
||||
NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
|
||||
NSArray *windows = [NSApp windows];
|
||||
NSWindow *window;
|
||||
|
||||
NSEnumerator *windowEnumerator = [windows objectEnumerator];
|
||||
while ((window = [windowEnumerator nextObject]) != nil) {
|
||||
if ([AWTWindow isAWTWindow: window]) {
|
||||
BOOL isUnderMouse = ([window windowNumber] == topmostWindowUnderMouseID);
|
||||
BOOL mouseIsOver = [[window contentView] mouseIsOver];
|
||||
if (isUnderMouse && !mouseIsOver) {
|
||||
[AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseEntered];
|
||||
} else if (!isUnderMouse && mouseIsOver) {
|
||||
[AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseExited];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) dealloc {
|
||||
@ -825,7 +851,7 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
|
||||
// (this will also re-enable screen updates, which were disabled above)
|
||||
// TODO: send PaintEvent
|
||||
|
||||
[window synthesizeMouseEnteredExitedEvents];
|
||||
[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
|
||||
}];
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
@ -1038,24 +1064,44 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CPlatformWindow
|
||||
* Method: nativeGetTopmostPlatformWindowUnderMouse
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT jobject
|
||||
JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse
|
||||
(JNIEnv *env, jclass clazz)
|
||||
{
|
||||
jobject topmostWindowUnderMouse = nil;
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse];
|
||||
if (awtWindow != nil) {
|
||||
topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject];
|
||||
}
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
return topmostWindowUnderMouse;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CPlatformWindow
|
||||
* Method: nativeSynthesizeMouseEnteredExitedEvents
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
|
||||
(JNIEnv *env, jclass clazz, jlong windowPtr)
|
||||
(JNIEnv *env, jclass clazz)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
AWT_ASSERT_NOT_APPKIT_THREAD;
|
||||
|
||||
NSWindow *nsWindow = OBJC(windowPtr);
|
||||
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
|
||||
|
||||
[window synthesizeMouseEnteredExitedEvents];
|
||||
[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
|
||||
}];
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
@ -30,6 +30,8 @@ import java.awt.Container;
|
||||
import java.awt.Event;
|
||||
import java.awt.KeyEventPostProcessor;
|
||||
import java.awt.Window;
|
||||
import java.awt.Toolkit;
|
||||
import sun.awt.SunToolkit;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
@ -125,7 +127,19 @@ public class WindowsRootPaneUI extends BasicRootPaneUI {
|
||||
}
|
||||
JMenu menu = mbar != null ? mbar.getMenu(0) : null;
|
||||
|
||||
if (menu != null) {
|
||||
// It might happen that the altRelease event is processed
|
||||
// with a reasonable delay since it has been generated.
|
||||
// Here we check the last deactivation time of the containing
|
||||
// window. If this time appears to be greater than the altRelease
|
||||
// event time the event is skipped to avoid unexpected menu
|
||||
// activation. See 7121442.
|
||||
boolean skip = false;
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
if (tk instanceof SunToolkit) {
|
||||
skip = ev.getWhen() <= ((SunToolkit)tk).getWindowDeactivationTime(winAncestor);
|
||||
}
|
||||
|
||||
if (menu != null && !skip) {
|
||||
MenuElement[] path = new MenuElement[2];
|
||||
path[0] = mbar;
|
||||
path[1] = menu;
|
||||
|
||||
@ -4710,7 +4710,10 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
/*
|
||||
* 0. Set timestamp and modifiers of current event.
|
||||
*/
|
||||
EventQueue.setCurrentEventAndMostRecentTime(e);
|
||||
if (!(e instanceof KeyEvent)) {
|
||||
// Timestamp of a key event is set later in DKFM.preDispatchKeyEvent(KeyEvent).
|
||||
EventQueue.setCurrentEventAndMostRecentTime(e);
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Pre-dispatchers. Do any necessary retargeting/reordering here
|
||||
@ -7606,13 +7609,33 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
boolean focusedWindowChangeAllowed,
|
||||
CausedFocusEvent.Cause cause)
|
||||
{
|
||||
// 1) Check if the event being dispatched is a system-generated mouse event.
|
||||
AWTEvent currentEvent = EventQueue.getCurrentEvent();
|
||||
if (currentEvent instanceof MouseEvent &&
|
||||
SunToolkit.isSystemGenerated(currentEvent))
|
||||
{
|
||||
// 2) Sanity check: if the mouse event component source belongs to the same containing window.
|
||||
Component source = ((MouseEvent)currentEvent).getComponent();
|
||||
if (source == null || source.getContainingWindow() == getContainingWindow()) {
|
||||
focusLog.finest("requesting focus by mouse event \"in window\"");
|
||||
|
||||
// If both the conditions are fulfilled the focus request should be strictly
|
||||
// bounded by the toplevel window. It's assumed that the mouse event activates
|
||||
// the window (if it wasn't active) and this makes it possible for a focus
|
||||
// request with a strong in-window requirement to change focus in the bounds
|
||||
// of the toplevel. If, by any means, due to asynchronous nature of the event
|
||||
// dispatching mechanism, the window happens to be natively inactive by the time
|
||||
// this focus request is eventually handled, it should not re-activate the
|
||||
// toplevel. Otherwise the result may not meet user expectations. See 6981400.
|
||||
focusedWindowChangeAllowed = false;
|
||||
}
|
||||
}
|
||||
if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) {
|
||||
if (focusLog.isLoggable(PlatformLogger.FINEST)) {
|
||||
focusLog.finest("requestFocus is not accepted");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update most-recent map
|
||||
KeyboardFocusManager.setMostRecentFocusOwner(this);
|
||||
|
||||
@ -7645,7 +7668,15 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
}
|
||||
|
||||
// Focus this Component
|
||||
long time = EventQueue.getMostRecentEventTime();
|
||||
long time = 0;
|
||||
if (EventQueue.isDispatchThread()) {
|
||||
time = Toolkit.getEventQueue().getMostRecentKeyEventTime();
|
||||
} else {
|
||||
// A focus request made from outside EDT should not be associated with any event
|
||||
// and so its time stamp is simply set to the current time.
|
||||
time = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
boolean success = peer.requestFocus
|
||||
(this, temporary, focusedWindowChangeAllowed, time, cause);
|
||||
if (!success) {
|
||||
|
||||
@ -2863,7 +2863,7 @@ public class Container extends Component {
|
||||
|
||||
// keep the KeyEvents from being dispatched
|
||||
// until the focus has been transfered
|
||||
long time = Toolkit.getEventQueue().getMostRecentEventTime();
|
||||
long time = Toolkit.getEventQueue().getMostRecentKeyEventTime();
|
||||
Component predictedFocusOwner = (Component.isInstanceOf(this, "javax.swing.JInternalFrame")) ? ((javax.swing.JInternalFrame)(this)).getMostRecentFocusOwner() : null;
|
||||
if (predictedFocusOwner != null) {
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().
|
||||
|
||||
@ -41,6 +41,7 @@ import sun.awt.AppContext;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.awt.CausedFocusEvent;
|
||||
import sun.awt.TimedWindowEvent;
|
||||
|
||||
/**
|
||||
* The default KeyboardFocusManager for AWT applications. Focus traversal is
|
||||
@ -72,8 +73,8 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
private WeakReference<Window> realOppositeWindowWR = NULL_WINDOW_WR;
|
||||
private WeakReference<Component> realOppositeComponentWR = NULL_COMPONENT_WR;
|
||||
private int inSendMessage;
|
||||
private LinkedList enqueuedKeyEvents = new LinkedList(),
|
||||
typeAheadMarkers = new LinkedList();
|
||||
private LinkedList<KeyEvent> enqueuedKeyEvents = new LinkedList<KeyEvent>();
|
||||
private LinkedList<TypeAheadMarker> typeAheadMarkers = new LinkedList<TypeAheadMarker>();
|
||||
private boolean consumeNextKeyTyped;
|
||||
|
||||
static {
|
||||
@ -269,6 +270,31 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
return se.dispatched;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if the focus window event follows key events waiting in the type-ahead
|
||||
* queue (if any). This may happen when a user types ahead in the window, the client
|
||||
* listeners hang EDT for a while, and the user switches b/w toplevels. In that
|
||||
* case the focus window events may be dispatched before the type-ahead events
|
||||
* get handled. This may lead to wrong focus behavior and in order to avoid it,
|
||||
* the focus window events are reposted to the end of the event queue. See 6981400.
|
||||
*/
|
||||
private boolean repostIfFollowsKeyEvents(WindowEvent e) {
|
||||
if (!(e instanceof TimedWindowEvent)) {
|
||||
return false;
|
||||
}
|
||||
TimedWindowEvent we = (TimedWindowEvent)e;
|
||||
long time = we.getWhen();
|
||||
synchronized (this) {
|
||||
for (KeyEvent ke: enqueuedKeyEvents) {
|
||||
if (time >= ke.getWhen()) {
|
||||
SunToolkit.postEvent(AppContext.getAppContext(), new SequencedEvent(e));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by the AWT event dispatcher requesting that the
|
||||
* current KeyboardFocusManager dispatch the specified event on its behalf.
|
||||
@ -287,6 +313,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
if (focusLog.isLoggable(PlatformLogger.FINE) && (e instanceof WindowEvent || e instanceof FocusEvent)) focusLog.fine("" + e);
|
||||
switch (e.getID()) {
|
||||
case WindowEvent.WINDOW_GAINED_FOCUS: {
|
||||
if (repostIfFollowsKeyEvents((WindowEvent)e)) {
|
||||
break;
|
||||
}
|
||||
|
||||
WindowEvent we = (WindowEvent)e;
|
||||
Window oldFocusedWindow = getGlobalFocusedWindow();
|
||||
Window newFocusedWindow = we.getWindow();
|
||||
@ -646,6 +676,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
}
|
||||
|
||||
case WindowEvent.WINDOW_LOST_FOCUS: {
|
||||
if (repostIfFollowsKeyEvents((WindowEvent)e)) {
|
||||
break;
|
||||
}
|
||||
|
||||
WindowEvent we = (WindowEvent)e;
|
||||
Window currentFocusedWindow = getGlobalFocusedWindow();
|
||||
Window losingFocusWindow = we.getWindow();
|
||||
@ -825,10 +859,9 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
ke = null;
|
||||
synchronized (this) {
|
||||
if (enqueuedKeyEvents.size() != 0) {
|
||||
ke = (KeyEvent)enqueuedKeyEvents.getFirst();
|
||||
ke = enqueuedKeyEvents.getFirst();
|
||||
if (typeAheadMarkers.size() != 0) {
|
||||
TypeAheadMarker marker = (TypeAheadMarker)
|
||||
typeAheadMarkers.getFirst();
|
||||
TypeAheadMarker marker = typeAheadMarkers.getFirst();
|
||||
// Fixed 5064013: may appears that the events have the same time
|
||||
// if (ke.getWhen() >= marker.after) {
|
||||
// The fix is rolled out.
|
||||
@ -857,9 +890,9 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
focusLog.finest(">>> Markers dump, time: {0}", System.currentTimeMillis());
|
||||
synchronized (this) {
|
||||
if (typeAheadMarkers.size() != 0) {
|
||||
Iterator iter = typeAheadMarkers.iterator();
|
||||
Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator();
|
||||
while (iter.hasNext()) {
|
||||
TypeAheadMarker marker = (TypeAheadMarker)iter.next();
|
||||
TypeAheadMarker marker = iter.next();
|
||||
focusLog.finest(" {0}", marker);
|
||||
}
|
||||
}
|
||||
@ -881,8 +914,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
KeyEvent ke = (KeyEvent)e;
|
||||
synchronized (this) {
|
||||
if (e.isPosted && typeAheadMarkers.size() != 0) {
|
||||
TypeAheadMarker marker = (TypeAheadMarker)
|
||||
typeAheadMarkers.getFirst();
|
||||
TypeAheadMarker marker = typeAheadMarkers.getFirst();
|
||||
// Fixed 5064013: may appears that the events have the same time
|
||||
// if (ke.getWhen() >= marker.after) {
|
||||
// The fix is rolled out.
|
||||
@ -915,12 +947,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
synchronized (this) {
|
||||
boolean found = false;
|
||||
if (hasMarker(target)) {
|
||||
for (Iterator iter = typeAheadMarkers.iterator();
|
||||
for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator();
|
||||
iter.hasNext(); )
|
||||
{
|
||||
if (((TypeAheadMarker)iter.next()).untilFocused ==
|
||||
target)
|
||||
{
|
||||
if (iter.next().untilFocused == target) {
|
||||
found = true;
|
||||
} else if (found) {
|
||||
break;
|
||||
@ -955,8 +985,8 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
* @since 1.5
|
||||
*/
|
||||
private boolean hasMarker(Component comp) {
|
||||
for (Iterator iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
|
||||
if (((TypeAheadMarker)iter.next()).untilFocused == comp) {
|
||||
for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
|
||||
if (iter.next().untilFocused == comp) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -982,11 +1012,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Explicitly set the current event and most recent timestamp here in
|
||||
// addition to the call in Component.dispatchEventImpl. Because
|
||||
// KeyEvents can be delivered in response to a FOCUS_GAINED event, the
|
||||
// current timestamp may be incorrect. We need to set it here so that
|
||||
// KeyEventDispatchers will use the correct time.
|
||||
// Explicitly set the key event timestamp here (not in Component.dispatchEventImpl):
|
||||
// - A key event is anyway passed to this method which starts its actual dispatching.
|
||||
// - If a key event is put to the type ahead queue, its time stamp should not be registered
|
||||
// until its dispatching actually starts (by this method).
|
||||
EventQueue.setCurrentEventAndMostRecentTime(ke);
|
||||
|
||||
/**
|
||||
@ -1174,10 +1203,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
|
||||
int insertionIndex = 0,
|
||||
i = typeAheadMarkers.size();
|
||||
ListIterator iter = typeAheadMarkers.listIterator(i);
|
||||
ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator(i);
|
||||
|
||||
for (; i > 0; i--) {
|
||||
TypeAheadMarker marker = (TypeAheadMarker)iter.previous();
|
||||
TypeAheadMarker marker = iter.previous();
|
||||
if (marker.after <= after) {
|
||||
insertionIndex = i;
|
||||
break;
|
||||
@ -1213,12 +1242,12 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
after, untilFocused);
|
||||
|
||||
TypeAheadMarker marker;
|
||||
ListIterator iter = typeAheadMarkers.listIterator
|
||||
ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator
|
||||
((after >= 0) ? typeAheadMarkers.size() : 0);
|
||||
|
||||
if (after < 0) {
|
||||
while (iter.hasNext()) {
|
||||
marker = (TypeAheadMarker)iter.next();
|
||||
marker = iter.next();
|
||||
if (marker.untilFocused == untilFocused)
|
||||
{
|
||||
iter.remove();
|
||||
@ -1227,7 +1256,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
}
|
||||
} else {
|
||||
while (iter.hasPrevious()) {
|
||||
marker = (TypeAheadMarker)iter.previous();
|
||||
marker = iter.previous();
|
||||
if (marker.untilFocused == untilFocused &&
|
||||
marker.after == after)
|
||||
{
|
||||
@ -1255,8 +1284,8 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
|
||||
long start = -1;
|
||||
|
||||
for (Iterator iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
|
||||
TypeAheadMarker marker = (TypeAheadMarker)iter.next();
|
||||
for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
|
||||
TypeAheadMarker marker = iter.next();
|
||||
Component toTest = marker.untilFocused;
|
||||
boolean match = (toTest == comp);
|
||||
while (!match && toTest != null && !(toTest instanceof Window)) {
|
||||
@ -1287,8 +1316,8 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Iterator iter = enqueuedKeyEvents.iterator(); iter.hasNext(); ) {
|
||||
KeyEvent ke = (KeyEvent)iter.next();
|
||||
for (Iterator<KeyEvent> iter = enqueuedKeyEvents.iterator(); iter.hasNext(); ) {
|
||||
KeyEvent ke = iter.next();
|
||||
long time = ke.getWhen();
|
||||
|
||||
if (start < time && (end < 0 || time <= end)) {
|
||||
|
||||
@ -924,7 +924,7 @@ public class Dialog extends Window {
|
||||
isEnabled() && !isModalBlocked()) {
|
||||
// keep the KeyEvents from being dispatched
|
||||
// until the focus has been transfered
|
||||
time.set(Toolkit.getEventQueue().getMostRecentEventTimeEx());
|
||||
time.set(Toolkit.getEventQueue().getMostRecentKeyEventTime());
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().
|
||||
enqueueKeyEvents(time.get(), toFocus);
|
||||
}
|
||||
|
||||
@ -162,6 +162,11 @@ public class EventQueue {
|
||||
*/
|
||||
private long mostRecentEventTime = System.currentTimeMillis();
|
||||
|
||||
/*
|
||||
* The time stamp of the last KeyEvent .
|
||||
*/
|
||||
private long mostRecentKeyEventTime = System.currentTimeMillis();
|
||||
|
||||
/**
|
||||
* The modifiers field of the current event, if the current event is an
|
||||
* InputEvent or ActionEvent.
|
||||
@ -1142,6 +1147,15 @@ public class EventQueue {
|
||||
}
|
||||
}
|
||||
|
||||
synchronized long getMostRecentKeyEventTime() {
|
||||
pushPopLock.lock();
|
||||
try {
|
||||
return mostRecentKeyEventTime;
|
||||
} finally {
|
||||
pushPopLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static void setCurrentEventAndMostRecentTime(AWTEvent e) {
|
||||
Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e);
|
||||
}
|
||||
@ -1166,6 +1180,9 @@ public class EventQueue {
|
||||
if (e instanceof InputEvent) {
|
||||
InputEvent ie = (InputEvent)e;
|
||||
mostRecentEventTime2 = ie.getWhen();
|
||||
if (e instanceof KeyEvent) {
|
||||
mostRecentKeyEventTime = ie.getWhen();
|
||||
}
|
||||
} else if (e instanceof InputMethodEvent) {
|
||||
InputMethodEvent ime = (InputMethodEvent)e;
|
||||
mostRecentEventTime2 = ime.getWhen();
|
||||
|
||||
@ -445,7 +445,7 @@ public abstract class KeyboardFocusManager
|
||||
private void initPeer() {
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
KeyboardFocusManagerPeerProvider peerProvider = (KeyboardFocusManagerPeerProvider)tk;
|
||||
peer = peerProvider.createKeyboardFocusManagerPeer(this);
|
||||
peer = peerProvider.getKeyboardFocusManagerPeer();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
package java.awt;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.awt.AppContext;
|
||||
import sun.awt.SunToolkit;
|
||||
|
||||
@ -54,6 +55,17 @@ class SequencedEvent extends AWTEvent implements ActiveEvent {
|
||||
private AppContext appContext;
|
||||
private boolean disposed;
|
||||
|
||||
static {
|
||||
AWTAccessor.setSequencedEventAccessor(new AWTAccessor.SequencedEventAccessor() {
|
||||
public AWTEvent getNested(AWTEvent sequencedEvent) {
|
||||
return ((SequencedEvent)sequencedEvent).nested;
|
||||
}
|
||||
public boolean isSequencedEvent(AWTEvent event) {
|
||||
return event instanceof SequencedEvent;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new SequencedEvent which will dispatch the specified
|
||||
* nested event.
|
||||
|
||||
@ -33,6 +33,14 @@ import java.awt.Window;
|
||||
*/
|
||||
public interface KeyboardFocusManagerPeer {
|
||||
|
||||
/**
|
||||
* Sets the window that should become the focused window.
|
||||
*
|
||||
* @param win the window that should become the focused window
|
||||
*
|
||||
*/
|
||||
void setCurrentFocusedWindow(Window win);
|
||||
|
||||
/**
|
||||
* Returns the currently focused window.
|
||||
*
|
||||
|
||||
@ -1460,7 +1460,7 @@ class GenericBeanInfo extends SimpleBeanInfo {
|
||||
private PropertyDescriptor[] properties;
|
||||
private int defaultProperty;
|
||||
private MethodDescriptor[] methods;
|
||||
private final Reference<BeanInfo> targetBeanInfoRef;
|
||||
private Reference<BeanInfo> targetBeanInfoRef;
|
||||
|
||||
public GenericBeanInfo(BeanDescriptor beanDescriptor,
|
||||
EventSetDescriptor[] events, int defaultEvent,
|
||||
@ -1472,7 +1472,9 @@ class GenericBeanInfo extends SimpleBeanInfo {
|
||||
this.properties = properties;
|
||||
this.defaultProperty = defaultProperty;
|
||||
this.methods = methods;
|
||||
this.targetBeanInfoRef = new SoftReference<>(targetBeanInfo);
|
||||
this.targetBeanInfoRef = (targetBeanInfo != null)
|
||||
? new SoftReference<>(targetBeanInfo)
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1539,10 +1541,25 @@ class GenericBeanInfo extends SimpleBeanInfo {
|
||||
}
|
||||
|
||||
public java.awt.Image getIcon(int iconKind) {
|
||||
BeanInfo targetBeanInfo = this.targetBeanInfoRef.get();
|
||||
BeanInfo targetBeanInfo = getTargetBeanInfo();
|
||||
if (targetBeanInfo != null) {
|
||||
return targetBeanInfo.getIcon(iconKind);
|
||||
}
|
||||
return super.getIcon(iconKind);
|
||||
}
|
||||
|
||||
private BeanInfo getTargetBeanInfo() {
|
||||
if (this.targetBeanInfoRef == null) {
|
||||
return null;
|
||||
}
|
||||
BeanInfo targetBeanInfo = this.targetBeanInfoRef.get();
|
||||
if (targetBeanInfo == null) {
|
||||
targetBeanInfo = ThreadGroupContext.getContext().getBeanInfoFinder()
|
||||
.find(this.beanDescriptor.getBeanClass());
|
||||
if (targetBeanInfo != null) {
|
||||
this.targetBeanInfoRef = new SoftReference<>(targetBeanInfo);
|
||||
}
|
||||
}
|
||||
return targetBeanInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,6 +109,10 @@ public class PropertyDescriptor extends FeatureDescriptor {
|
||||
if (writeMethodName != null && getWriteMethod() == null) {
|
||||
throw new IntrospectionException("Method not found: " + writeMethodName);
|
||||
}
|
||||
boundInitialization(beanClass);
|
||||
}
|
||||
|
||||
private void boundInitialization(Class<?> beanClass) {
|
||||
// If this class or one of its base classes allow PropertyChangeListener,
|
||||
// then we assume that any properties we discover are "bound".
|
||||
// See Introspector.getTargetPropertyInfo() method.
|
||||
@ -159,6 +163,7 @@ public class PropertyDescriptor extends FeatureDescriptor {
|
||||
setReadMethod(read);
|
||||
setWriteMethod(write);
|
||||
this.baseName = base;
|
||||
boundInitialization(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -588,7 +593,7 @@ public class PropertyDescriptor extends FeatureDescriptor {
|
||||
Method yw = y.getWriteMethod();
|
||||
|
||||
try {
|
||||
if (yw != null && yw.getDeclaringClass() == getClass0()) {
|
||||
if (yw != null) {
|
||||
setWriteMethod(yw);
|
||||
} else {
|
||||
setWriteMethod(xw);
|
||||
|
||||
@ -631,7 +631,12 @@ public class XMLEncoder extends Encoder implements AutoCloseable {
|
||||
}
|
||||
|
||||
if (d.name != null) {
|
||||
outputXML(isArgument ? "object" : "void", " idref=" + quote(d.name), value);
|
||||
if (isArgument) {
|
||||
writeln("<object idref=" + quote(d.name) + "/>");
|
||||
}
|
||||
else {
|
||||
outputXML("void", " idref=" + quote(d.name), value);
|
||||
}
|
||||
}
|
||||
else if (d.exp != null) {
|
||||
outputStatement(d.exp, outer, isArgument);
|
||||
@ -710,12 +715,14 @@ public class XMLEncoder extends Encoder implements AutoCloseable {
|
||||
}
|
||||
else {
|
||||
d.refs = 2;
|
||||
getValueData(target).refs++;
|
||||
List<Statement> statements = statementList(target);
|
||||
if (!statements.contains(exp)) {
|
||||
statements.add(exp);
|
||||
if (d.name == null) {
|
||||
getValueData(target).refs++;
|
||||
List<Statement> statements = statementList(target);
|
||||
if (!statements.contains(exp)) {
|
||||
statements.add(exp);
|
||||
}
|
||||
outputValue(target, outer, false);
|
||||
}
|
||||
outputValue(target, outer, false);
|
||||
if (expression) {
|
||||
outputValue(value, outer, isArgument);
|
||||
}
|
||||
|
||||
@ -666,6 +666,21 @@ public final class AWTAccessor {
|
||||
public void consumeNextKeyTyped(DefaultKeyboardFocusManager dkfm, KeyEvent e);
|
||||
}
|
||||
|
||||
/*
|
||||
* An accessor for the SequencedEventAccessor class
|
||||
*/
|
||||
public interface SequencedEventAccessor {
|
||||
/*
|
||||
* Returns the nested event.
|
||||
*/
|
||||
AWTEvent getNested(AWTEvent sequencedEvent);
|
||||
|
||||
/*
|
||||
* Returns true if the event is an instances of SequencedEvent.
|
||||
*/
|
||||
boolean isSequencedEvent(AWTEvent event);
|
||||
}
|
||||
|
||||
/*
|
||||
* Accessor instances are initialized in the static initializers of
|
||||
* corresponding AWT classes by using setters defined below.
|
||||
@ -692,6 +707,7 @@ public final class AWTAccessor {
|
||||
private static SystemTrayAccessor systemTrayAccessor;
|
||||
private static TrayIconAccessor trayIconAccessor;
|
||||
private static DefaultKeyboardFocusManagerAccessor defaultKeyboardFocusManagerAccessor;
|
||||
private static SequencedEventAccessor sequencedEventAccessor;
|
||||
|
||||
/*
|
||||
* Set an accessor object for the java.awt.Component class.
|
||||
@ -1069,4 +1085,20 @@ public final class AWTAccessor {
|
||||
}
|
||||
return defaultKeyboardFocusManagerAccessor;
|
||||
}
|
||||
/*
|
||||
* Set an accessor object for the java.awt.SequencedEvent class.
|
||||
*/
|
||||
public static void setSequencedEventAccessor(SequencedEventAccessor sea) {
|
||||
sequencedEventAccessor = sea;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the accessor object for the java.awt.SequencedEvent class.
|
||||
*/
|
||||
public static SequencedEventAccessor getSequencedEventAccessor() {
|
||||
// The class is not public. So we can't ensure it's initialized.
|
||||
// Null returned value means it's not initialized
|
||||
// (so not a single instance of the event has been created).
|
||||
return sequencedEventAccessor;
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,6 +44,14 @@ import java.util.Properties;
|
||||
public class HToolkit extends SunToolkit
|
||||
implements ComponentFactory {
|
||||
|
||||
private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
|
||||
public void setCurrentFocusedWindow(Window win) {}
|
||||
public Window getCurrentFocusedWindow() { return null; }
|
||||
public void setCurrentFocusOwner(Component comp) {}
|
||||
public Component getCurrentFocusOwner() { return null; }
|
||||
public void clearGlobalFocusOwner(Window activeWindow) {}
|
||||
};
|
||||
|
||||
public HToolkit() {
|
||||
}
|
||||
|
||||
@ -152,15 +160,9 @@ public class HToolkit extends SunToolkit
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
|
||||
public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
|
||||
// See 6833019.
|
||||
return
|
||||
new KeyboardFocusManagerPeer() {
|
||||
public Window getCurrentFocusedWindow() { return null; }
|
||||
public void setCurrentFocusOwner(Component comp) {}
|
||||
public Component getCurrentFocusOwner() { return null; }
|
||||
public void clearGlobalFocusOwner(Window activeWindow) {}
|
||||
};
|
||||
return kfmPeer;
|
||||
}
|
||||
|
||||
public TrayIconPeer createTrayIcon(TrayIcon target)
|
||||
|
||||
@ -30,22 +30,25 @@ import java.awt.dnd.*;
|
||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||
import java.awt.event.*;
|
||||
import java.awt.im.InputMethodHighlight;
|
||||
import java.awt.im.spi.InputMethodDescriptor;
|
||||
import java.awt.image.*;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.peer.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import sun.awt.im.InputContext;
|
||||
import sun.awt.image.ImageRepresentation;
|
||||
|
||||
public class HeadlessToolkit extends Toolkit
|
||||
implements ComponentFactory, KeyboardFocusManagerPeerProvider {
|
||||
|
||||
private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
|
||||
public void setCurrentFocusedWindow(Window win) {}
|
||||
public Window getCurrentFocusedWindow() { return null; }
|
||||
public void setCurrentFocusOwner(Component comp) {}
|
||||
public Component getCurrentFocusOwner() { return null; }
|
||||
public void clearGlobalFocusOwner(Window activeWindow) {}
|
||||
};
|
||||
|
||||
private Toolkit tk;
|
||||
private ComponentFactory componentFactory;
|
||||
|
||||
@ -179,15 +182,9 @@ public class HeadlessToolkit extends Toolkit
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
|
||||
public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
|
||||
// See 6833019.
|
||||
return
|
||||
new KeyboardFocusManagerPeer() {
|
||||
public Window getCurrentFocusedWindow() { return null; }
|
||||
public void setCurrentFocusOwner(Component comp) {}
|
||||
public Component getCurrentFocusOwner() { return null; }
|
||||
public void clearGlobalFocusOwner(Window activeWindow) {}
|
||||
};
|
||||
return kfmPeer;
|
||||
}
|
||||
|
||||
public TrayIconPeer createTrayIcon(TrayIcon target)
|
||||
|
||||
@ -53,12 +53,6 @@ public abstract class KeyboardFocusManagerPeerImpl implements KeyboardFocusManag
|
||||
public static final int SNFH_SUCCESS_HANDLED = 1;
|
||||
public static final int SNFH_SUCCESS_PROCEED = 2;
|
||||
|
||||
protected KeyboardFocusManager manager;
|
||||
|
||||
public KeyboardFocusManagerPeerImpl(KeyboardFocusManager manager) {
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearGlobalFocusOwner(Window activeWindow) {
|
||||
if (activeWindow != null) {
|
||||
@ -134,7 +128,7 @@ public abstract class KeyboardFocusManagerPeerImpl implements KeyboardFocusManag
|
||||
|
||||
if (focusLog.isLoggable(PlatformLogger.FINER))
|
||||
focusLog.finer("Posting focus event: " + fl);
|
||||
SunToolkit.postPriorityEvent(fl);
|
||||
SunToolkit.postEvent(SunToolkit.targetToAppContext(currentOwner), fl);
|
||||
}
|
||||
|
||||
FocusEvent fg = new CausedFocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED,
|
||||
@ -142,7 +136,7 @@ public abstract class KeyboardFocusManagerPeerImpl implements KeyboardFocusManag
|
||||
|
||||
if (focusLog.isLoggable(PlatformLogger.FINER))
|
||||
focusLog.finer("Posting focus event: " + fg);
|
||||
SunToolkit.postPriorityEvent(fg);
|
||||
SunToolkit.postEvent(SunToolkit.targetToAppContext(lightweightChild), fg);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -25,20 +25,19 @@
|
||||
|
||||
package sun.awt;
|
||||
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.peer.KeyboardFocusManagerPeer;
|
||||
|
||||
/**
|
||||
* {@link KeyboardFocusManagerPeerProvider} is required to be implemented by
|
||||
* the currently used {@link java.awt.Toolkit} instance. In order to initialize
|
||||
* {@link java.awt.KeyboardFocusManager}, an instance of {@link KeyboardFocusManagerPeer}
|
||||
* is needed. To create that instance, the {@link #createKeyboardFocusManagerPeer}
|
||||
* {@link java.awt.KeyboardFocusManager}, a singleton instance of {@link KeyboardFocusManagerPeer}
|
||||
* is needed. To obtain that instance, the {@link #getKeyboardFocusManagerPeer}
|
||||
* method of the current toolkit is called.
|
||||
*/
|
||||
public interface KeyboardFocusManagerPeerProvider {
|
||||
|
||||
/**
|
||||
* Creates a KeyboardFocusManagerPeer for the specified KeyboardFocusManager.
|
||||
* Gets a singleton KeyboardFocusManagerPeer instance.
|
||||
*/
|
||||
KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager);
|
||||
KeyboardFocusManagerPeer getKeyboardFocusManagerPeer();
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ public abstract class SunToolkit extends Toolkit
|
||||
public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
|
||||
throws AWTException;
|
||||
|
||||
public abstract KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
|
||||
public abstract KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
|
||||
throws HeadlessException;
|
||||
|
||||
/**
|
||||
@ -463,6 +463,19 @@ public abstract class SunToolkit extends Toolkit
|
||||
if (event == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
AWTAccessor.SequencedEventAccessor sea = AWTAccessor.getSequencedEventAccessor();
|
||||
if (sea != null && sea.isSequencedEvent(event)) {
|
||||
AWTEvent nested = sea.getNested(event);
|
||||
if (nested.getID() == WindowEvent.WINDOW_LOST_FOCUS &&
|
||||
nested instanceof TimedWindowEvent)
|
||||
{
|
||||
TimedWindowEvent twe = (TimedWindowEvent)nested;
|
||||
((SunToolkit)Toolkit.getDefaultToolkit()).
|
||||
setWindowDeactivationTime((Window)twe.getSource(), twe.getWhen());
|
||||
}
|
||||
}
|
||||
|
||||
// All events posted via this method are system-generated.
|
||||
// Placing the following call here reduces considerably the
|
||||
// number of places throughout the toolkit that would
|
||||
@ -1863,6 +1876,28 @@ public abstract class SunToolkit extends Toolkit
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final Object DEACTIVATION_TIMES_MAP_KEY = new Object();
|
||||
|
||||
public synchronized void setWindowDeactivationTime(Window w, long time) {
|
||||
AppContext ctx = getAppContext(w);
|
||||
WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
|
||||
if (map == null) {
|
||||
map = new WeakHashMap<Window, Long>();
|
||||
ctx.put(DEACTIVATION_TIMES_MAP_KEY, map);
|
||||
}
|
||||
map.put(w, time);
|
||||
}
|
||||
|
||||
public synchronized long getWindowDeactivationTime(Window w) {
|
||||
AppContext ctx = getAppContext(w);
|
||||
WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
|
||||
if (map == null) {
|
||||
return -1;
|
||||
}
|
||||
Long time = map.get(w);
|
||||
return time == null ? -1 : time;
|
||||
}
|
||||
|
||||
// Cosntant alpha
|
||||
public boolean isWindowOpacitySupported() {
|
||||
return false;
|
||||
|
||||
51
jdk/src/share/classes/sun/awt/TimedWindowEvent.java
Normal file
51
jdk/src/share/classes/sun/awt/TimedWindowEvent.java
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.awt;
|
||||
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.Window;
|
||||
|
||||
public class TimedWindowEvent extends WindowEvent {
|
||||
|
||||
private long time;
|
||||
|
||||
public long getWhen() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public TimedWindowEvent(Window source, int id, Window opposite, long time) {
|
||||
super(source, id, opposite);
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public TimedWindowEvent(Window source, int id, Window opposite,
|
||||
int oldState, int newState, long time)
|
||||
{
|
||||
super(source, id, opposite, oldState, newState);
|
||||
this.time = time;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<body>
|
||||
<h1>Card Test (1.1)</h1>
|
||||
<hr>
|
||||
<applet code=CardTest.class width=400 height=300>
|
||||
<applet code=CardTest.class width=455 height=300>
|
||||
alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason."
|
||||
Your browser is completely ignoring the <APPLET> tag!
|
||||
</applet>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<body>
|
||||
<h1>Dither Test (1.1)</h1>
|
||||
<hr>
|
||||
<applet code=DitherTest.class width=425 height=400>
|
||||
<applet code=DitherTest.class width=455 height=400>
|
||||
alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason."
|
||||
Your browser is completely ignoring the <APPLET> tag!
|
||||
</applet>
|
||||
|
||||
@ -1001,6 +1001,13 @@ public class XBaseWindow {
|
||||
switch (xev.get_type()) {
|
||||
case XConstants.ButtonPress:
|
||||
if (buttonState == 0) {
|
||||
XWindowPeer parent = getToplevelXWindow();
|
||||
// See 6385277, 6981400.
|
||||
if (parent != null && parent.isFocusableWindow()) {
|
||||
// A click in a client area drops the actual focused window retaining.
|
||||
parent.setActualFocusedWindow(null);
|
||||
parent.requestWindowFocus(xbe.get_time(), true);
|
||||
}
|
||||
XAwtState.setAutoGrabWindow(this);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -588,33 +588,6 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
|
||||
|
||||
}
|
||||
|
||||
public void handleButtonPressRelease(XEvent xev) {
|
||||
/*
|
||||
* Fix for 6385277.
|
||||
* We request focus on simple Window by click in order
|
||||
* to make it behave like Frame/Dialog in this case and also to unify
|
||||
* the behaviour with what we have on MS Windows.
|
||||
* handleJavaMouseEvent() would be more suitable place to do this
|
||||
* but we want Swing to have this functionality also.
|
||||
*/
|
||||
if (xev.get_type() == XConstants.ButtonPress) {
|
||||
final XWindowPeer parentXWindow = getParentTopLevel();
|
||||
Window parentWindow = (Window)parentXWindow.getTarget();
|
||||
if (parentXWindow.isFocusableWindow() && parentXWindow.isSimpleWindow() &&
|
||||
XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() != parentWindow)
|
||||
{
|
||||
postEvent(new InvocationEvent(parentWindow, new Runnable() {
|
||||
public void run() {
|
||||
// Request focus on the EDT of 'parentWindow' because
|
||||
// XDecoratedPeer.requestWindowFocus() calls client code.
|
||||
parentXWindow.requestXFocus();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
super.handleButtonPressRelease(xev);
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize() {
|
||||
return target.getSize();
|
||||
}
|
||||
|
||||
@ -1108,7 +1108,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
focusLog.fine("Request for decorated window focus");
|
||||
// If this is Frame or Dialog we can't assure focus request success - but we still can try
|
||||
// If this is Window and its owner Frame is active we can be sure request succedded.
|
||||
Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
|
||||
Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
|
||||
Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
|
||||
|
||||
focusLog.finer("Current window is: active={0}, focused={1}",
|
||||
@ -1201,7 +1201,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
}
|
||||
|
||||
public void handleWindowFocusOut(Window oppositeWindow, long serial) {
|
||||
Window actualFocusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
|
||||
Window actualFocusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
|
||||
|
||||
// If the actual focused window is not this decorated window then retain it.
|
||||
if (actualFocusedWindow != null && actualFocusedWindow != target) {
|
||||
|
||||
@ -135,7 +135,7 @@ class XDialogPeer extends XDecoratedPeer implements DialogPeer {
|
||||
* Thus we don't have to perform any transitive (a blocker of a blocker) checks.
|
||||
*/
|
||||
boolean isFocusedWindowModalBlocker() {
|
||||
Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
|
||||
Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
|
||||
XWindowPeer focusedWindowPeer = null;
|
||||
|
||||
if (focusedWindow != null) {
|
||||
|
||||
@ -96,11 +96,11 @@ public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
|
||||
public void handleEvent(AWTEvent e) {
|
||||
switch (e.getID()) {
|
||||
case FocusEvent.FOCUS_GAINED:
|
||||
XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(proxy);
|
||||
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(proxy);
|
||||
container.focusGained(handle);
|
||||
break;
|
||||
case FocusEvent.FOCUS_LOST:
|
||||
XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
|
||||
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
|
||||
container.focusLost(handle);
|
||||
break;
|
||||
case KeyEvent.KEY_PRESSED:
|
||||
@ -172,7 +172,7 @@ public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
|
||||
if (lightweightChild == null) {
|
||||
lightweightChild = (Component)proxy;
|
||||
}
|
||||
Component currentOwner = XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner();
|
||||
Component currentOwner = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
|
||||
if (currentOwner != null && currentOwner.getPeer() == null) {
|
||||
currentOwner = null;
|
||||
}
|
||||
@ -224,7 +224,8 @@ public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
|
||||
if (parent != null) {
|
||||
Window parentWindow = (Window)parent;
|
||||
// and check that it is focused
|
||||
if (!parentWindow.isFocused() && XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == parentWindow) {
|
||||
if (!parentWindow.isFocused() &&
|
||||
XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == parentWindow) {
|
||||
// if it is not - skip requesting focus on Solaris
|
||||
// but return true for compatibility.
|
||||
return true;
|
||||
|
||||
@ -204,7 +204,7 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher
|
||||
// XEMBED_FOCUS_OUT client messages), so we first need to check if
|
||||
// embedded is an active window before sending WINDOW_LOST_FOCUS
|
||||
// to shared code
|
||||
if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == embedded.target) {
|
||||
if (XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == embedded.target) {
|
||||
embedded.handleWindowFocusOut(null, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,66 +25,48 @@
|
||||
package sun.awt.X11;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Window;
|
||||
|
||||
import java.awt.event.FocusEvent;
|
||||
|
||||
import java.awt.peer.KeyboardFocusManagerPeer;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import sun.awt.CausedFocusEvent;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.KeyboardFocusManagerPeerImpl;
|
||||
|
||||
public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
|
||||
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XKeyboardFocusManagerPeer");
|
||||
private static final XKeyboardFocusManagerPeer inst = new XKeyboardFocusManagerPeer();
|
||||
|
||||
private static Object lock = new Object() {};
|
||||
private static Component currentFocusOwner;
|
||||
private static Window currentFocusedWindow;
|
||||
private Component currentFocusOwner;
|
||||
private Window currentFocusedWindow;
|
||||
|
||||
XKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
|
||||
super(manager);
|
||||
public static XKeyboardFocusManagerPeer getInstance() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
private XKeyboardFocusManagerPeer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentFocusOwner(Component comp) {
|
||||
setCurrentNativeFocusOwner(comp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getCurrentFocusOwner() {
|
||||
return getCurrentNativeFocusOwner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Window getCurrentFocusedWindow() {
|
||||
return getCurrentNativeFocusedWindow();
|
||||
}
|
||||
|
||||
public static void setCurrentNativeFocusOwner(Component comp) {
|
||||
synchronized (lock) {
|
||||
synchronized (this) {
|
||||
currentFocusOwner = comp;
|
||||
}
|
||||
}
|
||||
|
||||
public static Component getCurrentNativeFocusOwner() {
|
||||
synchronized(lock) {
|
||||
@Override
|
||||
public Component getCurrentFocusOwner() {
|
||||
synchronized(this) {
|
||||
return currentFocusOwner;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setCurrentNativeFocusedWindow(Window win) {
|
||||
if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer("Setting current native focused window " + win);
|
||||
@Override
|
||||
public void setCurrentFocusedWindow(Window win) {
|
||||
if (focusLog.isLoggable(PlatformLogger.FINER)) {
|
||||
focusLog.finer("Setting current focused window " + win);
|
||||
}
|
||||
|
||||
XWindowPeer from = null, to = null;
|
||||
|
||||
synchronized(lock) {
|
||||
synchronized(this) {
|
||||
if (currentFocusedWindow != null) {
|
||||
from = (XWindowPeer)currentFocusedWindow.getPeer();
|
||||
}
|
||||
@ -104,8 +86,9 @@ public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
|
||||
}
|
||||
}
|
||||
|
||||
public static Window getCurrentNativeFocusedWindow() {
|
||||
synchronized(lock) {
|
||||
@Override
|
||||
public Window getCurrentFocusedWindow() {
|
||||
synchronized(this) {
|
||||
return currentFocusedWindow;
|
||||
}
|
||||
}
|
||||
@ -124,6 +107,6 @@ public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
|
||||
focusedWindowChangeAllowed,
|
||||
time,
|
||||
cause,
|
||||
getCurrentNativeFocusOwner());
|
||||
getInstance().getCurrentFocusOwner());
|
||||
}
|
||||
}
|
||||
|
||||
@ -663,7 +663,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
||||
long w = 0;
|
||||
if (windowToXWindow(ev.get_xany().get_window()) != null) {
|
||||
Component owner =
|
||||
XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner();
|
||||
XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
|
||||
if (owner != null) {
|
||||
XWindow ownerWindow = (XWindow) AWTAccessor.getComponentAccessor().getPeer(owner);
|
||||
if (ownerWindow != null) {
|
||||
@ -1155,9 +1155,8 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
||||
return peer;
|
||||
}
|
||||
|
||||
public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) throws HeadlessException {
|
||||
XKeyboardFocusManagerPeer peer = new XKeyboardFocusManagerPeer(manager);
|
||||
return peer;
|
||||
public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() throws HeadlessException {
|
||||
return XKeyboardFocusManagerPeer.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -617,7 +617,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
|
||||
public void handleWindowFocusIn_Dispatch() {
|
||||
if (EventQueue.isDispatchThread()) {
|
||||
XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
|
||||
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
|
||||
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
|
||||
SunToolkit.setSystemGenerated(we);
|
||||
target.dispatchEvent(we);
|
||||
@ -626,7 +626,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
|
||||
public void handleWindowFocusInSync(long serial) {
|
||||
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
|
||||
XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
|
||||
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
|
||||
sendEvent(we);
|
||||
}
|
||||
// NOTE: This method may be called by privileged threads.
|
||||
@ -634,7 +634,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
public void handleWindowFocusIn(long serial) {
|
||||
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
|
||||
/* wrap in Sequenced, then post*/
|
||||
XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
|
||||
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
|
||||
postEvent(wrapInSequenced((AWTEvent) we));
|
||||
}
|
||||
|
||||
@ -642,15 +642,15 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
||||
public void handleWindowFocusOut(Window oppositeWindow, long serial) {
|
||||
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
|
||||
XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow(null);
|
||||
XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
|
||||
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
|
||||
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
|
||||
/* wrap in Sequenced, then post*/
|
||||
postEvent(wrapInSequenced((AWTEvent) we));
|
||||
}
|
||||
public void handleWindowFocusOutSync(Window oppositeWindow, long serial) {
|
||||
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
|
||||
XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow(null);
|
||||
XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
|
||||
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
|
||||
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
|
||||
sendEvent(we);
|
||||
}
|
||||
|
||||
@ -1138,7 +1138,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
// getWMState() always returns 0 (Withdrawn) for simple windows. Hence
|
||||
// we ignore the state for such windows.
|
||||
if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) {
|
||||
if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() ==
|
||||
if (XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() ==
|
||||
getTarget())
|
||||
{
|
||||
show = true;
|
||||
@ -1165,15 +1165,25 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (isGrabbed()) {
|
||||
if (grabLog.isLoggable(PlatformLogger.FINE)) {
|
||||
grabLog.fine("Generating UngrabEvent on {0} because of the window disposal", this);
|
||||
}
|
||||
postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
|
||||
}
|
||||
|
||||
SunToolkit.awtLock();
|
||||
|
||||
try {
|
||||
windows.remove(this);
|
||||
} finally {
|
||||
SunToolkit.awtUnlock();
|
||||
}
|
||||
|
||||
if (warningWindow != null) {
|
||||
warningWindow.destroy();
|
||||
}
|
||||
|
||||
removeRootPropertyEventDispatcher();
|
||||
mustControlStackPosition = false;
|
||||
super.dispose();
|
||||
@ -1185,12 +1195,13 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
* receive WM_TAKE_FOCUS.
|
||||
*/
|
||||
if (isSimpleWindow()) {
|
||||
if (target == XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow()) {
|
||||
if (target == XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow()) {
|
||||
Window owner = getDecoratedOwner((Window)target);
|
||||
((XWindowPeer)AWTAccessor.getComponentAccessor().getPeer(owner)).requestWindowFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isResizable() {
|
||||
return winAttr.isResizable;
|
||||
}
|
||||
@ -1825,7 +1836,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
// If this is Frame or Dialog we can't assure focus request success - but we still can try
|
||||
// If this is Window and its owner Frame is active we can be sure request succedded.
|
||||
Window ownerWindow = XWindowPeer.getDecoratedOwner((Window)target);
|
||||
Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
|
||||
Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
|
||||
Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
|
||||
|
||||
if (isWMStateNetHidden()) {
|
||||
|
||||
@ -25,7 +25,6 @@
|
||||
|
||||
package sun.awt.windows;
|
||||
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Window;
|
||||
import java.awt.Component;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
@ -37,8 +36,13 @@ class WKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
|
||||
static native Component getNativeFocusOwner();
|
||||
static native Window getNativeFocusedWindow();
|
||||
|
||||
WKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
|
||||
super(manager);
|
||||
private static final WKeyboardFocusManagerPeer inst = new WKeyboardFocusManagerPeer();
|
||||
|
||||
public static WKeyboardFocusManagerPeer getInstance() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
private WKeyboardFocusManagerPeer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -51,6 +55,12 @@ class WKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
|
||||
return getNativeFocusOwner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentFocusedWindow(Window win) {
|
||||
// Not used on Windows
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Window getCurrentFocusedWindow() {
|
||||
return getNativeFocusedWindow();
|
||||
|
||||
@ -506,10 +506,10 @@ public class WToolkit extends SunToolkit implements Runnable {
|
||||
return true;
|
||||
}
|
||||
|
||||
public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
|
||||
public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
|
||||
throws HeadlessException
|
||||
{
|
||||
return new WKeyboardFocusManagerPeer(manager);
|
||||
return WKeyboardFocusManagerPeer.getInstance();
|
||||
}
|
||||
|
||||
protected native void setDynamicLayoutNative(boolean b);
|
||||
|
||||
@ -1477,7 +1477,7 @@ void AwtWindow::SendWindowEvent(jint id, HWND opposite,
|
||||
if (wClassEvent == NULL) {
|
||||
if (env->PushLocalFrame(1) < 0)
|
||||
return;
|
||||
wClassEvent = env->FindClass("java/awt/event/WindowEvent");
|
||||
wClassEvent = env->FindClass("sun/awt/TimedWindowEvent");
|
||||
if (wClassEvent != NULL) {
|
||||
wClassEvent = (jclass)env->NewGlobalRef(wClassEvent);
|
||||
}
|
||||
@ -1491,7 +1491,7 @@ void AwtWindow::SendWindowEvent(jint id, HWND opposite,
|
||||
if (wEventInitMID == NULL) {
|
||||
wEventInitMID =
|
||||
env->GetMethodID(wClassEvent, "<init>",
|
||||
"(Ljava/awt/Window;ILjava/awt/Window;II)V");
|
||||
"(Ljava/awt/Window;ILjava/awt/Window;IIJ)V");
|
||||
DASSERT(wEventInitMID);
|
||||
if (wEventInitMID == NULL) {
|
||||
return;
|
||||
@ -1532,7 +1532,7 @@ void AwtWindow::SendWindowEvent(jint id, HWND opposite,
|
||||
}
|
||||
}
|
||||
jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id,
|
||||
jOpposite, oldState, newState);
|
||||
jOpposite, oldState, newState, TimeHelper::getMessageTimeUTC());
|
||||
DASSERT(!safe_ExceptionOccurred(env));
|
||||
DASSERT(event != NULL);
|
||||
if (jOpposite != NULL) {
|
||||
|
||||
222
jdk/test/java/awt/Focus/6981400/Test1.java
Normal file
222
jdk/test/java/awt/Focus/6981400/Test1.java
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6981400
|
||||
* @summary Tabbing between textfiled do not work properly when ALT+TAB
|
||||
* @author anton.tarasov
|
||||
* @library ../../regtesthelpers
|
||||
* @build Util
|
||||
* @run main Test1
|
||||
*/
|
||||
|
||||
// This test shows a frame with four focusable components: b0, b1, b2, b3.
|
||||
// Then it presses Tab three times. EDT is freezed for a while on the first FOCUS_LOST event.
|
||||
// Meantime, the test clicks in a component of another frame and then clicks in the title
|
||||
// of the original frame. When EDT awakes and all the queued events get processed,
|
||||
// the other frame should ones gain focus and then pass it to the original frame.
|
||||
// The b3 component of the orinial frame should finally become a focus owner.
|
||||
// The FOCUS_LOST/FOCUS_GAINED events order in the original frame is tracked and should be:
|
||||
// b0 -> b1 -> b2 -> b3.
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.swing.*;
|
||||
import test.java.awt.regtesthelpers.Util;
|
||||
|
||||
public class Test1 {
|
||||
static JFrame f0 = new JFrame("base_frame") { public String getName() {return "base_frame";} };
|
||||
static JButton f0b0 = new JB("b0");
|
||||
static JButton f0b1 = new JB("b1");
|
||||
static JButton f0b2 = new JB("b2");
|
||||
static JButton f0b3 = new JB("b3");
|
||||
|
||||
static JFrame f1 = new JFrame("swing_frame") { public String getName() {return "swing_frame";} };
|
||||
static JButton f1b0 = new JButton("button");
|
||||
|
||||
static Frame f2 = new Frame("awt_frame") { public String getName() {return "awt_frame";} };
|
||||
static Button f2b0 = new Button("button");
|
||||
|
||||
static Robot robot;
|
||||
|
||||
static List<Component> gainedList = new ArrayList<Component>();
|
||||
static List<Component> lostList = new ArrayList<Component>();
|
||||
|
||||
static Component[] refGainedList = new Component[] {f0b1, f0b2, f0b3, f0b3};
|
||||
static Component[] refLostList = new Component[] {f0b0, f0b1, f0b2, f0b3};
|
||||
|
||||
static boolean tracking;
|
||||
|
||||
public static void main(String[] args) {
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
|
||||
public void eventDispatched(AWTEvent e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}, FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_EVENT_MASK);
|
||||
|
||||
try {
|
||||
robot = new Robot();
|
||||
} catch (AWTException ex) {
|
||||
throw new RuntimeException("Error: can't create Robot");
|
||||
}
|
||||
|
||||
f0.add(f0b0);
|
||||
f0.add(f0b1);
|
||||
f0.add(f0b2);
|
||||
f0.add(f0b3);
|
||||
f0.setLayout(new FlowLayout());
|
||||
f0.setBounds(0, 100, 400, 200);
|
||||
|
||||
f1.add(f1b0);
|
||||
f1.setBounds(0, 400, 400, 200);
|
||||
|
||||
f2.add(f2b0);
|
||||
f2.setBounds(0, 400, 400, 200);
|
||||
|
||||
f0b0.addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception ex) {}
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// Case 1. Test against swing JFrame.
|
||||
//
|
||||
|
||||
f1.setVisible(true);
|
||||
f0.setVisible(true);
|
||||
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
if (!f0b0.isFocusOwner()) {
|
||||
Util.clickOnComp(f0b0, robot);
|
||||
Util.waitForIdle(robot);
|
||||
if (!f0b0.isFocusOwner()) {
|
||||
throw new RuntimeException("Error: can't focus the component " + f0b0);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("\nTest case 1: swing frame\n");
|
||||
test(f1b0);
|
||||
|
||||
//
|
||||
// Case 2. Test against awt Frame.
|
||||
//
|
||||
|
||||
tracking = false;
|
||||
gainedList.clear();
|
||||
lostList.clear();
|
||||
|
||||
f1.dispose();
|
||||
f2.setAutoRequestFocus(false);
|
||||
f2.setVisible(true);
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
Util.clickOnComp(f0b0, robot);
|
||||
Util.waitForIdle(robot);
|
||||
if (!f0b0.isFocusOwner()) {
|
||||
throw new RuntimeException("Error: can't focus the component " + f0b0);
|
||||
}
|
||||
|
||||
System.out.println("\nTest case 2: awt frame\n");
|
||||
test(f2b0);
|
||||
|
||||
System.out.println("\nTest passed.");
|
||||
}
|
||||
|
||||
public static void test(Component compToClick) {
|
||||
tracking = true;
|
||||
|
||||
robot.keyPress(KeyEvent.VK_TAB);
|
||||
robot.delay(50);
|
||||
robot.keyRelease(KeyEvent.VK_TAB);
|
||||
robot.delay(50);
|
||||
|
||||
robot.keyPress(KeyEvent.VK_TAB);
|
||||
robot.delay(50);
|
||||
robot.keyRelease(KeyEvent.VK_TAB);
|
||||
robot.delay(50);
|
||||
|
||||
robot.keyPress(KeyEvent.VK_TAB);
|
||||
robot.delay(50);
|
||||
robot.keyRelease(KeyEvent.VK_TAB);
|
||||
|
||||
robot.delay(50);
|
||||
Util.clickOnComp(compToClick, robot);
|
||||
|
||||
robot.delay(50);
|
||||
Util.clickOnTitle(f0, robot);
|
||||
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
if (!f0b3.isFocusOwner()) {
|
||||
throw new RuntimeException("Test failed: f0b3 is not a focus owner");
|
||||
}
|
||||
|
||||
if (!"sun.awt.X11.XToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) {
|
||||
|
||||
if (!Arrays.asList(refGainedList).equals(gainedList)) {
|
||||
System.out.println("gained list: " + gainedList);
|
||||
throw new RuntimeException("Test failed: wrong FOCUS_GAINED events order");
|
||||
}
|
||||
if (!Arrays.asList(refLostList).equals(lostList)) {
|
||||
System.out.println("lost list: " + lostList);
|
||||
throw new RuntimeException("Test failed: wrong FOCUS_LOST events order");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JB extends JButton {
|
||||
String name;
|
||||
|
||||
public JB(String name) {
|
||||
super(name);
|
||||
this.name = name;
|
||||
|
||||
addFocusListener(new FocusListener() {
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (Test1.tracking)
|
||||
Test1.gainedList.add(e.getComponent());
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
if (Test1.tracking)
|
||||
Test1.lostList.add(e.getComponent());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[" + name + "]";
|
||||
}
|
||||
}
|
||||
118
jdk/test/java/awt/Focus/6981400/Test2.java
Normal file
118
jdk/test/java/awt/Focus/6981400/Test2.java
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6981400
|
||||
* @summary Tabbing between textfiled do not work properly when ALT+TAB
|
||||
* @author anton.tarasov
|
||||
* @library ../../regtesthelpers
|
||||
* @build Util
|
||||
* @run main Test2
|
||||
*/
|
||||
|
||||
// A focus request made after a char is typed ahead shouldn't affect the char's target component.
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import test.java.awt.regtesthelpers.Util;
|
||||
|
||||
public class Test2 {
|
||||
static Frame f = new Frame("frame");
|
||||
static TextArea t0 = new TextArea(1, 10) { public String toString() { return "[TA-0]";} };
|
||||
static TextArea t1 = new TextArea(1, 10) { public String toString() { return "[TA-1]";} };
|
||||
static TextArea t2 = new TextArea(1, 10) { public String toString() { return "[TA-2]";} };
|
||||
|
||||
static volatile boolean passed = true;
|
||||
|
||||
static Robot robot;
|
||||
|
||||
public static void main(String[] args) {
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
|
||||
public void eventDispatched(AWTEvent e) {
|
||||
System.out.println(e);
|
||||
if (e.getID() == KeyEvent.KEY_TYPED) {
|
||||
if (e.getSource() != t1) {
|
||||
passed = false;
|
||||
throw new RuntimeException("Test failed: the key event has wrong source: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, FocusEvent.FOCUS_EVENT_MASK | KeyEvent.KEY_EVENT_MASK);
|
||||
|
||||
try {
|
||||
robot = new Robot();
|
||||
} catch (AWTException ex) {
|
||||
throw new RuntimeException("Error: can't create Robot");
|
||||
}
|
||||
|
||||
f.add(t0);
|
||||
f.add(t1);
|
||||
f.add(t2);
|
||||
|
||||
f.setLayout(new FlowLayout());
|
||||
f.pack();
|
||||
|
||||
t0.addFocusListener(new FocusAdapter() {
|
||||
public void focusLost(FocusEvent e) {
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
} catch (Exception ex) {}
|
||||
}
|
||||
});
|
||||
|
||||
// The request shouldn't affect the key event delivery.
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (Exception ex) {}
|
||||
System.out.println("requesting focus to " + t2);
|
||||
t2.requestFocus();
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
||||
f.setVisible(true);
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
test();
|
||||
|
||||
if (passed) System.out.println("\nTest passed.");
|
||||
}
|
||||
|
||||
static void test() {
|
||||
Util.clickOnComp(t1, robot);
|
||||
|
||||
// The key event should be eventually delivered to t1.
|
||||
robot.delay(50);
|
||||
robot.keyPress(KeyEvent.VK_A);
|
||||
robot.delay(50);
|
||||
robot.keyRelease(KeyEvent.VK_A);
|
||||
|
||||
Util.waitForIdle(robot);
|
||||
}
|
||||
}
|
||||
|
||||
141
jdk/test/java/awt/Focus/6981400/Test3.java
Normal file
141
jdk/test/java/awt/Focus/6981400/Test3.java
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6981400
|
||||
* @summary Tabbing between textfiled do not work properly when ALT+TAB
|
||||
* @author anton.tarasov
|
||||
* @library ../../regtesthelpers
|
||||
* @build Util
|
||||
* @run main Test3
|
||||
*/
|
||||
|
||||
// A menu item in a frame should not be auto-selected when switching by Alt+TAB back and forth.
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.event.*;
|
||||
import test.java.awt.regtesthelpers.Util;
|
||||
|
||||
public class Test3 {
|
||||
static JFrame f = new JFrame("Frame");
|
||||
static JMenuBar bar = new JMenuBar();
|
||||
static JMenu menu = new JMenu("File");
|
||||
static JMenuItem item = new JMenuItem("Save");
|
||||
|
||||
static JButton b0 = new JButton("b0");
|
||||
static JButton b1 = new JButton("b1");
|
||||
|
||||
static Robot robot;
|
||||
|
||||
public static void main(String[] args) {
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
|
||||
public void eventDispatched(AWTEvent e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}, KeyEvent.KEY_EVENT_MASK);
|
||||
|
||||
try {
|
||||
robot = new Robot();
|
||||
} catch (AWTException ex) {
|
||||
throw new RuntimeException("Error: can't create Robot");
|
||||
}
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
|
||||
} catch (Exception e) {}
|
||||
|
||||
b0.addFocusListener(new FocusAdapter() {
|
||||
public void focusLost(FocusEvent f) {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
});
|
||||
|
||||
menu.add(item);
|
||||
bar.add(menu);
|
||||
f.setJMenuBar(bar);
|
||||
|
||||
f.add(b0);
|
||||
f.add(b1);
|
||||
|
||||
f.setLayout(new FlowLayout());
|
||||
f.setSize(400, 100);
|
||||
f.setVisible(true);
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
if (!b0.hasFocus()) {
|
||||
Util.clickOnComp(b0, robot);
|
||||
Util.waitForIdle(robot);
|
||||
if (!b0.hasFocus()) {
|
||||
throw new RuntimeException("Error: can't focus " + b0);
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
|
||||
System.out.println("Test passed.");
|
||||
}
|
||||
|
||||
public static void test() {
|
||||
robot.keyPress(KeyEvent.VK_TAB);
|
||||
robot.delay(50);
|
||||
robot.keyRelease(KeyEvent.VK_TAB);
|
||||
robot.delay(50);
|
||||
|
||||
robot.keyPress(KeyEvent.VK_ALT);
|
||||
robot.delay(50);
|
||||
robot.keyPress(KeyEvent.VK_TAB);
|
||||
robot.delay(50);
|
||||
robot.keyRelease(KeyEvent.VK_ALT);
|
||||
robot.delay(50);
|
||||
robot.keyRelease(KeyEvent.VK_TAB);
|
||||
|
||||
robot.delay(500);
|
||||
|
||||
robot.keyPress(KeyEvent.VK_ALT);
|
||||
robot.delay(50);
|
||||
robot.keyPress(KeyEvent.VK_TAB);
|
||||
robot.delay(50);
|
||||
robot.keyRelease(KeyEvent.VK_ALT);
|
||||
robot.delay(50);
|
||||
robot.keyRelease(KeyEvent.VK_TAB);
|
||||
|
||||
// Control shot.
|
||||
Util.clickOnTitle(f, robot);
|
||||
Util.waitForIdle(robot);
|
||||
|
||||
if (menu.isSelected()) {
|
||||
throw new RuntimeException("Test failed: the menu gets selected");
|
||||
}
|
||||
if (!b1.hasFocus()) {
|
||||
throw new RuntimeException("Test failed: the button is not a focus owner " + b1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -38,8 +38,7 @@ import infos.ThirdBeanBeanInfo;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.Introspector;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class TestBeanInfo implements Runnable {
|
||||
|
||||
@ -60,10 +59,9 @@ public class TestBeanInfo implements Runnable {
|
||||
try {
|
||||
actual = Introspector.getBeanInfo(type);
|
||||
type = actual.getClass();
|
||||
Field field = type.getDeclaredField("targetBeanInfoRef"); // NON-NLS: field name
|
||||
field.setAccessible(true);
|
||||
Reference ref = (Reference) field.get(actual);
|
||||
actual = (BeanInfo) ref.get();
|
||||
Method method = type.getDeclaredMethod("getTargetBeanInfo"); // NON-NLS: method name
|
||||
method.setAccessible(true);
|
||||
actual = (BeanInfo) method.invoke(actual);
|
||||
}
|
||||
catch (Exception exception) {
|
||||
throw new Error("unexpected error", exception);
|
||||
|
||||
55
jdk/test/java/beans/Introspector/Test7186794.java
Normal file
55
jdk/test/java/beans/Introspector/Test7186794.java
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7186794
|
||||
* @summary Tests setter in the super class
|
||||
* @author Sergey Malenkov
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Test7186794 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (null == BeanUtils.findPropertyDescriptor(MyBean.class, "value").getWriteMethod()) {
|
||||
throw new Error("The property setter is not found");
|
||||
}
|
||||
}
|
||||
|
||||
public static class BaseBean {
|
||||
|
||||
protected List<String> value;
|
||||
|
||||
public void setValue(List<String> value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyBean extends BaseBean {
|
||||
public List<String> getValue() {
|
||||
return super.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -28,17 +28,11 @@
|
||||
* @author Sergey Malenkov
|
||||
*/
|
||||
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
|
||||
public class Test7189112 {
|
||||
|
||||
public static void main(String[] args) throws IntrospectionException {
|
||||
for (PropertyDescriptor pd : Introspector.getBeanInfo(MyBean.class).getPropertyDescriptors()) {
|
||||
if (pd.getName().equals("value") && (null == pd.getWriteMethod())) {
|
||||
throw new Error("The property setter is not found");
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
if (null == BeanUtils.findPropertyDescriptor(MyBean.class, "value").getWriteMethod()) {
|
||||
throw new Error("The property setter is not found");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
83
jdk/test/java/beans/Introspector/Test7192955.java
Normal file
83
jdk/test/java/beans/Introspector/Test7192955.java
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7192955
|
||||
* @summary Tests that all properties are bound
|
||||
* @author Sergey Malenkov
|
||||
*/
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.List;
|
||||
|
||||
public class Test7192955 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (!BeanUtils.findPropertyDescriptor(MyBean.class, "test").isBound()) {
|
||||
throw new Error("a simple property is not bound");
|
||||
}
|
||||
if (!BeanUtils.findPropertyDescriptor(MyBean.class, "list").isBound()) {
|
||||
throw new Error("a generic property is not bound");
|
||||
}
|
||||
if (!BeanUtils.findPropertyDescriptor(MyBean.class, "readOnly").isBound()) {
|
||||
throw new Error("a read-only property is not bound");
|
||||
}
|
||||
}
|
||||
|
||||
public static class BaseBean {
|
||||
|
||||
private List<String> list;
|
||||
|
||||
public List<String> getList() {
|
||||
return this.list;
|
||||
}
|
||||
|
||||
public void setList(List<String> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
}
|
||||
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
}
|
||||
|
||||
public List<String> getReadOnly() {
|
||||
return this.list;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyBean extends BaseBean {
|
||||
|
||||
private String test;
|
||||
|
||||
public String getTest() {
|
||||
return this.test;
|
||||
}
|
||||
|
||||
public void setTest(String test) {
|
||||
this.test = test;
|
||||
}
|
||||
}
|
||||
}
|
||||
67
jdk/test/java/beans/Introspector/Test7195106.java
Normal file
67
jdk/test/java/beans/Introspector/Test7195106.java
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7195106
|
||||
* @summary Tests that explicit BeanInfo is not collected
|
||||
* @author Sergey Malenkov
|
||||
*/
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.SimpleBeanInfo;
|
||||
|
||||
public class Test7195106 {
|
||||
|
||||
public static void main(String[] arg) throws Exception {
|
||||
BeanInfo info = Introspector.getBeanInfo(My.class);
|
||||
if (null == info.getIcon(BeanInfo.ICON_COLOR_16x16)) {
|
||||
throw new Error("Unexpected behavior");
|
||||
}
|
||||
try {
|
||||
int[] array = new int[1024];
|
||||
while (true) {
|
||||
array = new int[array.length << 1];
|
||||
}
|
||||
}
|
||||
catch (OutOfMemoryError error) {
|
||||
System.gc();
|
||||
}
|
||||
if (null == info.getIcon(BeanInfo.ICON_COLOR_16x16)) {
|
||||
throw new Error("Explicit BeanInfo is collected");
|
||||
}
|
||||
}
|
||||
|
||||
public static class My {
|
||||
}
|
||||
|
||||
public static class MyBeanInfo extends SimpleBeanInfo {
|
||||
@Override
|
||||
public Image getIcon(int type) {
|
||||
return new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
|
||||
}
|
||||
}
|
||||
}
|
||||
101
jdk/test/java/beans/XMLEncoder/Test7169395.java
Normal file
101
jdk/test/java/beans/XMLEncoder/Test7169395.java
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7169395
|
||||
* @summary Tests that array list initialized correctly
|
||||
* @author Sergey Malenkov
|
||||
*/
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class Test7169395 extends AbstractTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Test7169395().test(true);
|
||||
}
|
||||
|
||||
protected Object getObject() {
|
||||
Container container = new Container();
|
||||
container.add("test-null", null);
|
||||
container.add("test-value", "value");
|
||||
container.add("test-other", "other");
|
||||
return container;
|
||||
}
|
||||
|
||||
public static class Component {
|
||||
|
||||
private final Container container;
|
||||
private final String name;
|
||||
private String value;
|
||||
|
||||
@ConstructorProperties({ "container", "name" })
|
||||
public Component(Container container, String name) {
|
||||
this.container = container;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Container getContainer() {
|
||||
return this.container;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Container {
|
||||
|
||||
private final Map<String, Component> map = new TreeMap<String, Component>();
|
||||
|
||||
public Collection<Component> getComponents() {
|
||||
return new ArrayList<Component>(this.map.values());
|
||||
}
|
||||
|
||||
public void setComponents(Collection<Component> components) {
|
||||
this.map.clear();
|
||||
for (Component component : components){
|
||||
this.map.put(component.getName(), component);
|
||||
}
|
||||
}
|
||||
|
||||
public void add(String name, String value) {
|
||||
Component list = new Component(this, name);
|
||||
list.setValue(value);
|
||||
this.map.put(name, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user