--- a/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java Wed Nov 27 10:44:41 2013 -0800
@@ -158,12 +158,12 @@
boolean fsSupported = isFullScreenSupported();
if (fsSupported && old != null) {
- // restore original display mode and enter windowed mode.
+ // enter windowed mode and restore original display mode
+ exitFullScreenExclusive(old);
if (originalMode != null) {
setDisplayMode(originalMode);
originalMode = null;
}
- exitFullScreenExclusive(old);
}
super.setFullScreenWindow(w);
@@ -227,14 +227,10 @@
throw new IllegalArgumentException("Invalid display mode");
}
if (!Objects.equals(dm, getDisplayMode())) {
- final Window w = getFullScreenWindow();
- if (w != null) {
- exitFullScreenExclusive(w);
- }
nativeSetDisplayMode(displayID, dm.getWidth(), dm.getHeight(),
- dm.getBitDepth(), dm.getRefreshRate());
- if (isFullScreenSupported() && w != null) {
- enterFullScreenExclusive(w);
+ dm.getBitDepth(), dm.getRefreshRate());
+ if (isFullScreenSupported() && getFullScreenWindow() != null) {
+ getFullScreenWindow().setSize(dm.getWidth(), dm.getHeight());
}
}
}
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Wed Nov 27 10:44:41 2013 -0800
@@ -379,10 +379,6 @@
return windowPeer.getPlatformWindow();
}
- protected AppContext getAppContext() {
- return SunToolkit.targetToAppContext(getTarget());
- }
-
// ---- PEER METHODS ---- //
// Just a helper method
@@ -1162,8 +1158,8 @@
/**
* Post an event to the proper Java EDT.
*/
- public void postEvent(AWTEvent event) {
- SunToolkit.postEvent(getAppContext(), event);
+ public void postEvent(final AWTEvent event) {
+ LWToolkit.postEvent(event);
}
protected void postPaintEvent(int x, int y, int w, int h) {
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Wed Nov 27 10:44:41 2013 -0800
@@ -949,7 +949,8 @@
KeyEvent keyEvent = new KeyEvent(focusOwner, id, when, modifiers,
keyCode, keyChar, keyLocation);
AWTAccessor.getKeyEventAccessor().setExtendedKeyCode(keyEvent,
- ExtendedKeyCodes.getExtendedKeyCodeForChar(keyChar));
+ (keyChar == KeyEvent.CHAR_UNDEFINED) ? keyCode
+ : ExtendedKeyCodes.getExtendedKeyCodeForChar(keyChar));
postEvent(keyEvent);
}
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CClipboard.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CClipboard.java Wed Nov 27 10:44:41 2013 -0800
@@ -25,8 +25,10 @@
package sun.lwawt.macosx;
+import java.awt.*;
import java.awt.datatransfer.*;
import java.io.IOException;
+import java.io.NotSerializableException;
import java.util.*;
import sun.awt.datatransfer.*;
@@ -65,12 +67,10 @@
long[] formatArray = dataTransferer.getFormatsForTransferableAsArray(contents, flavorMap);
declareTypes(formatArray, this);
- Map<Long, DataFlavor> formatMap = DataTransferer.getInstance().getFormatsForTransferable(contents, flavorMap);
-
- for (Iterator<Long> iter = formatMap.keySet().iterator(); iter.hasNext(); ) {
- Long lFormat = iter.next();
- long format = lFormat.longValue();
- DataFlavor flavor = formatMap.get(lFormat);
+ Map<Long, DataFlavor> formatMap = dataTransferer.getFormatsForTransferable(contents, flavorMap);
+ for (Map.Entry<Long, DataFlavor> entry : formatMap.entrySet()) {
+ long format = entry.getKey();
+ DataFlavor flavor = entry.getValue();
try {
byte[] bytes = DataTransferer.getInstance().translateTransferable(contents, flavor, format);
@@ -80,17 +80,27 @@
// javaJVMLocalObjectMimeType failed to serialize.
// May remove this if-check when 5078787 is fixed.
if (!(flavor.isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType) &&
- e instanceof java.io.NotSerializableException)) {
+ e instanceof NotSerializableException)) {
e.printStackTrace();
}
}
}
+
+ notifyChanged();
}
- private void lostSelectionOwnershipImpl() {
+ private void notifyLostOwnership() {
lostOwnershipImpl();
}
+ private static void notifyChanged() {
+ CClipboard clipboard = (CClipboard) Toolkit.getDefaultToolkit().getSystemClipboard();
+ if (!clipboard.areFlavorListenersRegistered()) {
+ return;
+ }
+ clipboard.checkChange(clipboard.getClipboardFormats());
+ }
+
protected native long[] getClipboardFormats();
protected native byte[] getClipboardData(long format) throws IOException;
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m Wed Nov 27 10:44:41 2013 -0800
@@ -468,8 +468,6 @@
// TODO: create generic AWT assert
}
- [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
-
NSRect frame = ConvertNSScreenRect(env, [self.nsWindow frame]);
static JNF_MEMBER_CACHE(jm_deliverMoveResizeEvent, jc_CPlatformWindow, "deliverMoveResizeEvent", "(IIIIZ)V");
@@ -480,6 +478,8 @@
(jint)frame.size.height,
(jboolean)[self.nsWindow inLiveResize]);
(*env)->DeleteLocalRef(env, platformWindow);
+
+ [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
}
- (void)windowDidMove:(NSNotification *)notification {
@@ -1236,7 +1236,9 @@
NSRect screenRect = [[nsWindow screen] frame];
[nsWindow setFrame:screenRect display:YES];
} else {
- [JNFException raise:env as:kRuntimeException reason:"Failed to enter full screen."];
+ [JNFException raise:[ThreadUtilities getJNIEnv]
+ as:kRuntimeException
+ reason:"Failed to enter full screen."];
}
}];
@@ -1261,7 +1263,9 @@
// GraphicsDevice takes care of restoring pre full screen bounds
} else {
- [JNFException raise:env as:kRuntimeException reason:"Failed to exit full screen."];
+ [JNFException raise:[ThreadUtilities getJNIEnv]
+ as:kRuntimeException
+ reason:"Failed to exit full screen."];
}
}];
--- a/jdk/src/macosx/native/sun/awt/CClipboard.h Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/macosx/native/sun/awt/CClipboard.h Wed Nov 27 10:44:41 2013 -0800
@@ -43,6 +43,4 @@
- (NSArray *) javaGetTypes;
- (NSData *) javaGetDataForType:(NSString *)inFormat;
-- (void) pasteboardChangedOwner:(NSPasteboard *)sender;
-
@end
--- a/jdk/src/macosx/native/sun/awt/CClipboard.m Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/macosx/native/sun/awt/CClipboard.m Wed Nov 27 10:44:41 2013 -0800
@@ -91,7 +91,9 @@
{
if (sClipboard == nil) {
sClipboard = [[CClipboard alloc] init];
- [[NSNotificationCenter defaultCenter] addObserver:sClipboard selector: @selector(checkPasteboard:) name: NSApplicationDidBecomeActiveNotification object: nil];
+ [[NSNotificationCenter defaultCenter] addObserver:sClipboard selector: @selector(checkPasteboard:)
+ name: NSApplicationDidBecomeActiveNotification
+ object: nil];
}
return sClipboard;
@@ -110,8 +112,6 @@
- (void) javaDeclareTypes:(NSArray *)inTypes withOwner:(jobject)inClipboard jniEnv:(JNIEnv *)inEnv {
- //NSLog(@"CClipboard javaDeclareTypes %@ withOwner", inTypes);
-
@synchronized(self) {
if (inClipboard != NULL) {
if (fClipboardOwner != NULL) {
@@ -126,8 +126,6 @@
- (void) _nativeDeclareTypes:(NSArray *)inTypes {
AWT_ASSERT_APPKIT_THREAD;
- //NSLog(@"CClipboard _nativeDeclareTypes %@ withOwner", inTypes);
-
fChangeCount = [[NSPasteboard generalPasteboard] declareTypes:inTypes owner:self];
}
@@ -136,8 +134,6 @@
NSMutableArray *args = [NSMutableArray arrayWithCapacity:1];
[ThreadUtilities performOnMainThread:@selector(_nativeGetTypes:) on:self withObject:args waitUntilDone:YES];
-
- //NSLog(@"CClipboard getTypes returns %@", [args lastObject]);
return [args lastObject];
}
@@ -145,8 +141,6 @@
AWT_ASSERT_APPKIT_THREAD;
[args addObject:[[NSPasteboard generalPasteboard] types]];
-
- //NSLog(@"CClipboard getTypes returns %@", [args lastObject]);
}
- (void) javaSetData:(NSData *)inData forType:(NSString *) inFormat {
@@ -154,25 +148,18 @@
CClipboardUpdate *newUpdate = [[CClipboardUpdate alloc] initWithData:inData withFormat:inFormat];
[ThreadUtilities performOnMainThread:@selector(_nativeSetData:) on:self withObject:newUpdate waitUntilDone:YES];
[newUpdate release];
-
- //NSLog(@"CClipboard javaSetData forType %@", inFormat);
}
- (void) _nativeSetData:(CClipboardUpdate *)newUpdate {
AWT_ASSERT_APPKIT_THREAD;
[[NSPasteboard generalPasteboard] setData:[newUpdate data] forType:[newUpdate format]];
-
- //NSLog(@"CClipboard _nativeSetData setData %@", [newUpdate data]);
- //NSLog(@"CClipboard _nativeSetData forType %@", [newUpdate format]);
}
- (NSData *) javaGetDataForType:(NSString *) inFormat {
NSMutableArray *args = [NSMutableArray arrayWithObject:inFormat];
[ThreadUtilities performOnMainThread:@selector(_nativeGetDataForType:) on:self withObject:args waitUntilDone:YES];
-
- //NSLog(@"CClipboard javaGetDataForType %@ returns an NSData", inFormat);
return [args lastObject];
}
@@ -183,15 +170,11 @@
if (returnValue) [args replaceObjectAtIndex:0 withObject:returnValue];
else [args removeLastObject];
-
- //NSLog(@"CClipboard _nativeGetDataForType");
}
- (void) checkPasteboard:(id)application {
AWT_ASSERT_APPKIT_THREAD;
- //NSLog(@"CClipboard checkPasteboard oldCount %d newCount %d newTypes %@", fChangeCount, [[NSPasteboard generalPasteboard] changeCount], [[NSPasteboard generalPasteboard] types]);
-
// This is called via NSApplicationDidBecomeActiveNotification.
// If the change count on the general pasteboard is different than when we set it
@@ -199,27 +182,23 @@
NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount];
if (fChangeCount != newChangeCount) {
- fChangeCount = newChangeCount;
-
- [self pasteboardChangedOwner:[NSPasteboard generalPasteboard]];
- }
-}
+ fChangeCount = newChangeCount;
-- (void)pasteboardChangedOwner:(NSPasteboard *)sender; {
- AWT_ASSERT_APPKIT_THREAD;
+ // Notify that the content might be changed
+ static JNF_CLASS_CACHE(jc_CClipboard, "sun/lwawt/macosx/CClipboard");
+ static JNF_STATIC_MEMBER_CACHE(jm_contentChanged, jc_CClipboard, "notifyChanged", "()V");
+ JNIEnv *env = [ThreadUtilities getJNIEnv];
+ JNFCallStaticVoidMethod(env, jm_contentChanged);
- static JNF_CLASS_CACHE(jc_CClipboard, "sun/lwawt/macosx/CClipboard");
- static JNF_MEMBER_CACHE(jm_lostOwnership, jc_CClipboard, "lostSelectionOwnershipImpl", "()V");
-
- //NSLog(@"CClipboard pasteboardChangedOwner");
-
- // If we have a Java pasteboard owner, tell it that it doesn't own the pasteboard anymore.
- @synchronized(self) {
- if (fClipboardOwner) {
- JNIEnv *env = [ThreadUtilities getJNIEnv];
- JNFCallVoidMethod(env, fClipboardOwner, jm_lostOwnership); // AWT_THREADING Safe (event)
- JNFDeleteGlobalRef(env, fClipboardOwner);
- fClipboardOwner = NULL;
+ // If we have a Java pasteboard owner, tell it that it doesn't own the pasteboard anymore.
+ static JNF_MEMBER_CACHE(jm_lostOwnership, jc_CClipboard, "notifyLostOwnership", "()V");
+ @synchronized(self) {
+ if (fClipboardOwner) {
+ JNIEnv *env = [ThreadUtilities getJNIEnv];
+ JNFCallVoidMethod(env, fClipboardOwner, jm_lostOwnership); // AWT_THREADING Safe (event)
+ JNFDeleteGlobalRef(env, fClipboardOwner);
+ fClipboardOwner = NULL;
+ }
}
}
}
@@ -265,9 +244,6 @@
}
JNF_COCOA_ENTER(env);
-
- //NSLog(@"Java_sun_lwawt_macosx_CClipboard_setData");
-
jint nBytes = (*env)->GetArrayLength(env, inBytes);
jbyte *rawBytes = (*env)->GetPrimitiveArrayCritical(env, inBytes, NULL);
NSData *bytesAsData = [NSData dataWithBytes:rawBytes length:nBytes];
@@ -288,8 +264,6 @@
jlongArray returnValue = NULL;
JNF_COCOA_ENTER(env);
- //NSLog(@"Java_sun_lwawt_macosx_CClipboard_getClipboardFormats");
-
NSArray *dataTypes = [[CClipboard sharedClipboard] javaGetTypes];
NSUInteger nFormats = [dataTypes count];
NSUInteger knownFormats = 0;
@@ -346,8 +320,6 @@
// a byte array back to Java. CDataTransferer will do that if necessary.
JNF_COCOA_ENTER(env);
- //NSLog(@"Java_sun_lwawt_macosx_CClipboard_getClipboardData");
-
NSString *formatAsString = formatForIndex(format);
NSData *clipData = [[CClipboard sharedClipboard] javaGetDataForType:formatAsString];
--- a/jdk/src/share/classes/com/sun/beans/finder/ConstructorFinder.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/share/classes/com/sun/beans/finder/ConstructorFinder.java Wed Nov 27 10:44:41 2013 -0800
@@ -24,11 +24,12 @@
*/
package com.sun.beans.finder;
-import com.sun.beans.WeakCache;
+import com.sun.beans.util.Cache;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
+import static com.sun.beans.util.Cache.Kind.SOFT;
import static sun.reflect.misc.ReflectUtil.isPackageAccessible;
/**
@@ -41,7 +42,18 @@
* @author Sergey A. Malenkov
*/
public final class ConstructorFinder extends AbstractFinder<Constructor<?>> {
- private static final WeakCache<Signature, Constructor<?>> CACHE = new WeakCache<Signature, Constructor<?>>();
+ private static final Cache<Signature, Constructor<?>> CACHE = new Cache<Signature, Constructor<?>>(SOFT, SOFT) {
+ @Override
+ public Constructor create(Signature signature) {
+ try {
+ ConstructorFinder finder = new ConstructorFinder(signature.getArgs());
+ return finder.find(signature.getType().getConstructors());
+ }
+ catch (Exception exception) {
+ throw new SignatureException(exception);
+ }
+ }
+ };
/**
* Finds public constructor
@@ -69,13 +81,12 @@
PrimitiveWrapperMap.replacePrimitivesWithWrappers(args);
Signature signature = new Signature(type, args);
- Constructor<?> constructor = CACHE.get(signature);
- if (constructor != null) {
- return constructor;
+ try {
+ return CACHE.get(signature);
}
- constructor = new ConstructorFinder(args).find(type.getConstructors());
- CACHE.put(signature, constructor);
- return constructor;
+ catch (SignatureException exception) {
+ throw exception.toNoSuchMethodException("Constructor is not found");
+ }
}
/**
--- a/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java Wed Nov 27 10:44:41 2013 -0800
@@ -25,7 +25,7 @@
package com.sun.beans.finder;
import com.sun.beans.TypeResolver;
-import com.sun.beans.WeakCache;
+import com.sun.beans.util.Cache;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -33,6 +33,7 @@
import java.lang.reflect.Type;
import java.util.Arrays;
+import static com.sun.beans.util.Cache.Kind.SOFT;
import static sun.reflect.misc.ReflectUtil.isPackageAccessible;
/**
@@ -45,7 +46,18 @@
* @author Sergey A. Malenkov
*/
public final class MethodFinder extends AbstractFinder<Method> {
- private static final WeakCache<Signature, Method> CACHE = new WeakCache<Signature, Method>();
+ private static final Cache<Signature, Method> CACHE = new Cache<Signature, Method>(SOFT, SOFT) {
+ @Override
+ public Method create(Signature signature) {
+ try {
+ MethodFinder finder = new MethodFinder(signature.getName(), signature.getArgs());
+ return findAccessibleMethod(finder.find(signature.getType().getMethods()));
+ }
+ catch (Exception exception) {
+ throw new SignatureException(exception);
+ }
+ }
+ };
/**
* Finds public method (static or non-static)
@@ -65,16 +77,13 @@
PrimitiveWrapperMap.replacePrimitivesWithWrappers(args);
Signature signature = new Signature(type, name, args);
- Method method = CACHE.get(signature);
- boolean cached = method != null;
- if (cached && isPackageAccessible(method.getDeclaringClass())) {
- return method;
+ try {
+ Method method = CACHE.get(signature);
+ return (method == null) || isPackageAccessible(method.getDeclaringClass()) ? method : CACHE.create(signature);
}
- method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods()));
- if (!cached) {
- CACHE.put(signature, method);
+ catch (SignatureException exception) {
+ throw exception.toNoSuchMethodException("Method '" + name + "' is not found");
}
- return method;
}
/**
--- a/jdk/src/share/classes/com/sun/beans/finder/Signature.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/share/classes/com/sun/beans/finder/Signature.java Wed Nov 27 10:44:41 2013 -0800
@@ -62,6 +62,18 @@
this.args = args;
}
+ Class<?> getType() {
+ return this.type;
+ }
+
+ String getName() {
+ return this.name;
+ }
+
+ Class<?>[] getArgs() {
+ return this.args;
+ }
+
/**
* Indicates whether some other object is "equal to" this one.
*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/finder/SignatureException.java Wed Nov 27 10:44:41 2013 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013, 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 com.sun.beans.finder;
+
+final class SignatureException extends RuntimeException {
+ SignatureException(Throwable cause) {
+ super(cause);
+ }
+
+ NoSuchMethodException toNoSuchMethodException(String message) {
+ Throwable throwable = getCause();
+ if (throwable instanceof NoSuchMethodException) {
+ return (NoSuchMethodException) throwable;
+ }
+ NoSuchMethodException exception = new NoSuchMethodException(message);
+ exception.initCause(throwable);
+ return exception;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/util/Cache.java Wed Nov 27 10:44:41 2013 -0800
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) 2013, 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 com.sun.beans.util;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.util.Objects;
+
+/**
+ * Hash table based implementation of the cache,
+ * which allows to use weak or soft references for keys and values.
+ * An entry in a {@code Cache} will automatically be removed
+ * when its key or value is no longer in ordinary use.
+ *
+ * @author Sergey Malenkov
+ * @since 1.8
+ */
+public abstract class Cache<K,V> {
+ private static final int MAXIMUM_CAPACITY = 1 << 30; // maximum capacity MUST be a power of two <= 1<<30
+
+ private final boolean identity; // defines whether the identity comparison is used
+ private final Kind keyKind; // a reference kind for the cache keys
+ private final Kind valueKind; // a reference kind for the cache values
+
+ private final ReferenceQueue<Object> queue = new ReferenceQueue<>(); // queue for references to remove
+
+ private volatile CacheEntry<K,V>[] table = newTable(1 << 3); // table's length MUST be a power of two
+ private int threshold = 6; // the next size value at which to resize
+ private int size; // the number of key-value mappings contained in this map
+
+ /**
+ * Creates a corresponding value for the specified key.
+ *
+ * @param key a key that can be used to create a value
+ * @return a corresponding value for the specified key
+ */
+ public abstract V create(K key);
+
+ /**
+ * Constructs an empty {@code Cache}.
+ * The default initial capacity is 8.
+ * The default load factor is 0.75.
+ *
+ * @param keyKind a reference kind for keys
+ * @param valueKind a reference kind for values
+ *
+ * @throws NullPointerException if {@code keyKind} or {@code valueKind} are {@code null}
+ */
+ public Cache(Kind keyKind, Kind valueKind) {
+ this(keyKind, valueKind, false);
+ }
+
+ /**
+ * Constructs an empty {@code Cache}
+ * with the specified comparison method.
+ * The default initial capacity is 8.
+ * The default load factor is 0.75.
+ *
+ * @param keyKind a reference kind for keys
+ * @param valueKind a reference kind for values
+ * @param identity defines whether reference-equality
+ * is used in place of object-equality
+ *
+ * @throws NullPointerException if {@code keyKind} or {@code valueKind} are {@code null}
+ */
+ public Cache(Kind keyKind, Kind valueKind, boolean identity) {
+ Objects.requireNonNull(keyKind, "keyKind");
+ Objects.requireNonNull(valueKind, "valueKind");
+ this.keyKind = keyKind;
+ this.valueKind = valueKind;
+ this.identity = identity;
+ }
+
+ /**
+ * Returns the value to which the specified key is mapped,
+ * or {@code null} if there is no mapping for the key.
+ *
+ * @param key the key whose cached value is to be returned
+ * @return a value to which the specified key is mapped,
+ * or {@code null} if there is no mapping for {@code key}
+ *
+ * @throws NullPointerException if {@code key} is {@code null}
+ * or corresponding value is {@code null}
+ */
+ public final V get(K key) {
+ Objects.requireNonNull(key, "key");
+ removeStaleEntries();
+ int hash = hash(key);
+ // unsynchronized search improves performance
+ // the null value does not mean that there are no needed entry
+ CacheEntry<K,V>[] table = this.table; // unsynchronized access
+ V current = getEntryValue(key, hash, table[index(hash, table)]);
+ if (current != null) {
+ return current;
+ }
+ synchronized (this.queue) {
+ // synchronized search improves stability
+ // we must create and add new value if there are no needed entry
+ int index = index(hash, this.table);
+ current = getEntryValue(key, hash, this.table[index]);
+ if (current != null) {
+ return current;
+ }
+ V value = create(key);
+ Objects.requireNonNull(value, "value");
+ this.table[index] = new CacheEntry<>(hash, key, value, this.table[index]);
+ if (++this.size >= this.threshold) {
+ if (this.table.length == MAXIMUM_CAPACITY) {
+ this.threshold = Integer.MAX_VALUE;
+ } else {
+ removeStaleEntries();
+ table = newTable(this.table.length << 1);
+ transfer(this.table, table);
+ // If ignoring null elements and processing ref queue caused massive
+ // shrinkage, then restore old table. This should be rare, but avoids
+ // unbounded expansion of garbage-filled tables.
+ if (this.size >= this.threshold / 2) {
+ this.table = table;
+ this.threshold <<= 1;
+ } else {
+ transfer(table, this.table);
+ }
+ removeStaleEntries();
+ }
+ }
+ return value;
+ }
+ }
+
+ /**
+ * Removes the cached value that corresponds to the specified key.
+ *
+ * @param key the key whose mapping is to be removed from this cache
+ */
+ public final void remove(K key) {
+ if (key != null) {
+ synchronized (this.queue) {
+ removeStaleEntries();
+ int hash = hash(key);
+ int index = index(hash, this.table);
+ CacheEntry<K,V> prev = this.table[index];
+ CacheEntry<K,V> entry = prev;
+ while (entry != null) {
+ CacheEntry<K,V> next = entry.next;
+ if (entry.matches(hash, key)) {
+ if (entry == prev) {
+ this.table[index] = next;
+ } else {
+ prev.next = next;
+ }
+ entry.unlink();
+ break;
+ }
+ prev = entry;
+ entry = next;
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes all of the mappings from this cache.
+ * It will be empty after this call returns.
+ */
+ public final void clear() {
+ synchronized (this.queue) {
+ int index = this.table.length;
+ while (0 < index--) {
+ CacheEntry<K,V> entry = this.table[index];
+ while (entry != null) {
+ CacheEntry<K,V> next = entry.next;
+ entry.unlink();
+ entry = next;
+ }
+ this.table[index] = null;
+ }
+ while (null != this.queue.poll()) {
+ // Clear out the reference queue.
+ }
+ }
+ }
+
+ /**
+ * Retrieves object hash code and applies a supplemental hash function
+ * to the result hash, which defends against poor quality hash functions.
+ * This is critical because {@code Cache} uses power-of-two length hash tables,
+ * that otherwise encounter collisions for hashCodes that do not differ
+ * in lower bits.
+ *
+ * @param key the object which hash code is to be calculated
+ * @return a hash code value for the specified object
+ */
+ private int hash(Object key) {
+ if (this.identity) {
+ int hash = System.identityHashCode(key);
+ return (hash << 1) - (hash << 8);
+ }
+ int hash = key.hashCode();
+ // This function ensures that hashCodes that differ only by
+ // constant multiples at each bit position have a bounded
+ // number of collisions (approximately 8 at default load factor).
+ hash ^= (hash >>> 20) ^ (hash >>> 12);
+ return hash ^ (hash >>> 7) ^ (hash >>> 4);
+ }
+
+ /**
+ * Returns index of the specified hash code in the given table.
+ * Note that the table size must be a power of two.
+ *
+ * @param hash the hash code
+ * @param table the table
+ * @return an index of the specified hash code in the given table
+ */
+ private static int index(int hash, Object[] table) {
+ return hash & (table.length - 1);
+ }
+
+ /**
+ * Creates a new array for the cache entries.
+ *
+ * @param size requested capacity MUST be a power of two
+ * @return a new array for the cache entries
+ */
+ @SuppressWarnings("unchecked")
+ private CacheEntry<K,V>[] newTable(int size) {
+ return (CacheEntry<K,V>[]) new CacheEntry[size];
+ }
+
+ private V getEntryValue(K key, int hash, CacheEntry<K,V> entry) {
+ while (entry != null) {
+ if (entry.matches(hash, key)) {
+ return entry.value.getReferent();
+ }
+ entry = entry.next;
+ }
+ return null;
+ }
+
+ private void removeStaleEntries() {
+ Object reference = this.queue.poll();
+ if (reference != null) {
+ synchronized (this.queue) {
+ do {
+ if (reference instanceof Ref) {
+ Ref ref = (Ref) reference;
+ @SuppressWarnings("unchecked")
+ CacheEntry<K,V> owner = (CacheEntry<K,V>) ref.getOwner();
+ if (owner != null) {
+ int index = index(owner.hash, this.table);
+ CacheEntry<K,V> prev = this.table[index];
+ CacheEntry<K,V> entry = prev;
+ while (entry != null) {
+ CacheEntry<K,V> next = entry.next;
+ if (entry == owner) {
+ if (entry == prev) {
+ this.table[index] = next;
+ } else {
+ prev.next = next;
+ }
+ entry.unlink();
+ break;
+ }
+ prev = entry;
+ entry = next;
+ }
+ }
+ }
+ reference = this.queue.poll();
+ }
+ while (reference != null);
+ }
+ }
+ }
+
+ private void transfer(CacheEntry<K,V>[] oldTable, CacheEntry<K,V>[] newTable) {
+ int oldIndex = oldTable.length;
+ while (0 < oldIndex--) {
+ CacheEntry<K,V> entry = oldTable[oldIndex];
+ oldTable[oldIndex] = null;
+ while (entry != null) {
+ CacheEntry<K,V> next = entry.next;
+ if (entry.key.isStale() || entry.value.isStale()) {
+ entry.unlink();
+ } else {
+ int newIndex = index(entry.hash, newTable);
+ entry.next = newTable[newIndex];
+ newTable[newIndex] = entry;
+ }
+ entry = next;
+ }
+ }
+ }
+
+ /**
+ * Represents a cache entry (key-value pair).
+ */
+ private final class CacheEntry<K,V> {
+ private final int hash;
+ private final Ref<K> key;
+ private final Ref<V> value;
+ private volatile CacheEntry<K,V> next;
+
+ /**
+ * Constructs an entry for the cache.
+ *
+ * @param hash the hash code calculated for the entry key
+ * @param key the entry key
+ * @param value the initial value of the entry
+ * @param next the next entry in a chain
+ */
+ private CacheEntry(int hash, K key, V value, CacheEntry<K,V> next) {
+ this.hash = hash;
+ this.key = Cache.this.keyKind.create(this, key, Cache.this.queue);
+ this.value = Cache.this.valueKind.create(this, value, Cache.this.queue);
+ this.next = next;
+ }
+
+ /**
+ * Determines whether the entry has the given key with the given hash code.
+ *
+ * @param hash an expected hash code
+ * @param object an object to be compared with the entry key
+ * @return {@code true} if the entry has the given key with the given hash code;
+ * {@code false} otherwise
+ */
+ private boolean matches(int hash, Object object) {
+ if (this.hash != hash) {
+ return false;
+ }
+ Object key = this.key.getReferent();
+ return (key == object) || !Cache.this.identity && (key != null) && key.equals(object);
+ }
+
+ /**
+ * Marks the entry as actually removed from the cache.
+ */
+ private void unlink() {
+ this.next = null;
+ this.key.removeOwner();
+ this.value.removeOwner();
+ Cache.this.size--;
+ }
+ }
+
+ /**
+ * Basic interface for references.
+ * It defines the operations common for the all kind of references.
+ *
+ * @param <T> the type of object to refer
+ */
+ private static interface Ref<T> {
+ /**
+ * Returns the object that possesses information about the reference.
+ *
+ * @return the owner of the reference or {@code null} if the owner is unknown
+ */
+ Object getOwner();
+
+ /**
+ * Returns the object to refer.
+ *
+ * @return the referred object or {@code null} if it was collected
+ */
+ T getReferent();
+
+ /**
+ * Determines whether the referred object was taken by the garbage collector or not.
+ *
+ * @return {@code true} if the referred object was collected
+ */
+ boolean isStale();
+
+ /**
+ * Marks this reference as removed from the cache.
+ */
+ void removeOwner();
+ }
+
+ /**
+ * Represents a reference kind.
+ */
+ public static enum Kind {
+ STRONG {
+ <T> Ref<T> create(Object owner, T value, ReferenceQueue<? super T> queue) {
+ return new Strong<>(owner, value);
+ }
+ },
+ SOFT {
+ <T> Ref<T> create(Object owner, T referent, ReferenceQueue<? super T> queue) {
+ return (referent == null)
+ ? new Strong<>(owner, referent)
+ : new Soft<>(owner, referent, queue);
+ }
+ },
+ WEAK {
+ <T> Ref<T> create(Object owner, T referent, ReferenceQueue<? super T> queue) {
+ return (referent == null)
+ ? new Strong<>(owner, referent)
+ : new Weak<>(owner, referent, queue);
+ }
+ };
+
+ /**
+ * Creates a reference to the specified object.
+ *
+ * @param <T> the type of object to refer
+ * @param owner the owner of the reference, if needed
+ * @param referent the object to refer
+ * @param queue the queue to register the reference with,
+ * or {@code null} if registration is not required
+ * @return the reference to the specified object
+ */
+ abstract <T> Ref<T> create(Object owner, T referent, ReferenceQueue<? super T> queue);
+
+ /**
+ * This is an implementation of the {@link Cache.Ref} interface
+ * that uses the strong references that prevent their referents
+ * from being made finalizable, finalized, and then reclaimed.
+ *
+ * @param <T> the type of object to refer
+ */
+ private static final class Strong<T> implements Ref<T> {
+ private Object owner;
+ private final T referent;
+
+ /**
+ * Creates a strong reference to the specified object.
+ *
+ * @param owner the owner of the reference, if needed
+ * @param referent the non-null object to refer
+ */
+ private Strong(Object owner, T referent) {
+ this.owner = owner;
+ this.referent = referent;
+ }
+
+ /**
+ * Returns the object that possesses information about the reference.
+ *
+ * @return the owner of the reference or {@code null} if the owner is unknown
+ */
+ public Object getOwner() {
+ return this.owner;
+ }
+
+ /**
+ * Returns the object to refer.
+ *
+ * @return the referred object
+ */
+ public T getReferent() {
+ return this.referent;
+ }
+
+ /**
+ * Determines whether the referred object was taken by the garbage collector or not.
+ *
+ * @return {@code true} if the referred object was collected
+ */
+ public boolean isStale() {
+ return false;
+ }
+
+ /**
+ * Marks this reference as removed from the cache.
+ */
+ public void removeOwner() {
+ this.owner = null;
+ }
+ }
+
+ /**
+ * This is an implementation of the {@link Cache.Ref} interface
+ * that uses the soft references that are cleared at the discretion
+ * of the garbage collector in response to a memory request.
+ *
+ * @param <T> the type of object to refer
+ * @see java.lang.ref.SoftReference
+ */
+ private static final class Soft<T> extends SoftReference<T> implements Ref<T> {
+ private Object owner;
+
+ /**
+ * Creates a soft reference to the specified object.
+ *
+ * @param owner the owner of the reference, if needed
+ * @param referent the non-null object to refer
+ * @param queue the queue to register the reference with,
+ * or {@code null} if registration is not required
+ */
+ private Soft(Object owner, T referent, ReferenceQueue<? super T> queue) {
+ super(referent, queue);
+ this.owner = owner;
+ }
+
+ /**
+ * Returns the object that possesses information about the reference.
+ *
+ * @return the owner of the reference or {@code null} if the owner is unknown
+ */
+ public Object getOwner() {
+ return this.owner;
+ }
+
+ /**
+ * Returns the object to refer.
+ *
+ * @return the referred object or {@code null} if it was collected
+ */
+ public T getReferent() {
+ return get();
+ }
+
+ /**
+ * Determines whether the referred object was taken by the garbage collector or not.
+ *
+ * @return {@code true} if the referred object was collected
+ */
+ public boolean isStale() {
+ return null == get();
+ }
+
+ /**
+ * Marks this reference as removed from the cache.
+ */
+ public void removeOwner() {
+ this.owner = null;
+ }
+ }
+
+ /**
+ * This is an implementation of the {@link Cache.Ref} interface
+ * that uses the weak references that do not prevent their referents
+ * from being made finalizable, finalized, and then reclaimed.
+ *
+ * @param <T> the type of object to refer
+ * @see java.lang.ref.WeakReference
+ */
+ private static final class Weak<T> extends WeakReference<T> implements Ref<T> {
+ private Object owner;
+
+ /**
+ * Creates a weak reference to the specified object.
+ *
+ * @param owner the owner of the reference, if needed
+ * @param referent the non-null object to refer
+ * @param queue the queue to register the reference with,
+ * or {@code null} if registration is not required
+ */
+ private Weak(Object owner, T referent, ReferenceQueue<? super T> queue) {
+ super(referent, queue);
+ this.owner = owner;
+ }
+
+ /**
+ * Returns the object that possesses information about the reference.
+ *
+ * @return the owner of the reference or {@code null} if the owner is unknown
+ */
+ public Object getOwner() {
+ return this.owner;
+ }
+
+ /**
+ * Returns the object to refer.
+ *
+ * @return the referred object or {@code null} if it was collected
+ */
+ public T getReferent() {
+ return get();
+ }
+
+ /**
+ * Determines whether the referred object was taken by the garbage collector or not.
+ *
+ * @return {@code true} if the referred object was collected
+ */
+ public boolean isStale() {
+ return null == get();
+ }
+
+ /**
+ * Marks this reference as removed from the cache.
+ */
+ public void removeOwner() {
+ this.owner = null;
+ }
+ }
+ }
+}
--- a/jdk/src/share/classes/java/awt/Container.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/share/classes/java/awt/Container.java Wed Nov 27 10:44:41 2013 -0800
@@ -43,7 +43,6 @@
import java.security.AccessController;
-import java.util.Arrays;
import java.util.EventListener;
import java.util.HashSet;
import java.util.Set;
@@ -4427,6 +4426,7 @@
stopListeningForOtherDrags();
mouseEventTarget = null;
targetLastEntered = null;
+ targetLastEnteredDT = null;
}
/**
@@ -4617,59 +4617,80 @@
}
/*
+ * Generates dnd enter/exit events as mouse moves over lw components
+ * @param targetOver Target mouse is over (including native container)
+ * @param e SunDropTarget mouse event in native container
+ */
+ private void trackDropTargetEnterExit(Component targetOver, MouseEvent e) {
+ int id = e.getID();
+ if (id == MouseEvent.MOUSE_ENTERED && isMouseDTInNativeContainer) {
+ // This can happen if a lightweight component which initiated the
+ // drag has an associated drop target. MOUSE_ENTERED comes when the
+ // mouse is in the native container already. To propagate this event
+ // properly we should null out targetLastEntered.
+ targetLastEnteredDT = null;
+ } else if (id == MouseEvent.MOUSE_ENTERED) {
+ isMouseDTInNativeContainer = true;
+ } else if (id == MouseEvent.MOUSE_EXITED) {
+ isMouseDTInNativeContainer = false;
+ }
+ targetLastEnteredDT = retargetMouseEnterExit(targetOver, e,
+ targetLastEnteredDT,
+ isMouseDTInNativeContainer);
+ }
+
+ /*
* Generates enter/exit events as mouse moves over lw components
* @param targetOver Target mouse is over (including native container)
* @param e Mouse event in native container
*/
private void trackMouseEnterExit(Component targetOver, MouseEvent e) {
- Component targetEnter = null;
- int id = e.getID();
-
- if (e instanceof SunDropTargetEvent &&
- id == MouseEvent.MOUSE_ENTERED &&
- isMouseInNativeContainer == true) {
- // This can happen if a lightweight component which initiated the
- // drag has an associated drop target. MOUSE_ENTERED comes when the
- // mouse is in the native container already. To propagate this event
- // properly we should null out targetLastEntered.
- targetLastEntered = null;
- } else if ( id != MouseEvent.MOUSE_EXITED &&
+ if (e instanceof SunDropTargetEvent) {
+ trackDropTargetEnterExit(targetOver, e);
+ return;
+ }
+ int id = e.getID();
+
+ if ( id != MouseEvent.MOUSE_EXITED &&
id != MouseEvent.MOUSE_DRAGGED &&
id != LWD_MOUSE_DRAGGED_OVER &&
- isMouseInNativeContainer == false ) {
+ !isMouseInNativeContainer) {
// any event but an exit or drag means we're in the native container
isMouseInNativeContainer = true;
startListeningForOtherDrags();
- } else if ( id == MouseEvent.MOUSE_EXITED ) {
+ } else if (id == MouseEvent.MOUSE_EXITED) {
isMouseInNativeContainer = false;
stopListeningForOtherDrags();
}
-
- if (isMouseInNativeContainer) {
- targetEnter = targetOver;
- }
-
- if (targetLastEntered == targetEnter) {
- return;
- }
-
- if (targetLastEntered != null) {
- retargetMouseEvent(targetLastEntered, MouseEvent.MOUSE_EXITED, e);
+ targetLastEntered = retargetMouseEnterExit(targetOver, e,
+ targetLastEntered,
+ isMouseInNativeContainer);
+ }
+
+ private Component retargetMouseEnterExit(Component targetOver, MouseEvent e,
+ Component lastEntered,
+ boolean inNativeContainer) {
+ int id = e.getID();
+ Component targetEnter = inNativeContainer ? targetOver : null;
+
+ if (lastEntered != targetEnter) {
+ if (lastEntered != null) {
+ retargetMouseEvent(lastEntered, MouseEvent.MOUSE_EXITED, e);
+ }
+ if (id == MouseEvent.MOUSE_EXITED) {
+ // consume native exit event if we generate one
+ e.consume();
+ }
+
+ if (targetEnter != null) {
+ retargetMouseEvent(targetEnter, MouseEvent.MOUSE_ENTERED, e);
+ }
+ if (id == MouseEvent.MOUSE_ENTERED) {
+ // consume native enter event if we generate one
+ e.consume();
+ }
}
- if (id == MouseEvent.MOUSE_EXITED) {
- // consume native exit event if we generate one
- e.consume();
- }
-
- if (targetEnter != null) {
- retargetMouseEvent(targetEnter, MouseEvent.MOUSE_ENTERED, e);
- }
- if (id == MouseEvent.MOUSE_ENTERED) {
- // consume native enter event if we generate one
- e.consume();
- }
-
- targetLastEntered = targetEnter;
+ return targetEnter;
}
/*
@@ -4908,21 +4929,31 @@
private transient Component mouseEventTarget;
/**
- * The last component entered
+ * The last component entered by the {@code MouseEvent}.
*/
private transient Component targetLastEntered;
/**
+ * The last component entered by the {@code SunDropTargetEvent}.
+ */
+ private transient Component targetLastEnteredDT;
+
+ /**
* Indicates whether {@code mouseEventTarget} was removed and nulled
*/
private transient boolean isCleaned;
/**
- * Is the mouse over the native container
+ * Is the mouse over the native container.
*/
private transient boolean isMouseInNativeContainer = false;
/**
+ * Is DnD over the native container.
+ */
+ private transient boolean isMouseDTInNativeContainer = false;
+
+ /**
* This variable is not used, but kept for serialization compatibility
*/
private Cursor nativeCursor;
@@ -4960,5 +4991,8 @@
if (targetLastEntered == removedComponent) {
targetLastEntered = null;
}
+ if (targetLastEnteredDT == removedComponent) {
+ targetLastEnteredDT = null;
+ }
}
}
--- a/jdk/src/share/classes/javax/swing/JPopupMenu.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/share/classes/javax/swing/JPopupMenu.java Wed Nov 27 10:44:41 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -736,7 +736,7 @@
if (pref == null || pref.width != getWidth() ||
pref.height != getHeight()) {
- popup = getPopup();
+ showPopup();
} else {
validate();
}
@@ -787,7 +787,7 @@
if(b) {
firePopupMenuWillBecomeVisible();
- popup = getPopup();
+ showPopup();
firePropertyChange("visible", Boolean.FALSE, Boolean.TRUE);
@@ -805,7 +805,7 @@
}
/**
- * Returns a <code>Popup</code> instance from the
+ * Retrieves <code>Popup</code> instance from the
* <code>PopupMenuUI</code> that has had <code>show</code> invoked on
* it. If the current <code>popup</code> is non-null,
* this will invoke <code>dispose</code> of it, and then
@@ -814,7 +814,7 @@
* This does NOT fire any events, it is up the caller to dispatch
* the necessary events.
*/
- private Popup getPopup() {
+ private void showPopup() {
Popup oldPopup = popup;
if (oldPopup != null) {
@@ -838,8 +838,8 @@
desiredLocationY);
popupFactory.setPopupType(PopupFactory.LIGHT_WEIGHT_POPUP);
+ popup = newPopup;
newPopup.show();
- return newPopup;
}
/**
@@ -873,7 +873,7 @@
desiredLocationX = x;
desiredLocationY = y;
if(popup != null && (x != oldX || y != oldY)) {
- popup = getPopup();
+ showPopup();
}
}
@@ -1030,7 +1030,7 @@
Dimension newSize = getPreferredSize();
if (!oldSize.equals(newSize)) {
- popup = getPopup();
+ showPopup();
}
}
}
--- a/jdk/src/share/classes/sun/applet/AppletPanel.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/share/classes/sun/applet/AppletPanel.java Wed Nov 27 10:44:41 2013 -0800
@@ -794,18 +794,13 @@
doInit = true;
} else {
// serName is not null;
- InputStream is = (InputStream)
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction() {
- public Object run() {
- return loader.getResourceAsStream(serName);
- }
- });
- ObjectInputStream ois =
- new AppletObjectInputStream(is, loader);
- Object serObject = ois.readObject();
- applet = (Applet) serObject;
- doInit = false; // skip over the first init
+ try (InputStream is = AccessController.doPrivileged(
+ (PrivilegedAction<InputStream>)() -> loader.getResourceAsStream(serName));
+ ObjectInputStream ois = new AppletObjectInputStream(is, loader)) {
+
+ applet = (Applet) ois.readObject();
+ doInit = false; // skip over the first init
+ }
}
// Determine the JDK level that the applet targets.
@@ -1239,20 +1234,13 @@
// append .class
final String resourceName = name + ".class";
- InputStream is = null;
byte[] classHeader = new byte[8];
- try {
- is = (InputStream) java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction() {
- public Object run() {
- return loader.getResourceAsStream(resourceName);
- }
- });
+ try (InputStream is = AccessController.doPrivileged(
+ (PrivilegedAction<InputStream>) () -> loader.getResourceAsStream(resourceName))) {
// Read the first 8 bytes of the class file
int byteRead = is.read(classHeader, 0, 8);
- is.close();
// return if the header is not read in entirely
// for some reasons.
--- a/jdk/src/share/classes/sun/applet/AppletViewer.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/share/classes/sun/applet/AppletViewer.java Wed Nov 27 10:44:41 2013 -0800
@@ -668,11 +668,11 @@
String dname = fd.getDirectory();
File file = new File(dname, fname);
- try {
- BufferedOutputStream s = new BufferedOutputStream(new FileOutputStream(file));
- ObjectOutputStream os = new ObjectOutputStream(s);
- showStatus(amh.getMessage("appletsave.err1",
- panel.applet.toString(), file.toString()));
+ try (FileOutputStream fos = new FileOutputStream(file);
+ BufferedOutputStream bos = new BufferedOutputStream(fos);
+ ObjectOutputStream os = new ObjectOutputStream(bos)) {
+
+ showStatus(amh.getMessage("appletsave.err1", panel.applet.toString(), file.toString()));
os.writeObject(panel.applet);
} catch (IOException ex) {
System.err.println(amh.getMessage("appletsave.err2", ex));
--- a/jdk/src/share/classes/sun/applet/Main.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/share/classes/sun/applet/Main.java Wed Nov 27 10:44:41 2013 -0800
@@ -432,10 +432,8 @@
}
// SAVE THE FILE
- try {
- FileOutputStream out = new FileOutputStream(dotAV);
+ try (FileOutputStream out = new FileOutputStream(dotAV)) {
avProps.store(out, lookup("main.prop.store"));
- out.close();
} catch (IOException e) {
System.err.println(lookup("main.err.prop.cantsave",
dotAV.toString()));
@@ -472,13 +470,10 @@
// read the file
Properties tmpProps = new Properties();
- try {
- FileInputStream in = new FileInputStream(inFile);
+ try (FileInputStream in = new FileInputStream(inFile)) {
tmpProps.load(new BufferedInputStream(in));
- in.close();
} catch (IOException e) {
- System.err.println(lookup("main.err.prop.cantread",
- inFile.toString()));
+ System.err.println(lookup("main.err.prop.cantread", inFile.toString()));
}
// pick off the properties we care about
--- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Wed Nov 27 10:44:41 2013 -0800
@@ -740,37 +740,7 @@
// Bounds of the window
Rectangle targetBounds = AWTAccessor.getComponentAccessor().getBounds((Component)target);
- Point newLocation = targetBounds.getLocation();
- if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) {
- // Location, Client size + insets
- newLocation = new Point(xe.get_x() - currentInsets.left, xe.get_y() - currentInsets.top);
- } else {
- // ICCCM 4.1.5 states that a real ConfigureNotify will be sent when
- // a window is resized but the client can not tell if the window was
- // moved or not. The client should consider the position as unkown
- // and use TranslateCoordinates to find the actual position.
- //
- // TODO this should be the default for every case.
- switch (XWM.getWMID()) {
- case XWM.CDE_WM:
- case XWM.MOTIF_WM:
- case XWM.METACITY_WM:
- case XWM.MUTTER_WM:
- case XWM.SAWFISH_WM:
- {
- Point xlocation = queryXLocation();
- if (log.isLoggable(PlatformLogger.Level.FINE)) {
- log.fine("New X location: {0}", xlocation);
- }
- if (xlocation != null) {
- newLocation = xlocation;
- }
- break;
- }
- default:
- break;
- }
- }
+ Point newLocation = getNewLocation(xe, currentInsets.left, currentInsets.top);
WindowDimensions newDimensions =
new WindowDimensions(newLocation,
@@ -1261,12 +1231,4 @@
}
super.handleWindowFocusOut(oppositeWindow, serial);
}
-
- private Point queryXLocation()
- {
- return XlibUtil.translateCoordinates(
- getContentWindow(),
- XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber()),
- new Point(0, 0));
- }
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Wed Nov 27 10:44:41 2013 -0800
@@ -740,15 +740,67 @@
public void paletteChanged() {
}
+ private Point queryXLocation()
+ {
+ return XlibUtil.translateCoordinates(
+ getContentWindow(),
+ XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber()),
+ new Point(0, 0));
+ }
+
+ protected Point getNewLocation(XConfigureEvent xe, int leftInset, int topInset) {
+ // Bounds of the window
+ Rectangle targetBounds = AWTAccessor.getComponentAccessor().getBounds((Component)target);
+
+ int runningWM = XWM.getWMID();
+ Point newLocation = targetBounds.getLocation();
+ if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) {
+ // Location, Client size + insets
+ newLocation = new Point(xe.get_x() - leftInset, xe.get_y() - topInset);
+ } else {
+ // ICCCM 4.1.5 states that a real ConfigureNotify will be sent when
+ // a window is resized but the client can not tell if the window was
+ // moved or not. The client should consider the position as unkown
+ // and use TranslateCoordinates to find the actual position.
+ //
+ // TODO this should be the default for every case.
+ switch (runningWM) {
+ case XWM.CDE_WM:
+ case XWM.MOTIF_WM:
+ case XWM.METACITY_WM:
+ case XWM.MUTTER_WM:
+ case XWM.SAWFISH_WM:
+ {
+ Point xlocation = queryXLocation();
+ if (log.isLoggable(PlatformLogger.Level.FINE)) {
+ log.fine("New X location: {0}", xlocation);
+ }
+ if (xlocation != null) {
+ newLocation = xlocation;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return newLocation;
+ }
+
/*
* Overridden to check if we need to update our GraphicsDevice/Config
* Added for 4934052.
*/
@Override
public void handleConfigureNotifyEvent(XEvent xev) {
- // TODO: We create an XConfigureEvent every time we override
- // handleConfigureNotify() - too many!
XConfigureEvent xe = xev.get_xconfigure();
+ /*
+ * Correct window location which could be wrong in some cases.
+ * See getNewLocation() for the details.
+ */
+ Point newLocation = getNewLocation(xe, 0, 0);
+ xe.set_x(newLocation.x);
+ xe.set_y(newLocation.y);
checkIfOnNewScreen(new Rectangle(xe.get_x(),
xe.get_y(),
xe.get_width(),
--- a/jdk/test/java/awt/EventQueue/MainAppContext/MainAppContext.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/test/java/awt/EventQueue/MainAppContext/MainAppContext.java Wed Nov 27 10:44:41 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011,2013 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
@@ -23,9 +23,9 @@
/*
* @test
- * @bug 7122796
- * @summary Tests 7122796
- * @author anthony.petrov@oracle.com
+ * @bug 8004584
+ * @summary Tests 8004584
+ * @author anthony.petrov@oracle.com, petr.pchelko@oracle.com
*/
import java.awt.*;
@@ -37,12 +37,10 @@
public static void main(String[] args) {
ThreadGroup secondGroup = new ThreadGroup("test");
- new Thread(secondGroup, new Runnable() {
- public void run() {
- SunToolkit.createNewAppContext();
- test(true);
- }
- }).start();
+ new Thread(secondGroup, () -> {
+ SunToolkit.createNewAppContext();
+ test(true);
+ }).start();
// Sleep on the main thread so that the AWT Toolkit is initialized
// in a user AppContext first
@@ -51,9 +49,11 @@
test(false);
}
- private static void test(boolean userAppContext) {
- if (Toolkit.getDefaultToolkit().getSystemEventQueue() == null) {
- throw new RuntimeException("No EventQueue for the current app context! userAppContext: " + userAppContext);
+ private static void test(boolean expectAppContext) {
+ boolean appContextIsCreated = AppContext.getAppContext() != null;
+ if (expectAppContext != appContextIsCreated) {
+ throw new RuntimeException("AppContext is created: " + appContextIsCreated
+ + " expected: " + expectAppContext);
}
}
}
--- a/jdk/test/java/awt/Menu/OpensWithNoGrab/OpensWithNoGrab.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/test/java/awt/Menu/OpensWithNoGrab/OpensWithNoGrab.java Wed Nov 27 10:44:41 2013 -0800
@@ -33,6 +33,8 @@
import java.awt.*;
import java.awt.event.*;
+
+import sun.awt.OSInfo;
import test.java.awt.regtesthelpers.Util;
public class OpensWithNoGrab
@@ -49,8 +51,8 @@
Sysout.createDialog( );
Sysout.printInstructions( instructions );
- String toolkit = Toolkit.getDefaultToolkit().getClass().getName();
- if (toolkit.equals("sun.awt.windows.WToolkit")){
+ if (!(OSInfo.getOSType().equals(OSInfo.OSType.LINUX)
+ || OSInfo.getOSType().equals(OSInfo.OSType.SOLARIS))) {
System.out.println("This test is for XAWT/Motif only");
OpensWithNoGrab.pass();
}
--- a/jdk/test/java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/test/java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java Wed Nov 27 10:44:41 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -28,15 +28,16 @@
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.InputEvent;
+
import sun.awt.SunToolkit;
-/*
+
+/**
* @test
* @bug 8008728
* @summary [macosx] Swing. JDialog. Modal dialog goes to background
* @author Alexandr Scherbatiy
* @run main ModalDialogOrderingTest
*/
-
public class ModalDialogOrderingTest {
private static final Color DIALOG_COLOR = Color.GREEN;
@@ -45,13 +46,13 @@
public static void main(String[] args) {
final Frame frame = new Frame("Test");
- frame.setSize(100, 100);
+ frame.setSize(400, 400);
frame.setBackground(FRAME_COLOR);
frame.setVisible(true);
- final Dialog modalDialog = new Dialog((Frame) null, true);
+ final Dialog modalDialog = new Dialog(null, true);
modalDialog.setTitle("Modal Dialog");
- modalDialog.setSize(50, 50);
+ modalDialog.setSize(400, 200);
modalDialog.setBackground(DIALOG_COLOR);
modalDialog.setModal(true);
@@ -68,40 +69,35 @@
private static void runTest(Dialog dialog, Frame frame) {
try {
- SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
Robot robot = new Robot();
- robot.setAutoDelay(15);
+ robot.setAutoDelay(50);
robot.mouseMove(300, 300);
while (!dialog.isVisible()) {
- toolkit.realSync();
+ sleep();
}
Rectangle dialogBounds = dialog.getBounds();
Rectangle frameBounds = frame.getBounds();
- double x0 = dialogBounds.getX();
- double y0 = dialogBounds.getY();
- double x1 = dialogBounds.getX() + dialogBounds.getWidth();
- double y1 = dialogBounds.getY() + dialogBounds.getHeight();
- double x2 = frameBounds.getX() + frameBounds.getWidth();
- double y2 = frameBounds.getY() + frameBounds.getHeight();
+ int y1 = dialogBounds.y + dialogBounds.height;
+ int y2 = frameBounds.y + frameBounds.height;
- int clickX = (int) ((x2 + x1) / 2);
- int clickY = (int) ((y2 + y1) / 2);
+ int clickX = frameBounds.x + frameBounds.width / 2;
+ int clickY = y1 + (y2 - y1) / 2;
robot.mouseMove(clickX, clickY);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
- toolkit.realSync();
+ sleep();
- int colorX = (int) ((x0 + x1) / 2);
- int colorY = (int) ((y0 + y1) / 2);
+ int colorX = dialogBounds.x + dialogBounds.width / 2;
+ int colorY = dialogBounds.y + dialogBounds.height / 2;
Color color = robot.getPixelColor(colorX, colorY);
- dialog.setVisible(false);
- frame.setVisible(false);
+ dialog.dispose();
+ frame.dispose();
if (!DIALOG_COLOR.equals(color)) {
throw new RuntimeException("The frame is on top"
@@ -111,4 +107,12 @@
throw new RuntimeException(ex);
}
}
+
+ private static void sleep() {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ignored) {
+ }
+ ((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
+ }
}
--- a/jdk/test/java/awt/Mouse/EnterExitEvents/FullscreenEnterEventTest.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/test/java/awt/Mouse/EnterExitEvents/FullscreenEnterEventTest.java Wed Nov 27 10:44:41 2013 -0800
@@ -61,6 +61,12 @@
return;
}
+ //Move the mouse out, because it could interfere with the test.
+ Robot r = Util.createRobot();
+ Util.waitForIdle(r);
+ r.mouseMove(0, 0);
+ Util.waitForIdle(r);
+
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
@@ -69,7 +75,6 @@
});
//Move the mouse away from the frame and check the View-base full screen mode
- Robot r = Util.createRobot();
Util.waitForIdle(r);
r.mouseMove(500, 500);
Util.waitForIdle(r);
@@ -92,6 +97,7 @@
});
//Test native full screen support
+ Util.waitForIdle(r);
Point fullScreenButtonPos = frame.getLocation();
fullScreenButtonPos.translate(frame.getWidth() - 10, 10);
r.mouseMove(fullScreenButtonPos.x, fullScreenButtonPos.y);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Window/TopLevelLocation/TopLevelLocation.java Wed Nov 27 10:44:41 2013 -0800
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2013, 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 8027628
+ * @author Oleg Pekhovskiy
+ * @summary JWindow jumps to (0, 0) after mouse clicked
+ * @run main TopLevelLocation
+ */
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.JFrame;
+import javax.swing.JWindow;
+
+public class TopLevelLocation {
+
+ private static JFrame frame;
+ private static JWindow window;
+ private static boolean passed = true;
+
+ public static void main(String[] args) throws Exception {
+ EventQueue.invokeAndWait(() -> {
+ frame = new JFrame();
+ frame.getContentPane().setBackground(Color.PINK);
+ frame.setBounds(100, 100, 500, 400);
+ frame.setUndecorated(true);
+ frame.setVisible(true);
+ window = new JWindow(frame);
+ window.setBackground(Color.BLUE);
+ window.setAlwaysOnTop(true);
+ window.setBounds(200, 200, 200, 200);
+ window.addMouseListener(new MouseAdapter() {
+ private Point dragOrigin = null;
+ private Dimension origSize = null;
+ private Point origLoc = null;
+ private Point lastLoc = null;
+ private boolean left = false;
+ private boolean top = false;
+ private boolean bottom = false;
+ private boolean right = false;
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+ System.out.println("mousePressed");
+ dragOrigin = e.getLocationOnScreen();
+ origSize = window.getSize();
+ origLoc = window.getLocationOnScreen();
+ if (lastLoc != null) {
+ System.out.println("SET LOCATION: " + lastLoc);
+ System.out.println("CURRENT LOCATION: " + origLoc);
+ if (lastLoc.x != origLoc.x || lastLoc.y != origLoc.y) {
+ passed = false;
+ }
+ }
+ right = (origLoc.x + window.getWidth() - dragOrigin.x) < 5;
+ left = !right && dragOrigin.x - origLoc.x < 5;
+ bottom = (origLoc.y + window.getHeight() - dragOrigin.y) < 5;
+ top = !bottom && dragOrigin.y - origLoc.y < 5;
+ }
+
+ @Override
+ public void mouseDragged(MouseEvent e) {
+ System.out.println("mouseDragged");
+ resize(e);
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ System.out.println("mouseReleased");
+ resize(e);
+ }
+
+ void resize(MouseEvent e) {
+ Point dragDelta = e.getLocationOnScreen();
+ dragDelta.translate(-dragOrigin.x, -dragOrigin.y);
+ Point newLoc = new Point(origLoc);
+ newLoc.translate(dragDelta.x, dragDelta.y);
+ Dimension newSize = new Dimension(origSize);
+ if (left || right) {
+ newSize.width += right ? dragDelta.x : -dragDelta.x;
+ }
+ if (top || bottom) {
+ newSize.height += bottom ? dragDelta.y : -dragDelta.y;
+ }
+ if (right || (top || bottom) && !left) {
+ newLoc.x = origLoc.x;
+ }
+ if (bottom || (left || right) && !top) {
+ newLoc.y = origLoc.y;
+ }
+ window.setBounds(newLoc.x, newLoc.y, newSize.width, newSize.height);
+ lastLoc = newLoc;
+ }
+ });
+ window.setVisible(true);
+ });
+ Thread.sleep(500);
+ Dimension size = window.getSize();
+ Point location = window.getLocation();
+ Robot robot = new Robot();
+ robot.setAutoDelay(200);
+ robot.setAutoWaitForIdle(true);
+ robot.waitForIdle();
+ robot.mouseMove(location.x + size.height - 2, location.y + size.width - 2);
+ robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK);
+ robot.mouseMove(location.x + size.height, location.y + size.width);
+ robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK);
+ robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK);
+ robot.mouseMove(location.x + size.height + 2, location.y + size.width + 2);
+ robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK);
+ Thread.sleep(500);
+ frame.dispose();
+ if (!passed) {
+ throw new RuntimeException("TEST FAILED: Location doesn't match!");
+ }
+ System.out.println("TEST PASSED!");
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/dnd/MissingDragExitEventTest/MissingDragExitEventTest.java Wed Nov 27 10:44:41 2013 -0800
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2013, 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 8027913
+ * @library ../../regtesthelpers
+ * @build Util
+ * @compile MissingDragExitEventTest.java
+ * @run main/othervm MissingDragExitEventTest
+ * @author Sergey Bylokhov
+ */
+
+import java.awt.Color;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetAdapter;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+import javax.swing.JFrame;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+import sun.awt.SunToolkit;
+import test.java.awt.regtesthelpers.Util;
+
+public class MissingDragExitEventTest {
+
+ private static volatile JFrame frame;
+ private static boolean FAILED;
+ private static boolean MOUSE_ENTERED_DT;
+ private static boolean MOUSE_ENTERED;
+ private static boolean MOUSE_EXIT_TD;
+ private static boolean MOUSE_EXIT;
+ private static int SIZE = 300;
+
+ private static void initAndShowUI() {
+ frame = new JFrame("Test frame");
+
+ frame.setSize(SIZE, SIZE);
+ frame.setLocationRelativeTo(null);
+ final JTextArea jta = new JTextArea();
+ jta.setBackground(Color.RED);
+ frame.add(jta);
+ jta.setText("1234567890");
+ jta.setFont(jta.getFont().deriveFont(150f));
+ jta.setDragEnabled(true);
+ jta.selectAll();
+ jta.setDropTarget(new DropTarget(jta, DnDConstants.ACTION_COPY,
+ new TestdropTargetListener()));
+ jta.addMouseListener(new TestMouseAdapter());
+ frame.setVisible(true);
+ }
+
+ public static void main(final String[] args) throws Exception {
+ try {
+ final Robot r = new Robot();
+ r.setAutoDelay(50);
+ r.mouseMove(100, 100);
+ Util.waitForIdle(r);
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ initAndShowUI();
+ }
+ });
+
+ final Point inside = new Point(frame.getLocationOnScreen());
+ inside.translate(20, SIZE / 2);
+ final Point outer = new Point(inside);
+ outer.translate(-40, 0);
+ r.mouseMove(inside.x, inside.y);
+ r.mousePress(InputEvent.BUTTON1_MASK);
+ try {
+ for (int i = 0; i < 3; ++i) {
+ Util.mouseMove(r, inside, outer);
+ Util.mouseMove(r, outer, inside);
+ }
+ } finally {
+ r.mouseRelease(InputEvent.BUTTON1_MASK);
+ }
+ sleep();
+
+ if (FAILED || !MOUSE_ENTERED || !MOUSE_ENTERED_DT || !MOUSE_EXIT
+ || !MOUSE_EXIT_TD) {
+ throw new RuntimeException("Failed");
+ }
+ } finally {
+ if (frame != null) {
+ frame.dispose();
+ }
+ }
+ }
+
+ private static void sleep() {
+ try {
+ Thread.sleep(10000);
+ } catch (InterruptedException ignored) {
+ }
+ ((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
+ }
+
+ static class TestdropTargetListener extends DropTargetAdapter {
+
+ private volatile boolean inside;
+
+ @Override
+ public void dragEnter(final DropTargetDragEvent dtde) {
+ if (inside) {
+ FAILED = true;
+ Thread.dumpStack();
+ }
+ inside = true;
+ MOUSE_ENTERED_DT = true;
+ try {
+ Thread.sleep(10000); // we should have time to leave a component
+ } catch (InterruptedException ignored) {
+ }
+ }
+
+ @Override
+ public void dragOver(final DropTargetDragEvent dtde) {
+ if (!inside) {
+ FAILED = true;
+ Thread.dumpStack();
+ }
+ }
+
+ @Override
+ public void dragExit(final DropTargetEvent dte) {
+ if (!inside) {
+ FAILED = true;
+ Thread.dumpStack();
+ }
+ inside = false;
+ MOUSE_EXIT_TD = true;
+ }
+
+ @Override
+ public void drop(final DropTargetDropEvent dtde) {
+ if (!inside) {
+ FAILED = true;
+ Thread.dumpStack();
+ }
+ inside = false;
+ }
+ }
+
+ static class TestMouseAdapter extends MouseAdapter {
+
+ private volatile boolean inside;
+
+ @Override
+ public void mouseEntered(final MouseEvent e) {
+ if (inside) {
+ FAILED = true;
+ Thread.dumpStack();
+ }
+ inside = true;
+ MOUSE_ENTERED = true;
+ }
+
+ @Override
+ public void mouseExited(final MouseEvent e) {
+ if (!inside) {
+ FAILED = true;
+ Thread.dumpStack();
+ }
+ inside = false;
+ MOUSE_EXIT = true;
+ }
+ }
+}
--- a/jdk/test/java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/test/java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java Wed Nov 27 10:44:41 2013 -0800
@@ -31,7 +31,7 @@
/*
* @test
- * @bug 8007156
+ * @bug 8007156 8025126
* @summary Extended key code is not set for a key event
* @author Alexandr Scherbatiy
* @run main ExtendedKeyCodeTest
@@ -44,6 +44,7 @@
public static void main(String[] args) throws Exception {
SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
Robot robot = new Robot();
+ robot.setAutoDelay(50);
Frame frame = new Frame();
frame.setSize(300, 300);
@@ -54,14 +55,14 @@
public void keyPressed(KeyEvent e) {
eventsCount++;
setExtendedKeyCode = setExtendedKeyCode && (e.getExtendedKeyCode()
- == ExtendedKeyCodes.getExtendedKeyCodeForChar(e.getKeyChar()));
+ == ExtendedKeyCodes.getExtendedKeyCodeForChar(e.getKeyChar()));
}
@Override
public void keyReleased(KeyEvent e) {
eventsCount++;
setExtendedKeyCode = setExtendedKeyCode && (e.getExtendedKeyCode()
- == ExtendedKeyCodes.getExtendedKeyCodeForChar(e.getKeyChar()));
+ == ExtendedKeyCodes.getExtendedKeyCodeForChar(e.getKeyChar()));
}
});
@@ -77,5 +78,29 @@
if (eventsCount != 2 || !setExtendedKeyCode) {
throw new RuntimeException("Wrong extended key code");
}
+
+ frame = new Frame();
+ frame.setSize(300, 300);
+ setExtendedKeyCode = false;
+
+ frame.addKeyListener(new KeyAdapter() {
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ setExtendedKeyCode = e.getExtendedKeyCode() == KeyEvent.VK_LEFT;
+ }
+ });
+
+ frame.setVisible(true);
+ toolkit.realSync();
+
+ robot.keyPress(KeyEvent.VK_LEFT);
+ robot.keyRelease(KeyEvent.VK_LEFT);
+ toolkit.realSync();
+ frame.dispose();
+
+ if (!setExtendedKeyCode) {
+ throw new RuntimeException("Wrong extended key code!");
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/8028054/Task.java Wed Nov 27 10:44:41 2013 -0800
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+abstract class Task<T> implements Runnable {
+ private transient boolean working = true;
+ private final List<T> methods;
+ private final Thread thread;
+
+ Task(List<T> methods) {
+ this.methods = methods;
+ this.thread = new Thread(this);
+ this.thread.start();
+ }
+
+ boolean isAlive() {
+ return this.thread.isAlive();
+ }
+
+ boolean isWorking() {
+ boolean working = this.working && this.thread.isAlive();
+ this.working = false;
+ return working;
+ }
+
+ @Override
+ public void run() {
+ long time = -System.currentTimeMillis();
+ for (T method : this.methods) {
+ this.working = true;
+ try {
+ for (int i = 0; i < 100; i++) {
+ process(method);
+ }
+ } catch (NoSuchMethodException ignore) {
+ }
+ }
+ time += System.currentTimeMillis();
+ print("thread done in " + time / 1000 + " seconds");
+ }
+
+ protected abstract void process(T method) throws NoSuchMethodException;
+
+ static synchronized void print(Object message) {
+ System.out.println(message);
+ System.out.flush();
+ }
+
+ static List<Class<?>> getClasses(int count) throws Exception {
+ String resource = ClassLoader.getSystemClassLoader().getResource("java/lang/Object.class").toString();
+
+ Pattern pattern = Pattern.compile("jar:file:(.*)!.*");
+ Matcher matcher = pattern.matcher(resource);
+ matcher.matches();
+ resource = matcher.group(1);
+
+ List<Class<?>> classes = new ArrayList<>();
+ try (JarFile jarFile = new JarFile(resource)) {
+ Enumeration<JarEntry> entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ String name = entries.nextElement().getName();
+ if (name.startsWith("java") && name.endsWith(".class")) {
+ classes.add(Class.forName(name.substring(0, name.indexOf(".")).replace('/', '.')));
+ if (count == classes.size()) {
+ break;
+ }
+ }
+ }
+ }
+ return classes;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/8028054/TestConstructorFinder.java Wed Nov 27 10:44:41 2013 -0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import com.sun.beans.finder.ConstructorFinder;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8028054
+ * @summary Tests that cached constructors have synchronized access
+ * @author Sergey Malenkov
+ * @compile -XDignore.symbol.file TestConstructorFinder.java
+ * @run main TestConstructorFinder
+ */
+
+public class TestConstructorFinder {
+ public static void main(String[] args) throws Exception {
+ List<Class<?>> classes = Task.getClasses(Integer.MAX_VALUE);
+ List<Constructor> constructors = new ArrayList<>();
+ for (Class<?> type : classes) {
+ Collections.addAll(constructors, type.getConstructors());
+ }
+ Task.print("found " + constructors.size() + " constructors in " + classes.size() + " classes");
+
+ List<Task> tasks = new ArrayList<>();
+ for (int i = 0; i < 50; i++) {
+ tasks.add(new Task<Constructor>(constructors) {
+ @Override
+ protected void process(Constructor constructor) throws NoSuchMethodException {
+ ConstructorFinder.findConstructor(constructor.getDeclaringClass(), constructor.getParameterTypes());
+ }
+ });
+ }
+ int alarm = 0;
+ while (true) {
+ int alive = 0;
+ int working = 0;
+ for (Task task : tasks) {
+ if (task.isWorking()) {
+ working++;
+ alive++;
+ } else if (task.isAlive()) {
+ alive++;
+ }
+ }
+ if (alive == 0) {
+ break;
+ }
+ Task.print(working + " out of " + alive + " threads are working");
+ if ((working == 0) && (++alarm == 10)) {
+ Task.print("DEADLOCK DETECTED");
+ System.exit(100);
+ }
+ Thread.sleep(1000);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLDecoder/8028054/TestMethodFinder.java Wed Nov 27 10:44:41 2013 -0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import com.sun.beans.finder.MethodFinder;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8028054
+ * @summary Tests that cached methods have synchronized access
+ * @author Sergey Malenkov
+ * @compile -XDignore.symbol.file TestMethodFinder.java
+ * @run main TestMethodFinder
+ */
+
+public class TestMethodFinder {
+ public static void main(String[] args) throws Exception {
+ List<Class<?>> classes = Task.getClasses(4000);
+ List<Method> methods = new ArrayList<>();
+ for (Class<?> type : classes) {
+ Collections.addAll(methods, type.getMethods());
+ }
+ Task.print("found " + methods.size() + " methods in " + classes.size() + " classes");
+
+ List<Task> tasks = new ArrayList<>();
+ for (int i = 0; i < 50; i++) {
+ tasks.add(new Task<Method>(methods) {
+ @Override
+ protected void process(Method method) throws NoSuchMethodException {
+ MethodFinder.findMethod(method.getDeclaringClass(), method.getName(), method.getParameterTypes());
+ }
+ });
+ }
+ int alarm = 0;
+ while (true) {
+ int alive = 0;
+ int working = 0;
+ for (Task task : tasks) {
+ if (task.isWorking()) {
+ working++;
+ alive++;
+ } else if (task.isAlive()) {
+ alive++;
+ }
+ }
+ if (alive == 0) {
+ break;
+ }
+ Task.print(working + " out of " + alive + " threads are working");
+ if ((working == 0) && (++alarm == 10)) {
+ Task.print("DEADLOCK DETECTED");
+ System.exit(100);
+ }
+ Thread.sleep(1000);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFrame/8016356/bug8016356.java Wed Nov 27 10:44:41 2013 -0800
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013, 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 8016356
+ @summary Any swing frame resizes ugly.
+ @run main bug8016356
+ @author Oleg Pekhovskiy
+*/
+
+import java.awt.AWTException;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.event.InputEvent;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import sun.awt.OSInfo;
+
+public class bug8016356 {
+ private static JFrame frame;
+ private static Color color;
+ private static int scrTop;
+
+ private static Point frLoc;
+ private static Dimension frSize;
+
+ public static void main(String[] args) throws Exception {
+
+ // Windows only test
+ if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS) {
+
+ // Retrieving top edge of Desktop
+ GraphicsConfiguration grConf = GraphicsEnvironment
+ .getLocalGraphicsEnvironment().getDefaultScreenDevice()
+ .getDefaultConfiguration();
+ Rectangle scrRect = grConf.getBounds();
+ Insets scrInsets = Toolkit.getDefaultToolkit().getScreenInsets(grConf);
+ scrTop = scrRect.y + scrInsets.top;
+
+ color = new Color(0, 255, 0);
+
+ SwingUtilities.invokeAndWait(() -> {
+ createAndShowUI();
+ });
+
+ try {
+ Robot robot = new Robot();
+ robot.setAutoDelay(500);
+ robot.setAutoWaitForIdle(true);
+ robot.delay(1000);
+
+ // Resizing a window to invoke Windows Snap feature
+ readFrameInfo();
+ robot.mouseMove(frLoc.x + frSize.width / 2, frLoc.y);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseMove(frLoc.x + frSize.width / 2, scrTop);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+ // Retrieving the color of window expanded area
+ readFrameInfo();
+ Insets insets = frame.getInsets();
+ Color bgColor = robot.getPixelColor(frLoc.x + frSize.width / 2,
+ frLoc.y + frSize.height - insets.bottom - 1);
+
+ frame.dispose();
+
+ if (!bgColor.equals(color)) {
+ throw new RuntimeException("TEST FAILED: got "
+ + bgColor + " instead of " + color);
+ }
+ System.out.println("TEST PASSED!");
+ } catch (AWTException ex) {
+ throw new RuntimeException("TEST FAILED!");
+ }
+ }
+ }
+
+ private static void createAndShowUI() {
+ frame = new JFrame();
+ frame.setBounds(10, scrTop + 10, 300, 100);
+ JPanel panel = new JPanel();
+ panel.setBackground(color);
+ frame.getContentPane().add(panel);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setVisible(true);
+ }
+
+ private static void readFrameInfo() throws Exception {
+ SwingUtilities.invokeAndWait(() -> {
+ frLoc = frame.getLocationOnScreen();
+ frSize = frame.getSize();
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JPopupMenu/7160604/bug7160604.html Wed Nov 27 10:44:41 2013 -0800
@@ -0,0 +1,30 @@
+<!--
+ Copyright (c) 2013, 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.
+-->
+
+<html>
+<body>
+<applet code="bug7160604.class" width=400 height=100></applet>
+Click on the top-bar and combo-box more than once.
+Make sure popup menu and drop-down list have a border and their items are drawn properly.
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JPopupMenu/7160604/bug7160604.java Wed Nov 27 10:44:41 2013 -0800
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2013, 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 7160604
+ @summary Using non-opaque windows - popups are initially not painted correctly
+ @author Oleg Pekhovskiy
+ @run applet/manual=yesno bug7160604.html
+*/
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.JApplet;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JWindow;
+import javax.swing.SwingUtilities;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+public class bug7160604 extends JApplet {
+
+ public void init() {
+ SwingUtilities.invokeLater(() -> {
+ final JWindow window = new JWindow();
+ window.setLocation(200, 200);
+ window.setSize(300, 300);
+
+ final JLabel label = new JLabel("...click to invoke JPopupMenu");
+ label.setOpaque(true);
+ final JPanel contentPane = new JPanel(new BorderLayout());
+ contentPane.setBorder(BorderFactory.createLineBorder(Color.RED));
+ window.setContentPane(contentPane);
+ contentPane.add(label, BorderLayout.NORTH);
+
+ final JComboBox comboBox = new JComboBox(new Object[]{"1", "2", "3", "4"});
+ contentPane.add(comboBox, BorderLayout.SOUTH);
+
+ final JPopupMenu jPopupMenu = new JPopupMenu();
+
+ jPopupMenu.add("string");
+ jPopupMenu.add(new AbstractAction("action") {
+ @Override
+ public void actionPerformed(final ActionEvent e) {
+ }
+ });
+ jPopupMenu.add(new JLabel("label"));
+ jPopupMenu.add(new JMenuItem("MenuItem"));
+ label.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseReleased(final MouseEvent e) {
+ jPopupMenu.show(label, 0, 0);
+ }
+ });
+
+ window.setBackground(new Color(0, 0, 0, 0));
+
+ window.setVisible(true);
+ });
+ }
+}
--- a/jdk/test/javax/swing/plaf/windows/WindowsRootPaneUI/WrongAltProcessing/WrongAltProcessing.java Wed Nov 27 10:42:42 2013 -0800
+++ b/jdk/test/javax/swing/plaf/windows/WindowsRootPaneUI/WrongAltProcessing/WrongAltProcessing.java Wed Nov 27 10:44:41 2013 -0800
@@ -22,7 +22,7 @@
*/
/* @test
- @bug 8001633
+ @bug 8001633 8028271
@summary Wrong alt processing during switching between windows
@author mikhail.cherkasov@oracle.com
@run main WrongAltProcessing
@@ -44,16 +44,27 @@
private static JTextField mainFrameTf2;
private static JTextField secondFrameTf;
- public static void main(String[] args) throws AWTException {
+ public static void main(String[] args) throws Exception {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception e) {
return;// miss unsupported platforms.
}
- createWindows();
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ createWindows();
+ }
+ });
+ sync();
initRobot();
runScript();
- verify();
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ verify();
+ }
+ });
}
private static void verify() {
@@ -76,7 +87,7 @@
private static void clickWindowsTitle(JFrame frame) {
Point point = frame.getLocationOnScreen();
- robot.mouseMove(point.x + (frame.getWidth() / 2), point.y + 5);
+ robot.mouseMove(point.x + (frame.getWidth() / 2), point.y + frame.getInsets().top / 2);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
}
@@ -112,6 +123,7 @@
public static void createWindows() {
firstFrame = new JFrame("Frame");
firstFrame.setLayout(new FlowLayout());
+ firstFrame.setPreferredSize(new Dimension(600,100));
JMenuBar bar = new JMenuBar();
JMenu menu = new JMenu("File");
@@ -146,24 +158,16 @@
firstFrame.pack();
secondFrame = new JFrame("Frame 2");
+ secondFrame.setPreferredSize(new Dimension(600,100));
secondFrame.setLocation(0, 150);
secondFrameTf = new JTextField(20);
secondFrame.add(secondFrameTf);
secondFrame.pack();
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- secondFrame.setVisible(true);
- }
- });
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- firstFrame.setVisible(true);
- }
- });
+
+ secondFrame.setVisible(true);
+
+ firstFrame.setVisible(true);
mainFrameTf1.requestFocus();
- sync();
}
}