提交 b0643450 编写于 作者: L lana

Merge

......@@ -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);
......
/*
* 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();
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);
final int[] displayIDs = getDisplayIDs();
private void initDevices() {
synchronized (this) {
final Map<Integer, CGraphicsDevice> old = new HashMap<>(devices);
devices.clear();
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.
if (!old.containsKey(mainID)) {
old.put(mainID, new CGraphicsDevice(mainID));
}
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();
......
......@@ -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;
// 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;
/**
* 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 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();
......
......@@ -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.
*/
......
......@@ -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();
}
}
......
/*
* 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 */
/*
* 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.
......
......@@ -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);
});
}
......
/*
* 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;
}
......
......@@ -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);
}
}];
}
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
}
}
......@@ -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.
*
......
......@@ -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;
......
......@@ -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))
......
......@@ -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();
......
/*
* 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);
......
# 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
......
/*
* 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();
}
}
}
......@@ -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);
}
}
}
......@@ -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) {
......
......@@ -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");
......
......@@ -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;
......
......@@ -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));
}
}
......
/*
* Copyright (c) 2003, 2009, 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
* 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.
* 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
......@@ -22,57 +20,64 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.beans;
/*
* @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;
/**
* A utility class for reflectively finding methods, constuctors and fields
* using reflection.
*/
class ReflectionUtils {
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");
@SuppressWarnings("rawtypes")
public static boolean isPrimitive(Class type) {
return primitiveTypeFor(type) != null;
public static void main(String[] args) throws Exception {
new java_awt_CardLayout().test(true);
}
@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;
@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;
}
/**
* 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) {
@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 {
Field f = cls.getDeclaredField(name);
f.setAccessible(true);
return f.get(instance);
}
catch (Exception e) {
if (el != null) {
el.exceptionThrown(e);
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);
}
return null;
}
}
/*
* 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);
}
*/
}
......@@ -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()))
......
/*
* 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();
}
}
}
\ No newline at end of file
/*
* 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;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册