This commit is contained in:
Lana Steuck 2013-05-01 11:27:12 -07:00
commit d467408daf
33 changed files with 875 additions and 308 deletions

View File

@ -35,10 +35,18 @@ import java.util.Objects;
import sun.java2d.opengl.CGLGraphicsConfig;
public final class CGraphicsDevice extends GraphicsDevice {
public final class CGraphicsDevice extends GraphicsDevice
implements DisplayChangedListener {
// CoreGraphics display ID
private final int displayID;
/**
* CoreGraphics display ID. This identifier can become non-valid at any time
* therefore methods, which is using this id should be ready to it.
*/
private volatile int displayID;
private volatile Insets screenInsets;
private volatile double xResolution;
private volatile double yResolution;
private volatile int scale;
// Array of all GraphicsConfig instances for this device
private final GraphicsConfiguration[] configs;
@ -51,7 +59,7 @@ public final class CGraphicsDevice extends GraphicsDevice {
// Save/restore DisplayMode for the Full Screen mode
private DisplayMode originalMode;
public CGraphicsDevice(int displayID) {
public CGraphicsDevice(final int displayID) {
this.displayID = displayID;
configs = new GraphicsConfiguration[] {
CGLGraphicsConfig.getConfig(this, 0)
@ -89,7 +97,7 @@ public final class CGraphicsDevice extends GraphicsDevice {
*/
@Override
public String getIDstring() {
return "Display " + this.displayID;
return "Display " + displayID;
}
/**
@ -104,15 +112,37 @@ public final class CGraphicsDevice extends GraphicsDevice {
}
public double getXResolution() {
return nativeGetXResolution(displayID);
return xResolution;
}
public double getYResolution() {
return nativeGetYResolution(displayID);
return yResolution;
}
public Insets getScreenInsets() {
return nativeGetScreenInsets(displayID);
return screenInsets;
}
public int getScaleFactor() {
return scale;
}
public void invalidate(final int defaultDisplayID) {
displayID = defaultDisplayID;
}
@Override
public void displayChanged() {
xResolution = nativeGetXResolution(displayID);
yResolution = nativeGetYResolution(displayID);
screenInsets = nativeGetScreenInsets(displayID);
scale = (int) nativeGetScaleFactor(displayID);
//TODO configs/fullscreenWindow/modes?
}
@Override
public void paletteChanged() {
// devices do not need to react to this event.
}
/**
@ -219,10 +249,6 @@ public final class CGraphicsDevice extends GraphicsDevice {
return nativeGetDisplayModes(displayID);
}
public int getScaleFactor() {
return (int) nativeGetScaleFactor(displayID);
}
private static native double nativeGetScaleFactor(int displayID);
private static native void nativeSetDisplayMode(int displayID, int w, int h, int bpp, int refrate);

View File

@ -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
@ -26,19 +26,20 @@
package sun.awt;
import java.awt.*;
import java.awt.print.*;
import java.util.*;
import sun.java2d.*;
/**
* This is an implementation of a GraphicsEnvironment object for the default local GraphicsEnvironment used by the Java
* Runtime Environment for Mac OS X GUI environments.
* This is an implementation of a GraphicsEnvironment object for the default
* local GraphicsEnvironment used by the Java Runtime Environment for Mac OS X
* GUI environments.
*
* @see GraphicsDevice
* @see GraphicsConfiguration
*/
public class CGraphicsEnvironment extends SunGraphicsEnvironment {
public final class CGraphicsEnvironment extends SunGraphicsEnvironment {
// Global initialization of the Cocoa runtime.
private static native void initCocoa();
@ -53,7 +54,8 @@ public class CGraphicsEnvironment extends SunGraphicsEnvironment {
private static native int getMainDisplayID();
/**
* Noop function that just acts as an entry point for someone to force a static initialization of this class.
* Noop function that just acts as an entry point for someone to force a
* static initialization of this class.
*/
public static void init() { }
@ -78,8 +80,9 @@ public class CGraphicsEnvironment extends SunGraphicsEnvironment {
}
/**
* Register the instance with CGDisplayRegisterReconfigurationCallback()
* The registration uses a weak global reference -- if our instance is garbage collected, the reference will be dropped.
* Register the instance with CGDisplayRegisterReconfigurationCallback().
* The registration uses a weak global reference -- if our instance is
* garbage collected, the reference will be dropped.
*
* @return Return the registration context (a pointer).
*/
@ -91,7 +94,7 @@ public class CGraphicsEnvironment extends SunGraphicsEnvironment {
private native void deregisterDisplayReconfiguration(long context);
/** Available CoreGraphics displays. */
private final Map<Integer, CGraphicsDevice> devices = new HashMap<Integer, CGraphicsDevice>();
private final Map<Integer, CGraphicsDevice> devices = new HashMap<>(5);
/** Reference to the display reconfiguration callback context. */
private final long displayReconfigContext;
@ -118,11 +121,18 @@ public class CGraphicsEnvironment extends SunGraphicsEnvironment {
/**
* Called by the CoreGraphics Display Reconfiguration Callback.
*
* @param displayId
* CoreGraphics displayId
* @param displayId CoreGraphics displayId
* @param removed true if displayId was removed, false otherwise.
*/
void _displayReconfiguration(long displayId) {
displayChanged();
void _displayReconfiguration(final int displayId, final boolean removed) {
synchronized (this) {
if (removed && devices.containsKey(displayId)) {
final CGraphicsDevice gd = devices.remove(displayId);
gd.invalidate(getMainDisplayID());
gd.displayChanged();
}
}
initDevices();
}
@Override
@ -135,31 +145,30 @@ public class CGraphicsEnvironment extends SunGraphicsEnvironment {
}
/**
* (Re)create all CGraphicsDevices
*
* @return
* (Re)create all CGraphicsDevices, reuses a devices if it is possible.
*/
private synchronized void initDevices() {
devices.clear();
private void initDevices() {
synchronized (this) {
final Map<Integer, CGraphicsDevice> old = new HashMap<>(devices);
devices.clear();
int mainID = getMainDisplayID();
int mainID = getMainDisplayID();
// initialization of the graphics device may change
// list of displays on hybrid systems via an activation
// of discrete video.
// So, we initialize the main display first, and then
// retrieve actual list of displays.
CGraphicsDevice mainDevice = new CGraphicsDevice(mainID);
// initialization of the graphics device may change
// list of displays on hybrid systems via an activation
// of discrete video.
// So, we initialize the main display first, and then
// retrieve actual list of displays.
if (!old.containsKey(mainID)) {
old.put(mainID, new CGraphicsDevice(mainID));
}
final int[] displayIDs = getDisplayIDs();
for (int displayID : displayIDs) {
if (displayID != mainID) {
devices.put(displayID, new CGraphicsDevice(displayID));
} else {
devices.put(mainID, mainDevice);
for (final int id : getDisplayIDs()) {
devices.put(id, old.containsKey(id) ? old.get(id)
: new CGraphicsDevice(id));
}
}
displayChanged();
}
@Override
@ -167,7 +176,7 @@ public class CGraphicsEnvironment extends SunGraphicsEnvironment {
final int mainDisplayID = getMainDisplayID();
CGraphicsDevice d = devices.get(mainDisplayID);
if (d == null) {
// we do not exepct that this may happen, the only responce
// we do not expect that this may happen, the only response
// is to re-initialize the list of devices
initDevices();

View File

@ -87,18 +87,22 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
private final T target;
// Container peer. It may not be the peer of the target's direct
// parent, for example, in the case of hw/lw mixing. However,
// let's skip this scenario for the time being. We also assume
// the container peer is not null, which might also be false if
// addNotify() is called for a component outside of the hierarchy.
// The exception is LWWindowPeers: their parents are always null
private LWContainerPeer containerPeer;
/**
* Container peer. It may not be the peer of the target's direct parent, for
* example, in the case of hw/lw mixing. However, let's skip this scenario
* for the time being. We also assume the container peer is not null, which
* might also be false if addNotify() is called for a component outside of
* the hierarchy. The exception is LWWindowPeers: their containers are
* always null
*/
private final LWContainerPeer containerPeer;
// Handy reference to the top-level window peer. Window peer is
// borrowed from the containerPeer in constructor, and should also
// be updated when the component is reparented to another container
private LWWindowPeer windowPeer;
/**
* Handy reference to the top-level window peer. Window peer is borrowed
* from the containerPeer in constructor, and should also be updated when
* the component is reparented to another container
*/
private final LWWindowPeer windowPeer;
private final AtomicBoolean disposed = new AtomicBoolean(false);
@ -183,13 +187,13 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
this.target = target;
this.platformComponent = platformComponent;
initializeContainerPeer();
// Container peer is always null for LWWindowPeers, so
// windowPeer is always null for them as well. On the other
// hand, LWWindowPeer shouldn't use windowPeer at all
if (containerPeer != null) {
windowPeer = containerPeer.getWindowPeerOrSelf();
}
final Container container = SunToolkit.getNativeContainer(target);
containerPeer = (LWContainerPeer) LWToolkit.targetToPeer(container);
windowPeer = containerPeer != null ? containerPeer.getWindowPeerOrSelf()
: null;
// don't bother about z-order here as updateZOrder()
// will be called from addNotify() later anyway
if (containerPeer != null) {
@ -356,15 +360,6 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
return containerPeer;
}
// Just a helper method
// Overridden in LWWindowPeer to skip containerPeer initialization
protected void initializeContainerPeer() {
Container parent = LWToolkit.getNativeContainer(target);
if (parent != null) {
containerPeer = (LWContainerPeer) LWToolkit.targetToPeer(parent);
}
}
public PlatformWindow getPlatformWindow() {
LWWindowPeer windowPeer = getWindowPeer();
return windowPeer.getPlatformWindow();

View File

@ -41,7 +41,7 @@ import sun.util.logging.PlatformLogger;
public class LWWindowPeer
extends LWContainerPeer<Window, JComponent>
implements WindowPeer, FramePeer, DialogPeer, FullScreenCapable
implements FramePeer, DialogPeer, FullScreenCapable, DisplayChangedListener
{
public static enum PeerType {
SIMPLEWINDOW,
@ -189,6 +189,7 @@ public class LWWindowPeer
if (getSurfaceData() == null) {
replaceSurfaceData(false);
}
activateDisplayListener();
}
// Just a helper method
@ -201,15 +202,11 @@ public class LWWindowPeer
return this;
}
@Override
protected void initializeContainerPeer() {
// No-op as LWWindowPeer doesn't have any containerPeer
}
// ---- PEER METHODS ---- //
@Override
protected void disposeImpl() {
deactivateDisplayListener();
SurfaceData oldData = getSurfaceData();
synchronized (surfaceDataLock){
surfaceData = null;
@ -880,6 +877,18 @@ public class LWWindowPeer
// ---- UTILITY METHODS ---- //
private void activateDisplayListener() {
final GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
((SunGraphicsEnvironment) ge).addDisplayChangedListener(this);
}
private void deactivateDisplayListener() {
final GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
((SunGraphicsEnvironment) ge).removeDisplayChangedListener(this);
}
private void postWindowStateChangedEvent(int newWindowState) {
if (getTarget() instanceof Frame) {
AWTAccessor.getFrameAccessor().setExtendedState(
@ -941,7 +950,6 @@ public class LWWindowPeer
graphicsDevice = newGraphicsDevice;
}
// TODO: DisplayChangedListener stuff
final GraphicsConfiguration newGC = newGraphicsDevice.getDefaultConfiguration();
if (!setGraphicsConfig(newGC)) return false;
@ -954,6 +962,20 @@ public class LWWindowPeer
return true;
}
@Override
public final void displayChanged() {
updateGraphicsDevice();
// Replace surface unconditionally, because internal state of the
// GraphicsDevice could be changed.
replaceSurfaceData();
repaintPeer();
}
@Override
public final void paletteChanged() {
// components do not need to react to this event.
}
/*
* May be called by delegate to provide SD to Java2D code.
*/

View File

@ -32,6 +32,7 @@ import java.awt.peer.WindowPeer;
import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Objects;
import javax.swing.*;
@ -916,9 +917,12 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
final Rectangle oldB = nativeBounds;
nativeBounds = new Rectangle(x, y, width, height);
final GraphicsConfiguration oldGC = peer.getGraphicsConfiguration();
peer.notifyReshape(x, y, width, height);
final GraphicsConfiguration newGC = peer.getGraphicsConfiguration();
// System-dependent appearance optimization.
if ((byUser && !oldB.getSize().equals(nativeBounds.getSize()))
|| isFullScreenAnimationOn) {
|| isFullScreenAnimationOn || !Objects.equals(newGC, oldGC)) {
flushBuffers();
}
}

View File

@ -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
@ -35,5 +35,6 @@ void SendAdditionalJavaEvents(JNIEnv *env, NSEvent *nsEvent, jobject peer);
jint GetJavaMouseModifiers(NSInteger button, NSUInteger modifierFlags);
jint NsKeyModifiersToJavaModifiers(NSUInteger nsFlags, BOOL isExtMods);
NSUInteger JavaModifiersToNsKeyModifiers(jint javaModifiers, BOOL isExtMods);
unichar NsCharToJavaChar(unichar nsChar, NSUInteger modifiers);
#endif /* __AWTEVENT_H */

View File

@ -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
@ -341,8 +341,7 @@ const charTable[] = {
{0, 0, 0}
};
static unichar
NsCharToJavaChar(unichar nsChar, NSUInteger modifiers)
unichar NsCharToJavaChar(unichar nsChar, NSUInteger modifiers)
{
const struct _char *cur;
// Mask off just the keyboard modifiers from the event modifier mask.

View File

@ -124,10 +124,11 @@ static void displaycb_handle
jobject graphicsEnv = [wrapper jObjectWithEnv:env];
if (graphicsEnv == NULL) return; // ref already GC'd
static JNF_CLASS_CACHE(jc_CGraphicsEnvironment, "sun/awt/CGraphicsEnvironment");
static JNF_MEMBER_CACHE(jm_displayReconfiguration, jc_CGraphicsEnvironment, "_displayReconfiguration", "(J)V");
JNFCallVoidMethod(env, graphicsEnv, jm_displayReconfiguration);
static JNF_MEMBER_CACHE(jm_displayReconfiguration, jc_CGraphicsEnvironment, "_displayReconfiguration", "(IZ)V");
JNFCallVoidMethod(env, graphicsEnv, jm_displayReconfiguration,
(jint) display,
(jboolean) flags & kCGDisplayRemoveFlag);
});
}

View File

@ -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
@ -71,12 +71,21 @@ AWT_ASSERT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
// If we are called as a result of user pressing a shorcut, do nothing,
// because AVTView has already sent corresponding key event to the Java
// because AVTView has already sent corresponding key event to the Java
// layer from performKeyEquivalent
NSEvent *currEvent = [[NSApplication sharedApplication] currentEvent];
if ([currEvent type] == NSKeyDown) {
NSString *menuKey = [sender keyEquivalent];
NSString *eventKey = [currEvent charactersIgnoringModifiers];
// Apple uses characters from private Unicode range for some of the
// keys, so we need to do the same translation here that we do
// for the regular key down events
if ([eventKey length] == 1) {
unichar ch = NsCharToJavaChar([eventKey characterAtIndex:0], 0);
eventKey = [NSString stringWithCharacters: &ch length: 1];
}
if ([menuKey isEqualToString:eventKey]) {
return;
}

View File

@ -316,7 +316,10 @@ AWT_ASSERT_APPKIT_THREAD;
// its finishLaunching has initialized it.
// ApplicationDelegate is the support code for com.apple.eawt.
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
OSXAPP_SetApplicationDelegate([ApplicationDelegate sharedDelegate]);
id<NSApplicationDelegate> delegate = [ApplicationDelegate sharedDelegate];
if (delegate != nil) {
OSXAPP_SetApplicationDelegate(delegate);
}
}];
}

View File

@ -216,7 +216,11 @@ Java_sun_java2d_opengl_CGLLayer_nativeSetScale
{
JNF_COCOA_ENTER(env);
CGLLayer *layer = jlong_to_ptr(layerPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
// We always call all setXX methods asynchronously, exception is only in
// this method where we need to change native texture size and layer's scale
// in one call on appkit, otherwise we'll get window's contents blinking,
// during screen-2-screen moving.
[ThreadUtilities performOnMainThreadWaiting:[NSThread isMainThread] block:^(){
layer.contentsScale = scale;
}];
JNF_COCOA_EXIT(env);

View File

@ -1051,11 +1051,11 @@ public abstract class Component implements ImageObserver, MenuContainer,
return parent;
}
// This method is overriden in the Window class to return null,
// This method is overridden in the Window class to return null,
// because the parent field of the Window object contains
// the owner of the window, not its parent.
Container getContainer() {
return getParent();
return getParent_NoClientCode();
}
/**
@ -8194,10 +8194,10 @@ public abstract class Component implements ImageObserver, MenuContainer,
* Fetches the native container somewhere higher up in the component
* tree that contains this component.
*/
Container getNativeContainer() {
Container p = parent;
final Container getNativeContainer() {
Container p = getContainer();
while (p != null && p.peer instanceof LightweightPeer) {
p = p.getParent_NoClientCode();
p = p.getContainer();
}
return p;
}

View File

@ -3914,7 +3914,7 @@ public class Window extends Container implements Accessible {
// ************************** MIXING CODE *******************************
// A window has a parent, but it does NOT have a container
// A window has an owner, but it does NOT have a container
@Override
final Container getContainer() {
return null;

View File

@ -69,8 +69,9 @@ import java.util.Objects;
* @author Philip Milne
* @author Steve Langley
*/
class MetaData {
class NullPersistenceDelegate extends PersistenceDelegate {
static final class NullPersistenceDelegate extends PersistenceDelegate {
// Note this will be called by all classes when they reach the
// top of their superclass chain.
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
@ -87,7 +88,7 @@ class NullPersistenceDelegate extends PersistenceDelegate {
*
* @author Sergey A. Malenkov
*/
class EnumPersistenceDelegate extends PersistenceDelegate {
static final class EnumPersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return oldInstance == newInstance;
}
@ -98,7 +99,7 @@ class EnumPersistenceDelegate extends PersistenceDelegate {
}
}
class PrimitivePersistenceDelegate extends PersistenceDelegate {
static final class PrimitivePersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return oldInstance.equals(newInstance);
}
@ -109,7 +110,7 @@ class PrimitivePersistenceDelegate extends PersistenceDelegate {
}
}
class ArrayPersistenceDelegate extends PersistenceDelegate {
static final class ArrayPersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return (newInstance != null &&
oldInstance.getClass() == newInstance.getClass() && // Also ensures the subtype is correct.
@ -150,7 +151,7 @@ class ArrayPersistenceDelegate extends PersistenceDelegate {
}
}
class ProxyPersistenceDelegate extends PersistenceDelegate {
static final class ProxyPersistenceDelegate extends PersistenceDelegate {
protected Expression instantiate(Object oldInstance, Encoder out) {
Class<?> type = oldInstance.getClass();
java.lang.reflect.Proxy p = (java.lang.reflect.Proxy)oldInstance;
@ -185,7 +186,7 @@ class ProxyPersistenceDelegate extends PersistenceDelegate {
}
// Strings
class java_lang_String_PersistenceDelegate extends PersistenceDelegate {
static final class java_lang_String_PersistenceDelegate extends PersistenceDelegate {
protected Expression instantiate(Object oldInstance, Encoder out) { return null; }
public void writeObject(Object oldInstance, Encoder out) {
@ -194,7 +195,7 @@ class java_lang_String_PersistenceDelegate extends PersistenceDelegate {
}
// Classes
class java_lang_Class_PersistenceDelegate extends PersistenceDelegate {
static final class java_lang_Class_PersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return oldInstance.equals(newInstance);
}
@ -228,7 +229,7 @@ class java_lang_Class_PersistenceDelegate extends PersistenceDelegate {
}
// Fields
class java_lang_reflect_Field_PersistenceDelegate extends PersistenceDelegate {
static final class java_lang_reflect_Field_PersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return oldInstance.equals(newInstance);
}
@ -243,7 +244,7 @@ class java_lang_reflect_Field_PersistenceDelegate extends PersistenceDelegate {
}
// Methods
class java_lang_reflect_Method_PersistenceDelegate extends PersistenceDelegate {
static final class java_lang_reflect_Method_PersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return oldInstance.equals(newInstance);
}
@ -267,7 +268,7 @@ class java_lang_reflect_Method_PersistenceDelegate extends PersistenceDelegate {
*
* @author Sergey A. Malenkov
*/
class java_util_Date_PersistenceDelegate extends PersistenceDelegate {
static class java_util_Date_PersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
if (!super.mutatesTo(oldInstance, newInstance)) {
return false;
@ -290,7 +291,7 @@ class java_util_Date_PersistenceDelegate extends PersistenceDelegate {
*
* @author Sergey A. Malenkov
*/
final class java_sql_Timestamp_PersistenceDelegate extends java_util_Date_PersistenceDelegate {
static final class java_sql_Timestamp_PersistenceDelegate extends java_util_Date_PersistenceDelegate {
private static final Method getNanosMethod = getNanosMethod();
private static Method getNanosMethod() {
@ -354,7 +355,7 @@ delegates to be registered with concrete classes.
*
* @author Sergey A. Malenkov
*/
abstract class java_util_Collections extends PersistenceDelegate {
private static abstract class java_util_Collections extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
if (!super.mutatesTo(oldInstance, newInstance)) {
return false;
@ -367,6 +368,10 @@ abstract class java_util_Collections extends PersistenceDelegate {
return (oldC.size() == newC.size()) && oldC.containsAll(newC);
}
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
// do not initialize these custom collections in default way
}
static final class EmptyList_PersistenceDelegate extends java_util_Collections {
protected Expression instantiate(Object oldInstance, Encoder out) {
return new Expression(oldInstance, Collections.class, "emptyList", null);
@ -569,7 +574,7 @@ abstract class java_util_Collections extends PersistenceDelegate {
*
* @author Sergey A. Malenkov
*/
class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate {
static final class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance));
}
@ -588,7 +593,7 @@ class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate {
*
* @author Sergey A. Malenkov
*/
class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate {
static final class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance));
}
@ -603,7 +608,7 @@ class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate {
}
// Collection
class java_util_Collection_PersistenceDelegate extends DefaultPersistenceDelegate {
static class java_util_Collection_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
java.util.Collection<?> oldO = (java.util.Collection)oldInstance;
java.util.Collection<?> newO = (java.util.Collection)newInstance;
@ -618,7 +623,7 @@ class java_util_Collection_PersistenceDelegate extends DefaultPersistenceDelegat
}
// List
class java_util_List_PersistenceDelegate extends DefaultPersistenceDelegate {
static class java_util_List_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
java.util.List<?> oldO = (java.util.List<?>)oldInstance;
java.util.List<?> newO = (java.util.List<?>)newInstance;
@ -653,7 +658,7 @@ class java_util_List_PersistenceDelegate extends DefaultPersistenceDelegate {
// Map
class java_util_Map_PersistenceDelegate extends DefaultPersistenceDelegate {
static class java_util_Map_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
// System.out.println("Initializing: " + newInstance);
java.util.Map<?,?> oldMap = (java.util.Map)oldInstance;
@ -691,14 +696,14 @@ class java_util_Map_PersistenceDelegate extends DefaultPersistenceDelegate {
}
}
class java_util_AbstractCollection_PersistenceDelegate extends java_util_Collection_PersistenceDelegate {}
class java_util_AbstractList_PersistenceDelegate extends java_util_List_PersistenceDelegate {}
class java_util_AbstractMap_PersistenceDelegate extends java_util_Map_PersistenceDelegate {}
class java_util_Hashtable_PersistenceDelegate extends java_util_Map_PersistenceDelegate {}
static final class java_util_AbstractCollection_PersistenceDelegate extends java_util_Collection_PersistenceDelegate {}
static final class java_util_AbstractList_PersistenceDelegate extends java_util_List_PersistenceDelegate {}
static final class java_util_AbstractMap_PersistenceDelegate extends java_util_Map_PersistenceDelegate {}
static final class java_util_Hashtable_PersistenceDelegate extends java_util_Map_PersistenceDelegate {}
// Beans
class java_beans_beancontext_BeanContextSupport_PersistenceDelegate extends java_util_Collection_PersistenceDelegate {}
static final class java_beans_beancontext_BeanContextSupport_PersistenceDelegate extends java_util_Collection_PersistenceDelegate {}
// AWT
@ -709,7 +714,7 @@ class java_beans_beancontext_BeanContextSupport_PersistenceDelegate extends java
*
* @author Sergey A. Malenkov
*/
final class java_awt_Insets_PersistenceDelegate extends PersistenceDelegate {
static final class java_awt_Insets_PersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return oldInstance.equals(newInstance);
}
@ -733,7 +738,7 @@ final class java_awt_Insets_PersistenceDelegate extends PersistenceDelegate {
*
* @author Sergey A. Malenkov
*/
final class java_awt_Font_PersistenceDelegate extends PersistenceDelegate {
static final class java_awt_Font_PersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return oldInstance.equals(newInstance);
}
@ -802,7 +807,7 @@ final class java_awt_Font_PersistenceDelegate extends PersistenceDelegate {
*
* @author Sergey A. Malenkov
*/
final class java_awt_AWTKeyStroke_PersistenceDelegate extends PersistenceDelegate {
static final class java_awt_AWTKeyStroke_PersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return oldInstance.equals(newInstance);
}
@ -843,7 +848,7 @@ final class java_awt_AWTKeyStroke_PersistenceDelegate extends PersistenceDelegat
}
}
class StaticFieldsPersistenceDelegate extends PersistenceDelegate {
static class StaticFieldsPersistenceDelegate extends PersistenceDelegate {
protected void installFields(Encoder out, Class<?> cls) {
Field fields[] = cls.getFields();
for(int i = 0; i < fields.length; i++) {
@ -870,13 +875,13 @@ class StaticFieldsPersistenceDelegate extends PersistenceDelegate {
}
// SystemColor
class java_awt_SystemColor_PersistenceDelegate extends StaticFieldsPersistenceDelegate {}
static final class java_awt_SystemColor_PersistenceDelegate extends StaticFieldsPersistenceDelegate {}
// TextAttribute
class java_awt_font_TextAttribute_PersistenceDelegate extends StaticFieldsPersistenceDelegate {}
static final class java_awt_font_TextAttribute_PersistenceDelegate extends StaticFieldsPersistenceDelegate {}
// MenuShortcut
class java_awt_MenuShortcut_PersistenceDelegate extends PersistenceDelegate {
static final class java_awt_MenuShortcut_PersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return oldInstance.equals(newInstance);
}
@ -889,7 +894,7 @@ class java_awt_MenuShortcut_PersistenceDelegate extends PersistenceDelegate {
}
// Component
class java_awt_Component_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class java_awt_Component_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
java.awt.Component c = (java.awt.Component)oldInstance;
@ -936,7 +941,7 @@ class java_awt_Component_PersistenceDelegate extends DefaultPersistenceDelegate
}
// Container
class java_awt_Container_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class java_awt_Container_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
// Ignore the children of a JScrollPane.
@ -971,7 +976,7 @@ class java_awt_Container_PersistenceDelegate extends DefaultPersistenceDelegate
}
// Choice
class java_awt_Choice_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class java_awt_Choice_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
java.awt.Choice m = (java.awt.Choice)oldInstance;
@ -983,7 +988,7 @@ class java_awt_Choice_PersistenceDelegate extends DefaultPersistenceDelegate {
}
// Menu
class java_awt_Menu_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class java_awt_Menu_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
java.awt.Menu m = (java.awt.Menu)oldInstance;
@ -995,7 +1000,7 @@ class java_awt_Menu_PersistenceDelegate extends DefaultPersistenceDelegate {
}
// MenuBar
class java_awt_MenuBar_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class java_awt_MenuBar_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
java.awt.MenuBar m = (java.awt.MenuBar)oldInstance;
@ -1007,7 +1012,7 @@ class java_awt_MenuBar_PersistenceDelegate extends DefaultPersistenceDelegate {
}
// List
class java_awt_List_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class java_awt_List_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
java.awt.List m = (java.awt.List)oldInstance;
@ -1022,7 +1027,7 @@ class java_awt_List_PersistenceDelegate extends DefaultPersistenceDelegate {
// LayoutManagers
// BorderLayout
class java_awt_BorderLayout_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class java_awt_BorderLayout_PersistenceDelegate extends DefaultPersistenceDelegate {
private static final String[] CONSTRAINTS = {
BorderLayout.NORTH,
BorderLayout.SOUTH,
@ -1053,41 +1058,44 @@ class java_awt_BorderLayout_PersistenceDelegate extends DefaultPersistenceDelega
}
// CardLayout
class java_awt_CardLayout_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class java_awt_CardLayout_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance,
Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
Hashtable<?,?> tab = (Hashtable<?,?>)ReflectionUtils.getPrivateField(oldInstance,
java.awt.CardLayout.class,
"tab",
out.getExceptionListener());
if (tab != null) {
for(Enumeration<?> e = tab.keys(); e.hasMoreElements();) {
Object child = e.nextElement();
invokeStatement(oldInstance, "addLayoutComponent",
new Object[]{child, (String)tab.get(child)}, out);
if (getVector(newInstance).isEmpty()) {
for (Object card : getVector(oldInstance)) {
Object[] args = {MetaData.getPrivateFieldValue(card, "java.awt.CardLayout$Card.name"),
MetaData.getPrivateFieldValue(card, "java.awt.CardLayout$Card.comp")};
invokeStatement(oldInstance, "addLayoutComponent", args, out);
}
}
}
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return super.mutatesTo(oldInstance, newInstance) && getVector(newInstance).isEmpty();
}
private static Vector<?> getVector(Object instance) {
return (Vector<?>) MetaData.getPrivateFieldValue(instance, "java.awt.CardLayout.vector");
}
}
// GridBagLayout
class java_awt_GridBagLayout_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class java_awt_GridBagLayout_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance,
Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
Hashtable<?,?> comptable = (Hashtable<?,?>)ReflectionUtils.getPrivateField(oldInstance,
java.awt.GridBagLayout.class,
"comptable",
out.getExceptionListener());
if (comptable != null) {
for(Enumeration<?> e = comptable.keys(); e.hasMoreElements();) {
Object child = e.nextElement();
invokeStatement(oldInstance, "addLayoutComponent",
new Object[]{child, comptable.get(child)}, out);
if (getHashtable(newInstance).isEmpty()) {
for (Map.Entry<?,?> entry : getHashtable(oldInstance).entrySet()) {
Object[] args = {entry.getKey(), entry.getValue()};
invokeStatement(oldInstance, "addLayoutComponent", args, out);
}
}
}
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return super.mutatesTo(oldInstance, newInstance) && getHashtable(newInstance).isEmpty();
}
private static Hashtable<?,?> getHashtable(Object instance) {
return (Hashtable<?,?>) MetaData.getPrivateFieldValue(instance, "java.awt.GridBagLayout.comptable");
}
}
// Swing
@ -1095,7 +1103,7 @@ class java_awt_GridBagLayout_PersistenceDelegate extends DefaultPersistenceDeleg
// JFrame (If we do this for Window instead of JFrame, the setVisible call
// will be issued before we have added all the children to the JFrame and
// will appear blank).
class javax_swing_JFrame_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class javax_swing_JFrame_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
java.awt.Window oldC = (java.awt.Window)oldInstance;
@ -1115,7 +1123,7 @@ class javax_swing_JFrame_PersistenceDelegate extends DefaultPersistenceDelegate
// Models
// DefaultListModel
class javax_swing_DefaultListModel_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class javax_swing_DefaultListModel_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
// Note, the "size" property will be set here.
super.initialize(type, oldInstance, newInstance, out);
@ -1129,7 +1137,7 @@ class javax_swing_DefaultListModel_PersistenceDelegate extends DefaultPersistenc
}
// DefaultComboBoxModel
class javax_swing_DefaultComboBoxModel_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class javax_swing_DefaultComboBoxModel_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
javax.swing.DefaultComboBoxModel<?> m = (javax.swing.DefaultComboBoxModel<?>)oldInstance;
@ -1141,7 +1149,7 @@ class javax_swing_DefaultComboBoxModel_PersistenceDelegate extends DefaultPersis
// DefaultMutableTreeNode
class javax_swing_tree_DefaultMutableTreeNode_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class javax_swing_tree_DefaultMutableTreeNode_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object
newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
@ -1157,7 +1165,7 @@ class javax_swing_tree_DefaultMutableTreeNode_PersistenceDelegate extends Defaul
}
// ToolTipManager
class javax_swing_ToolTipManager_PersistenceDelegate extends PersistenceDelegate {
static final class javax_swing_ToolTipManager_PersistenceDelegate extends PersistenceDelegate {
protected Expression instantiate(Object oldInstance, Encoder out) {
return new Expression(oldInstance, javax.swing.ToolTipManager.class,
"sharedInstance", new Object[]{});
@ -1165,7 +1173,7 @@ class javax_swing_ToolTipManager_PersistenceDelegate extends PersistenceDelegate
}
// JTabbedPane
class javax_swing_JTabbedPane_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class javax_swing_JTabbedPane_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
javax.swing.JTabbedPane p = (javax.swing.JTabbedPane)oldInstance;
@ -1180,7 +1188,7 @@ class javax_swing_JTabbedPane_PersistenceDelegate extends DefaultPersistenceDele
}
// Box
class javax_swing_Box_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class javax_swing_Box_PersistenceDelegate extends DefaultPersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return super.mutatesTo(oldInstance, newInstance) && getAxis(oldInstance).equals(getAxis(newInstance));
}
@ -1201,7 +1209,7 @@ class javax_swing_Box_PersistenceDelegate extends DefaultPersistenceDelegate {
// Container will return all of the sub menu items that
// need to be added to the menu item.
// Not so for JMenu apparently.
class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
javax.swing.JMenu m = (javax.swing.JMenu)oldInstance;
@ -1219,7 +1227,7 @@ class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate {
*
* @author Sergey A. Malenkov
*/
final class javax_swing_border_MatteBorder_PersistenceDelegate extends PersistenceDelegate {
static final class javax_swing_border_MatteBorder_PersistenceDelegate extends PersistenceDelegate {
protected Expression instantiate(Object oldInstance, Encoder out) {
MatteBorder border = (MatteBorder) oldInstance;
Insets insets = border.getBorderInsets();
@ -1239,7 +1247,7 @@ final class javax_swing_border_MatteBorder_PersistenceDelegate extends Persisten
}
/* XXX - doens't seem to work. Debug later.
class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate {
static final class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate {
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
javax.swing.JMenu m = (javax.swing.JMenu)oldInstance;
@ -1261,7 +1269,7 @@ class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate {
*
* @author Sergey A. Malenkov
*/
final class sun_swing_PrintColorUIResource_PersistenceDelegate extends PersistenceDelegate {
static final class sun_swing_PrintColorUIResource_PersistenceDelegate extends PersistenceDelegate {
protected boolean mutatesTo(Object oldInstance, Object newInstance) {
return oldInstance.equals(newInstance);
}
@ -1273,7 +1281,6 @@ final class sun_swing_PrintColorUIResource_PersistenceDelegate extends Persisten
}
}
class MetaData {
private static final Map<String,Field> fields = Collections.synchronizedMap(new WeakHashMap<String, Field>());
private static Hashtable<String, PersistenceDelegate> internalPersistenceDelegates = new Hashtable<>();
@ -1316,7 +1323,7 @@ class MetaData {
if (Enum.class.isAssignableFrom(type)) {
return enumPersistenceDelegate;
}
if (ReflectionUtils.isPrimitive(type)) {
if (null != XMLEncoder.primitiveTypeFor(type)) {
return primitivePersistenceDelegate;
}
// The persistence delegate for arrays is non-trivial; instantiate it lazily.
@ -1350,7 +1357,7 @@ class MetaData {
internalPersistenceDelegates.put(typeName, defaultPersistenceDelegate);
try {
String name = type.getName();
Class c = Class.forName("java.beans." + name.replace('.', '_')
Class c = Class.forName("java.beans.MetaData$" + name.replace('.', '_')
+ "_PersistenceDelegate");
pd = (PersistenceDelegate)c.newInstance();
internalPersistenceDelegates.put(typeName, pd);

View File

@ -1,78 +0,0 @@
/*
* Copyright (c) 2003, 2009, 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 java.beans;
import java.lang.reflect.Field;
/**
* A utility class for reflectively finding methods, constuctors and fields
* using reflection.
*/
class ReflectionUtils {
@SuppressWarnings("rawtypes")
public static boolean isPrimitive(Class type) {
return primitiveTypeFor(type) != null;
}
@SuppressWarnings("rawtypes")
public static Class primitiveTypeFor(Class wrapper) {
if (wrapper == Boolean.class) return Boolean.TYPE;
if (wrapper == Byte.class) return Byte.TYPE;
if (wrapper == Character.class) return Character.TYPE;
if (wrapper == Short.class) return Short.TYPE;
if (wrapper == Integer.class) return Integer.TYPE;
if (wrapper == Long.class) return Long.TYPE;
if (wrapper == Float.class) return Float.TYPE;
if (wrapper == Double.class) return Double.TYPE;
if (wrapper == Void.class) return Void.TYPE;
return null;
}
/**
* Returns the value of a private field.
*
* @param instance object instance
* @param cls class
* @param name name of the field
* @param el an exception listener to handle exceptions; or null
* @return value of the field; null if not found or an error is encountered
*/
@SuppressWarnings("rawtypes")
public static Object getPrivateField(Object instance, Class cls,
String name, ExceptionListener el) {
try {
Field f = cls.getDeclaredField(name);
f.setAccessible(true);
return f.get(instance);
}
catch (Exception e) {
if (el != null) {
el.exceptionThrown(e);
}
}
return null;
}
}

View File

@ -604,7 +604,7 @@ public class XMLEncoder extends Encoder implements AutoCloseable {
return;
}
Class<?> primitiveType = ReflectionUtils.primitiveTypeFor(value.getClass());
Class<?> primitiveType = primitiveTypeFor(value.getClass());
if (primitiveType != null && target == value.getClass() &&
methodName.equals("new")) {
String primitiveTypeName = primitiveType.getName();
@ -778,4 +778,18 @@ public class XMLEncoder extends Encoder implements AutoCloseable {
indentation--;
writeln("</" + tag + ">");
}
@SuppressWarnings("rawtypes")
static Class primitiveTypeFor(Class wrapper) {
if (wrapper == Boolean.class) return Boolean.TYPE;
if (wrapper == Byte.class) return Byte.TYPE;
if (wrapper == Character.class) return Character.TYPE;
if (wrapper == Short.class) return Short.TYPE;
if (wrapper == Integer.class) return Integer.TYPE;
if (wrapper == Long.class) return Long.TYPE;
if (wrapper == Float.class) return Float.TYPE;
if (wrapper == Double.class) return Double.TYPE;
if (wrapper == Void.class) return Void.TYPE;
return null;
}
}

View File

@ -427,6 +427,15 @@ public class JDesktopPane extends JLayeredPane implements Accessible
}
}
/**
* {@inheritDoc}
*/
@Override
public void remove(Component comp) {
super.remove(comp);
updateFramesCache();
}
/**
* Selects the next <code>JInternalFrame</code> in this desktop pane.
*

View File

@ -1887,7 +1887,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
switch (getWindowType())
{
case NORMAL:
typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_NORMAL;
typeAtom = (ownerPeer == null) ?
protocol.XA_NET_WM_WINDOW_TYPE_NORMAL :
protocol.XA_NET_WM_WINDOW_TYPE_DIALOG;
break;
case UTILITY:
typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_UTILITY;

View File

@ -759,9 +759,7 @@ public abstract class WComponentPeer extends WObjectPeer
WComponentPeer(Component target) {
this.target = target;
this.paintArea = new RepaintArea();
Container parent = WToolkit.getNativeContainer(target);
WComponentPeer parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent);
create(parentPeer);
create(getNativeParent());
// fix for 5088782: check if window object is created successfully
checkCreation();
@ -771,6 +769,17 @@ public abstract class WComponentPeer extends WObjectPeer
}
abstract void create(WComponentPeer parent);
/**
* Gets the native parent of this peer. We use the term "parent" explicitly,
* because we override the method in top-level window peer implementations.
*
* @return the parent container/owner of this peer.
*/
WComponentPeer getNativeParent() {
Container parent = SunToolkit.getNativeContainer((Component) target);
return (WComponentPeer) WToolkit.targetToPeer(parent);
}
protected void checkCreation()
{
if ((hwnd == 0) || (pData == 0))

View File

@ -215,6 +215,12 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
createAwtWindow(parent);
}
@Override
final WComponentPeer getNativeParent() {
final Container owner = ((Window) target).getOwner();
return (WComponentPeer) WToolkit.targetToPeer(owner);
}
// should be overriden in WDialogPeer
protected void realShow() {
super.show();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 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,7 +28,7 @@
* @author anton.tarasov@sun.com: area=awt.focus
* @library ../../regtesthelpers
* @build Util
* @run main OverrideRedirectWindowActivationTest
* @run main SimpleWindowActivationTest
*/
import java.awt.*;
import java.awt.event.*;
@ -37,7 +37,7 @@ import javax.swing.SwingUtilities;
import sun.awt.SunToolkit;
import test.java.awt.regtesthelpers.Util;
public class OverrideRedirectWindowActivationTest {
public class SimpleWindowActivationTest {
private static Frame frame;
private static Window window;
@ -115,7 +115,7 @@ public class OverrideRedirectWindowActivationTest {
wbutton = new Button("wbutton");
label = new Label("label");
window.setBounds(800, 200, 200, 100);
window.setBounds(800, 200, 300, 100);
window.setLayout(new FlowLayout());
window.add(wbutton);
window.add(label);
@ -126,7 +126,7 @@ public class OverrideRedirectWindowActivationTest {
private static void createAndShowFrame() {
fbutton = new Button("fbutton");
frame.setBounds(800, 0, 200, 100);
frame.setBounds(800, 0, 300, 100);
frame.setLayout(new FlowLayout());
frame.add(fbutton);
frame.setVisible(true);

View File

@ -1,4 +1,4 @@
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012, 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
@ -22,7 +22,8 @@
${TESTJAVA}/bin/javac -cp ${TESTSRC} -d . ${TESTSRC}/BadDisplayTest.java
export DISPLAY=
DISPLAY=
export DISPLAY
OS=`uname -s`
case "$OS" in

View File

@ -0,0 +1,144 @@
/*
* 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 8012586
* @summary verify that modal dialog will appeared above fullscreen window under Metacity WM.
* @run main FullscreenDialogModality
* @run main/othervm FullscreenDialogModality
* @author vkravets
*/
import test.java.awt.regtesthelpers.Util;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
public class FullscreenDialogModality extends Frame {
static Robot robot = null;
public void enterFS() {
GraphicsDevice gd = getGraphicsConfiguration().getDevice();
final boolean fs = gd.isFullScreenSupported();
System.out.println("FullscreenSupported: " + (fs ? "yes" : "no"));
gd.setFullScreenWindow(this);
try {
// Give the system time to set the FS window and display it
// properly
Thread.sleep(2000);
} catch (Exception e) {}
}
public void exitFS() {
GraphicsDevice gd = getGraphicsConfiguration().getDevice();
// reset window
gd.setFullScreenWindow(null);
try {
// Give the system time to set the FS window and display it
// properly
Thread.sleep(2000);
} catch (Exception e) {}
}
public void checkDialogModality() throws InvocationTargetException, InterruptedException {
// Dialog
final Dialog d = new Dialog(FullscreenDialogModality.this, "Modal dialog", Dialog.ModalityType.APPLICATION_MODAL);
d.setBounds(500, 500, 160, 160);
d.setModal(true);
d.setBackground(Color.red);
EventQueue.invokeLater(new Runnable()
{
public void run()
{
d.setVisible(true);
}
});
// Wait until the dialog is shown
EventQueue.invokeLater(new Runnable() {
public void run() {
// Empty
}
});
Util.waitForIdle(robot);
try {
//Check color
Point checkPoint = new Point(d.getX() + d.getWidth() / 2, d.getY() + d.getHeight() / 2);
Color actual = robot.getPixelColor(checkPoint.x, checkPoint.y);
System.out.println("Color = " + actual);
if (actual.getRGB() == Color.GREEN.getRGB()) {
throw new RuntimeException("Test FAILED: Modal dialog shown below fullscreen window");
} else if (actual.getRGB() == Color.RED.getRGB()) {
System.out.println("Test PASSED: Modal dialog shown above fullscreen window");
} else {
System.out.println("pixelColor " +
Integer.toHexString(actual.getRGB()) +
" at coordinates (" + checkPoint.x + ", " + checkPoint.y + ")");
throw new RuntimeException("Test FAILED: Unexpected behavior");
}
robot.delay(2000);
Util.waitForIdle(robot);
} finally {
d.dispose();
}
}
public static void main(String args[]) throws InvocationTargetException, InterruptedException {
if (Util.getWMID() != Util.METACITY_WM) {
System.out.println("This test is only useful on Metacity");
return;
}
robot = Util.createRobot();
Util.waitForIdle(robot);
final FullscreenDialogModality frame = new FullscreenDialogModality();
frame.setUndecorated(true);
frame.setBackground(Color.green);
frame.setSize(500, 500);
frame.setVisible(true);
try {
robot.delay(100);
Util.waitForIdle(robot);
EventQueue.invokeAndWait(new Runnable() {
public void run() {
frame.enterFS();
}
});
robot.delay(200);
Util.waitForIdle(robot);
frame.checkDialogModality();
EventQueue.invokeAndWait(new Runnable() {
public void run() {
frame.exitFS();
}
});
} finally {
frame.dispose();
}
}
}

View File

@ -30,8 +30,10 @@ import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.lang.reflect.Field;
abstract class AbstractTest<T> implements ExceptionListener {
private final BeanValidator validator = new BeanValidator();
final BeanValidator validator = new BeanValidator();
public final void exceptionThrown(Exception exception) {
throw new Error("unexpected exception", exception);
@ -59,7 +61,7 @@ abstract class AbstractTest<T> implements ExceptionListener {
}
/**
* This method should be overriden
* This method should be overridden
* if specified encoder should be initialized.
*
* @param encoder the XML encoder to initialize
@ -68,7 +70,7 @@ abstract class AbstractTest<T> implements ExceptionListener {
}
/**
* This method should be overriden
* This method should be overridden
* if specified decoder should be initialized.
*
* @param decoder the XML decoder to initialize
@ -77,7 +79,7 @@ abstract class AbstractTest<T> implements ExceptionListener {
}
/**
* This method should be overriden
* This method should be overridden
* for test-specific comparison.
*
* @param before the object before encoding
@ -134,6 +136,7 @@ abstract class AbstractTest<T> implements ExceptionListener {
private byte[] writeObject(Object object) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
XMLEncoder encoder = new XMLEncoder(output);
encoder.setExceptionListener(this);
initialize(encoder);
encoder.writeObject(object);
encoder.close();
@ -143,9 +146,24 @@ abstract class AbstractTest<T> implements ExceptionListener {
private Object readObject(byte[] array) {
ByteArrayInputStream input = new ByteArrayInputStream(array);
XMLDecoder decoder = new XMLDecoder(input);
decoder.setExceptionListener(this);
initialize(decoder);
Object object = decoder.readObject();
decoder.close();
return object;
}
static Field getField(String name) {
try {
int index = name.lastIndexOf('.');
String className = name.substring(0, index);
String fieldName = name.substring(1 + index);
Field field = Class.forName(className).getDeclaredField(fieldName);
field.setAccessible(true);
return field;
}
catch (Exception exception) {
throw new Error(exception);
}
}
}

View File

@ -63,6 +63,15 @@ final class BeanValidator {
}
Class type = object1.getClass();
if (!type.equals(object2.getClass())) {
// resolve different implementations of the Map.Entry interface
if ((object1 instanceof Map.Entry) && (object2 instanceof Map.Entry)) {
log("!!! special case", "Map.Entry");
Map.Entry entry1 = (Map.Entry) object1;
Map.Entry entry2 = (Map.Entry) object2;
validate(entry1.getKey(), entry2.getKey());
validate(entry1.getValue(), entry2.getValue());
return;
}
throw new IllegalStateException("could not compare objects with different types");
}
// validate elements of arrays
@ -82,10 +91,14 @@ final class BeanValidator {
}
return;
}
// special case for collections: do not use equals
boolean ignore = Collection.class.isAssignableFrom(type)
|| Map.Entry.class.isAssignableFrom(type)
|| Map.class.isAssignableFrom(type);
// validate objects using equals()
// we assume that the method equals(Object) can be called,
// if the class declares such method
if (isDefined(type, "equals", Object.class)) {
if (!ignore && isDefined(type, "equals", Object.class)) {
if (object1.equals(object2)) {
return;
}
@ -205,27 +218,7 @@ final class BeanValidator {
}
private void validate(Map map1, Map map2, boolean sorted) {
if (map1.size() != map2.size()) {
throw new IllegalStateException("could not compare maps with different sizes");
}
if (sorted) {
Iterator first = map1.entrySet().iterator();
Iterator second = map2.entrySet().iterator();
int index = 0;
while (first.hasNext() && second.hasNext()) {
log("validate map entry", Integer.valueOf(index++));
validate(first.next(), second.next());
}
if (first.hasNext() || second.hasNext()) {
throw new IllegalStateException("one map contains more entries than another one");
}
} else {
// assume that equals() can be used for keys
for (Object key : map1.keySet()) {
log("validate map value for key", key);
validate(map1.get(key), map2.get(key));
}
}
validate(map1.entrySet(), map2.entrySet(), sorted);
}
private boolean isCyclic(Object object1, Object object2) {

View File

@ -28,7 +28,6 @@
* @author Sergey Malenkov, Mark Davidson
*/
import java.beans.XMLEncoder;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
@ -78,10 +77,6 @@ public abstract class Test4631471 extends AbstractTest {
// do not any validation
}
protected final void initialize(XMLEncoder encoder) {
encoder.setExceptionListener(this);
}
public static TreeNode getRoot() {
DefaultMutableTreeNode node = new DefaultMutableTreeNode("root");
DefaultMutableTreeNode first = new DefaultMutableTreeNode("first");

View File

@ -103,7 +103,6 @@ public class Test4679556 extends AbstractTest {
}
protected void initialize(XMLEncoder encoder) {
encoder.setExceptionListener(this);
encoder.setPersistenceDelegate(C.class, new DefaultPersistenceDelegate() {
protected Expression instantiate(Object oldInstance, Encoder out) {
C c = (C) oldInstance;

View File

@ -68,11 +68,9 @@ public final class java_awt_BorderLayout extends AbstractTest<BorderLayout> {
@Override
protected void validate(BorderLayout before, BorderLayout after) {
super.validate(before, after);
BeanValidator validator = new BeanValidator();
for (String constraint : CONSTRAINTS) {
validator.validate(before.getLayoutComponent(constraint),
after.getLayoutComponent(constraint));
super.validator.validate(before.getLayoutComponent(constraint),
after.getLayoutComponent(constraint));
}
}

View File

@ -0,0 +1,83 @@
/*
* 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 8007458
* @summary Tests CardLayout encoding
* @author Sergey Malenkov
*/
import java.awt.CardLayout;
import java.lang.reflect.Field;
import java.util.Vector;
import javax.swing.JLabel;
public final class java_awt_CardLayout extends AbstractTest<CardLayout> {
private static final Field VECTOR = getField("java.awt.CardLayout.vector");
private static final Field NAME = getField("java.awt.CardLayout$Card.name");
private static final Field COMP = getField("java.awt.CardLayout$Card.comp");
public static void main(String[] args) throws Exception {
new java_awt_CardLayout().test(true);
}
@Override
protected CardLayout getObject() {
CardLayout layout = new CardLayout();
layout.addLayoutComponent(new JLabel("a"), "a");
layout.addLayoutComponent(new JLabel("b"), "b");
layout.addLayoutComponent(new JLabel("c"), "c");
return layout;
}
@Override
protected CardLayout getAnotherObject() {
CardLayout layout = new CardLayout();
layout.addLayoutComponent(new JLabel("a"), "a");
layout.addLayoutComponent(new JLabel("b"), "b");
layout.addLayoutComponent(new JLabel("c"), "c");
layout.addLayoutComponent(new JLabel("d"), "d");
return layout;
}
@Override
protected void validate(CardLayout before, CardLayout after) {
super.validate(before, after);
try {
Vector a = (Vector) VECTOR.get(after);
Vector b = (Vector) VECTOR.get(before);
int size = a.size();
if (size != b.size()) {
throw new Error("different content");
}
for (int i = 0; i < size; i++) {
super.validator.validate(NAME.get(a.get(i)), NAME.get(b.get(i)));
super.validator.validate(COMP.get(a.get(i)), COMP.get(b.get(i)));
}
}
catch (Exception exception) {
throw new Error(exception);
}
}
}

View File

@ -0,0 +1,101 @@
/*
* 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 8007458
* @summary Tests GridBagLayout encoding
* @author Sergey Malenkov
*/
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.lang.reflect.Field;
import java.util.Hashtable;
import java.util.Map;
import javax.swing.JLabel;
public final class java_awt_GridBagLayout extends AbstractTest<GridBagLayout> {
private static final Field HASHTABLE = getField("java.awt.GridBagLayout.comptable");
public static void main(String[] args) {
new java_awt_GridBagLayout().test(true);
}
@Override
protected GridBagLayout getObject() {
GridBagLayout layout = new GridBagLayout();
update(layout, "1", 1, 1);
update(layout, "2", 2, 2);
update(layout, "3", 3, 3);
return layout;
}
@Override
protected GridBagLayout getAnotherObject() {
GridBagLayout layout = new GridBagLayout();
update(layout, "11", 1, 1);
update(layout, "12", 1, 2);
update(layout, "21", 2, 1);
update(layout, "22", 2, 2);
return layout;
}
@Override
protected void validate(GridBagLayout before, GridBagLayout after) {
super.validate(before, after);
try {
Hashtable a = (Hashtable) HASHTABLE.get(after);
Hashtable b = (Hashtable) HASHTABLE.get(before);
super.validator.validate(a, b);
// for (int i = 0; i < size; i++) {
// validator.validate(NAME.get(a.get(i)), NAME.get(b.get(i)));
// validator.validate(COMP.get(a.get(i)), COMP.get(b.get(i)));
// }
}
catch (Exception exception) {
throw new Error(exception);
}
// for (String name : names) {
// validator.validate(getConstraints(before, name), getConstraints(after, name));
// }
}
private static void update(GridBagLayout layout, String id, int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
layout.addLayoutComponent(new JLabel(id), gbc);
}
/*
private static GridBagConstraints getConstraints(GridBagLayout layout, String id) {
return (layout == null) ? null : ((MyGridBagLayout) layout).getConstraints(id);
}
*/
}

View File

@ -28,6 +28,7 @@
* @author Sergey Malenkov
*/
import java.beans.XMLEncoder;
import javax.swing.DefaultCellEditor;
import javax.swing.JTextField;
import javax.swing.text.JTextComponent;
@ -46,6 +47,11 @@ public final class javax_swing_DefaultCellEditor extends AbstractTest<DefaultCel
// return new DefaultCellEditor(new JTextField("Second"));
}
@Override
protected void initialize(XMLEncoder encoder) {
encoder.setExceptionListener(null); // TODO: ignore non-public listener because of 4808251
}
protected void validate(DefaultCellEditor before, DefaultCellEditor after) {
String text = ((JTextComponent) after.getComponent()).getText();
if (!text.equals(((JTextComponent) before.getComponent()).getText()))

View File

@ -0,0 +1,138 @@
/*
* 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 8012004
@summary JINTERNALFRAME NOT BEING FINALIZED AFTER CLOSING
@author mcherkas
@run main InternalFrameIsNotCollectedTest
*/
import sun.awt.SunToolkit;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.beans.PropertyVetoException;
import java.util.Date;
public class InternalFrameIsNotCollectedTest {
public static final int waitTime = 10000;
private static Robot robot;
public static void sync() {
SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
toolkit.realSync();
}
public static void main(String[] args) throws Exception {
initRobot();
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
initUI();
try {
closeInternalFrame();
} catch (PropertyVetoException e) {
throw new RuntimeException(e);
}
}
});
sync();
invokeGC();
Thread.sleep(1000); // it's better to wait 1 sec now then 10 sec later
Date startWaiting = new Date();
synchronized (CustomInternalFrame.waiter) {
// Sync with finalization thread.
Date now = new Date();
while (now.getTime() - startWaiting.getTime() < waitTime && !CustomInternalFrame.finalized) {
CustomInternalFrame.waiter.wait(waitTime);
now = new Date();
}
}
if (!CustomInternalFrame.finalized) {
throw new RuntimeException("Closed internal frame wasn't collected");
}
}
private static void initRobot() throws AWTException {
robot = new Robot();
robot.setAutoDelay(100);
}
private static void closeInternalFrame() throws PropertyVetoException {
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_F4);
robot.keyRelease(KeyEvent.VK_F4);
robot.keyRelease(KeyEvent.VK_CONTROL);
}
private static void initUI() {
JFrame frame = new JFrame("Internal Frame Test");
frame.getContentPane().setLayout(new BorderLayout());
JDesktopPane desktopPane = new JDesktopPane();
desktopPane.setDesktopManager(new DefaultDesktopManager());
frame.getContentPane().add(desktopPane, BorderLayout.CENTER);
CustomInternalFrame iFrame = new CustomInternalFrame("Dummy Frame");
iFrame.setSize(200, 200);
iFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
desktopPane.add(iFrame);
frame.setSize(800, 600);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setVisible(true);
iFrame.setVisible(true);
}
private static void invokeGC() {
System.out.println("Firing garbage collection!");
try {
StringBuilder sb = new StringBuilder();
while (true) {
sb.append("any string. some test. a little bit more text." + sb.toString());
}
} catch (Throwable e) {
// do nothing
}
}
public static class CustomInternalFrame extends JInternalFrame {
public static volatile boolean finalized = false;
public static Object waiter = new Object();
public CustomInternalFrame(String title) {
super(title, true, true, true, true);
}
protected void finalize() {
System.out.println("Finalized!");
finalized = true;
waiter.notifyAll();
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 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
@ -35,43 +35,72 @@ import java.awt.event.*;
import javax.swing.*;
public class ActionListenerCalledTwiceTest {
static String menuItems[] = { "Item1", "Item2" };
static KeyStroke keyStrokes[] = {
KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.META_MASK),
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)
};
static volatile int listenerCallCounter = 0;
public static void main(String[] args) throws Exception {
if (sun.awt.OSInfo.getOSType() != sun.awt.OSInfo.OSType.MACOSX) {
System.out.println("This test is for MacOS only. Automatically passed on other platforms.");
return;
}
System.setProperty("apple.laf.useScreenMenuBar", "true");
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createAndShowGUI();
}
});
SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
Robot robot = new Robot();
robot.setAutoDelay(100);
robot.keyPress(KeyEvent.VK_META);
robot.keyPress(KeyEvent.VK_E);
robot.keyRelease(KeyEvent.VK_E);
robot.keyRelease(KeyEvent.VK_META);
toolkit.realSync();
if (listenerCallCounter != 1) {
throw new Exception("Test failed: ActionListener called " + listenerCallCounter + " times instead of 1!");
for (int i = 0; i < menuItems.length; ++i) {
KeyStroke ks = keyStrokes[i];
int modKeyCode = getModKeyCode(ks.getModifiers());
if (modKeyCode != 0) {
robot.keyPress(modKeyCode);
}
robot.keyPress(ks.getKeyCode());
robot.keyRelease(ks.getKeyCode());
if (modKeyCode != 0) {
robot.keyRelease(modKeyCode);
}
toolkit.realSync();
if (listenerCallCounter != 1) {
throw new Exception("Test failed: ActionListener for " + menuItems[i] +
" called " + listenerCallCounter + " times instead of 1!");
}
listenerCallCounter = 0;
}
}
private static void createAndShowGUI() {
JMenuItem newItem = new JMenuItem("Exit");
newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.META_MASK));
newItem.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e) {
listenerCallCounter++;
}
}
);
JMenu menu = new JMenu("Menu");
menu.add(newItem);
for (int i = 0; i < menuItems.length; ++i) {
JMenuItem newItem = new JMenuItem(menuItems[i]);
newItem.setAccelerator(keyStrokes[i]);
newItem.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e) {
listenerCallCounter++;
}
}
);
menu.add(newItem);
}
JMenuBar bar = new JMenuBar();
bar.add(menu);
JFrame frame = new JFrame("Test");
@ -80,4 +109,24 @@ public class ActionListenerCalledTwiceTest {
frame.pack();
frame.setVisible(true);
}
private static int getModKeyCode(int mod) {
if ((mod & (InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK)) != 0) {
return KeyEvent.VK_SHIFT;
}
if ((mod & (InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK)) != 0) {
return KeyEvent.VK_CONTROL;
}
if ((mod & (InputEvent.ALT_DOWN_MASK | InputEvent.ALT_MASK)) != 0) {
return KeyEvent.VK_ALT;
}
if ((mod & (InputEvent.META_DOWN_MASK | InputEvent.META_MASK)) != 0) {
return KeyEvent.VK_META;
}
return 0;
}
}