8006941: [macosx] Deadlock in drag and drop

7199783: Setting cursor on DragSourceContext does not work on OSX

Reviewed-by: anthony, serb
This commit is contained in:
Petr Pchelko 2013-04-05 18:29:53 +01:00
parent 918a376474
commit 9ff5db6260
11 changed files with 255 additions and 183 deletions

View File

@ -336,7 +336,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
return peerTreeLock;
}
final T getTarget() {
public final T getTarget() {
return target;
}

View File

@ -51,15 +51,6 @@ final class CCursorManager extends LWCursorManager {
@Override
protected Point getCursorPosition() {
synchronized(this) {
if (isDragging) {
// during the drag operation, the appkit thread is blocked,
// so nativeGetCursorPosition invocation may cause a deadlock.
// In order to avoid this, we returns last know cursor position.
return new Point(dragPos);
}
}
final Point2D nativePosition = nativeGetCursorPosition();
return new Point((int)nativePosition.getX(), (int)nativePosition.getY());
}
@ -101,31 +92,4 @@ final class CCursorManager extends LWCursorManager {
// do something special
throw new RuntimeException("Unimplemented");
}
// package private methods to handle cursor change during drag-and-drop
private boolean isDragging = false;
private Point dragPos = null;
synchronized void startDrag(int x, int y) {
if (isDragging) {
throw new RuntimeException("Invalid Drag state in CCursorManager!");
}
isDragging = true;
dragPos = new Point(x, y);
}
synchronized void updateDragPosition(int x, int y) {
if (!isDragging) {
throw new RuntimeException("Invalid Drag state in CCursorManager!");
}
dragPos.move(x, y);
}
synchronized void stopDrag() {
if (!isDragging) {
throw new RuntimeException("Invalid Drag state in CCursorManager!");
}
isDragging = false;
dragPos = null;
}
}

View File

@ -38,8 +38,12 @@ import javax.swing.text.*;
import javax.accessibility.*;
import java.util.Map;
import java.util.concurrent.Callable;
import sun.awt.dnd.*;
import sun.lwawt.LWComponentPeer;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.PlatformWindow;
public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
@ -104,13 +108,8 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
}
//It sure will be LWComponentPeer instance as rootComponent is a Window
LWComponentPeer peer = (LWComponentPeer)rootComponent.getPeer();
//Get a pointer to a native window
CPlatformWindow platformWindow = (CPlatformWindow) peer.getPlatformWindow();
long nativeWindowPtr = platformWindow.getNSWindowPtr();
// Get drag cursor:
Cursor cursor = this.getCursor();
PlatformWindow platformWindow = ((LWComponentPeer)rootComponent.getPeer()).getPlatformWindow();
long nativeViewPtr = CPlatformWindow.getNativeViewPtr(platformWindow);
// If there isn't any drag image make one of default appearance:
if (fDragImage == null)
@ -139,19 +138,15 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
try {
// Create native dragging source:
final long nativeDragSource = createNativeDragSource(component, peer, nativeWindowPtr, transferable, triggerEvent,
final long nativeDragSource = createNativeDragSource(component, nativeViewPtr, transferable, triggerEvent,
(int) (dragOrigin.getX()), (int) (dragOrigin.getY()), extModifiers,
clickCount, timestamp, cursor, fDragCImage, dragImageOffset.x, dragImageOffset.y,
clickCount, timestamp, fDragCImage, dragImageOffset.x, dragImageOffset.y,
getDragSourceContext().getSourceActions(), formats, formatMap);
if (nativeDragSource == 0)
throw new InvalidDnDOperationException("");
setNativeContext(nativeDragSource);
CCursorManager.getInstance().startDrag(
(int) (dragOrigin.getX()),
(int) (dragOrigin.getY()));
}
catch (Exception e) {
@ -160,6 +155,8 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(transferable);
CCursorManager.getInstance().setCursor(getCursor());
// Create a new thread to run the dragging operation since it's synchronous, only coming back
// after dragging is finished. This leaves the AWT event thread free to handle AWT events which
// are posted during dragging by native event handlers.
@ -173,8 +170,6 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
} catch (Exception e) {
e.printStackTrace();
} finally {
CCursorManager.getInstance().stopDrag();
releaseNativeDragSource(nativeDragSource);
fDragImage = null;
if (fDragCImage != null) {
@ -189,8 +184,6 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
}
catch (Exception e) {
CCursorManager.getInstance().stopDrag();
final long nativeDragSource = getNativeContext();
setNativeContext(0);
releaseNativeDragSource(nativeDragSource);
@ -416,13 +409,24 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
final int modifiers,
final int x, final int y) {
CCursorManager.getInstance().updateDragPosition(x, y);
try {
Component componentAt = LWCToolkit.invokeAndWait(
new Callable<Component>() {
@Override
public Component call() {
LWWindowPeer mouseEventComponent = LWWindowPeer.getWindowUnderCursor();
if (mouseEventComponent == null) {
return null;
}
Component root = SwingUtilities.getRoot(mouseEventComponent.getTarget());
if (root == null) {
return null;
}
Point rootLocation = root.getLocationOnScreen();
return getDropTargetAt(root, x - rootLocation.x, y - rootLocation.y);
}
}, getComponent());
Component rootComponent = SwingUtilities.getRoot(getComponent());
if(rootComponent != null) {
Point componentPoint = new Point(x, y);
SwingUtilities.convertPointFromScreen(componentPoint, rootComponent);
Component componentAt = SwingUtilities.getDeepestComponentAt(rootComponent, componentPoint.x, componentPoint.y);
if(componentAt != hoveringComponent) {
if(hoveringComponent != null) {
dragExit(x, y);
@ -432,20 +436,36 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
}
hoveringComponent = componentAt;
}
postDragSourceDragEvent(targetActions, modifiers, x, y,
DISPATCH_MOUSE_MOVED);
} catch (Exception e) {
throw new InvalidDnDOperationException("Failed to handle DragMouseMoved event");
}
postDragSourceDragEvent(targetActions, modifiers, x, y,
DISPATCH_MOUSE_MOVED);
}
/**
* upcall from native code
*/
private void dragEnter(final int targetActions,
final int modifiers,
final int x, final int y) {
CCursorManager.getInstance().updateDragPosition(x, y);
//Returns the first lightweight or heavyweight Component which has a dropTarget ready to accept the drag
//Should be called from the EventDispatchThread
private static Component getDropTargetAt(Component root, int x, int y) {
if (!root.contains(x, y) || !root.isEnabled() || !root.isVisible()) {
return null;
}
postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER);
if (root.getDropTarget() != null && root.getDropTarget().isActive()) {
return root;
}
if (root instanceof Container) {
for (Component comp : ((Container) root).getComponents()) {
Point loc = comp.getLocation();
Component dropTarget = getDropTargetAt(comp, x - loc.x, y - loc.y);
if (dropTarget != null) {
return dropTarget;
}
}
}
return null;
}
/**
@ -455,19 +475,15 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
hoveringComponent = null;
}
public void setCursor(Cursor c) throws InvalidDnDOperationException {
// TODO : BG
//AWTLockAccess.awtLock();
super.setCursor(c);
//AWTLockAccess.awtUnlock();
@Override
protected void setNativeCursor(long nativeCtxt, Cursor c, int cType) {
CCursorManager.getInstance().setCursor(c);
}
protected native void setNativeCursor(long nativeCtxt, Cursor c, int cType);
// Native support:
private native long createNativeDragSource(Component component, ComponentPeer peer, long nativePeer, Transferable transferable,
private native long createNativeDragSource(Component component, long nativePeer, Transferable transferable,
InputEvent triggerEvent, int dragPosX, int dragPosY, int extModifiers, int clickCount, long timestamp,
Cursor cursor, CImage nsDragImage, int dragImageOffsetX, int dragImageOffsetY,
CImage nsDragImage, int dragImageOffsetX, int dragImageOffsetY,
int sourceActions, long[] formats, Map formatMap);
private native void doDragging(long nativeDragSource);

View File

@ -30,6 +30,7 @@ import java.awt.peer.ComponentPeer;
import java.awt.dnd.DropTarget;
import sun.lwawt.LWComponentPeer;
import sun.lwawt.PlatformWindow;
public final class CDropTarget {
@ -50,21 +51,11 @@ public final class CDropTarget {
fComponent = component;
fPeer = peer;
// Make sure the drop target is a ComponentModel:
if (!(peer instanceof LWComponentPeer))
throw new IllegalArgumentException("CDropTarget's peer must be a LWComponentPeer.");
// Get model pointer (CButton.m and such) and its native peer:
LWComponentPeer model = (LWComponentPeer) peer;
if (model.getPlatformWindow() instanceof CPlatformWindow) {
CPlatformWindow platformWindow = (CPlatformWindow) model.getPlatformWindow();
long nativePeer = platformWindow.getNSWindowPtr();
// Create native dragging destination:
fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer);
if (fNativeDropTarget == 0) {
throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed.");
}
long nativePeer = CPlatformWindow.getNativeViewPtr(((LWComponentPeer) peer).getPlatformWindow());
// Create native dragging destination:
fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer);
if (fNativeDropTarget == 0) {
throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed.");
}
}

View File

@ -875,6 +875,21 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
}
}
/**
* Helper method to get a pointer to the native view from the PlatformWindow.
*/
static long getNativeViewPtr(PlatformWindow platformWindow) {
long nativePeer = 0L;
if (platformWindow instanceof CPlatformWindow) {
nativePeer = ((CPlatformWindow) platformWindow).getContentView().getAWTView();
} else if (platformWindow instanceof CViewPlatformEmbeddedFrame){
nativePeer = ((CViewPlatformEmbeddedFrame) platformWindow).getNSViewPtr();
} else {
throw new IllegalArgumentException("Unsupported platformWindow implementation");
}
return nativePeer;
}
/*************************************************************
* Callbacks from the AWTWindow and AWTView objc classes.
*************************************************************/

View File

@ -33,7 +33,6 @@
@private
NSView* fView;
jobject fComponent;
jobject fComponentPeer;
jobject fDragSourceContextPeer;
jobject fTransferable;
@ -43,8 +42,6 @@
jint fClickCount;
jint fModifiers;
jobject fCursor;
NSImage* fDragImage;
NSPoint fDragImageOffset;
@ -59,12 +56,22 @@
+ (CDragSource *) currentDragSource;
// Common methods:
- (id)init:(jobject)jdragsourcecontextpeer component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control
transferable:(jobject)jtransferable triggerEvent:(jobject)jtrigger
dragPosX:(jint)dragPosX dragPosY:(jint)dragPosY modifiers:(jint)extModifiers clickCount:(jint)clickCount timeStamp:(jlong)timeStamp
cursor:(jobject)jcursor
dragImage:(jobject)jnsdragimage dragImageOffsetX:(jint)jdragimageoffsetx dragImageOffsetY:(jint)jdragimageoffsety
sourceActions:(jint)jsourceactions formats:(jlongArray)jformats formatMap:(jobject)jformatmap;
- (id) init:(jobject)jDragSourceContextPeer
component:(jobject)jComponent
control:(id)control
transferable:(jobject)jTransferable
triggerEvent:(jobject)jTrigger
dragPosX:(jint)dragPosX
dragPosY:(jint)dragPosY
modifiers:(jint)extModifiers
clickCount:(jint)clickCount
timeStamp:(jlong)timeStamp
dragImage:(jobject)jDragImage
dragImageOffsetX:(jint)jDragImageOffsetX
dragImageOffsetY:(jint)jDragImageOffsetY
sourceActions:(jint)jSourceActions
formats:(jlongArray)jFormats
formatMap:(jobject)jFormatMap;
- (void)removeFromView:(JNIEnv *)env;

View File

@ -84,12 +84,22 @@ static BOOL sNeedsEnter;
return sCurrentDragSource;
}
- (id)init:(jobject)jdragsourcecontextpeer component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control
transferable:(jobject)jtransferable triggerEvent:(jobject)jtrigger
dragPosX:(jint)dragPosX dragPosY:(jint)dragPosY modifiers:(jint)extModifiers clickCount:(jint)clickCount
timeStamp:(jlong)timeStamp cursor:(jobject)jcursor
dragImage:(jobject)jnsdragimage dragImageOffsetX:(jint)jdragimageoffsetx dragImageOffsetY:(jint)jdragimageoffsety
sourceActions:(jint)jsourceactions formats:(jlongArray)jformats formatMap:(jobject)jformatmap
- (id) init:(jobject)jDragSourceContextPeer
component:(jobject)jComponent
control:(id)control
transferable:(jobject)jTransferable
triggerEvent:(jobject)jTrigger
dragPosX:(jint)dragPosX
dragPosY:(jint)dragPosY
modifiers:(jint)extModifiers
clickCount:(jint)clickCount
timeStamp:(jlong)timeStamp
dragImage:(jobject)jDragImage
dragImageOffsetX:(jint)jDragImageOffsetX
dragImageOffsetY:(jint)jDragImageOffsetY
sourceActions:(jint)jSourceActions
formats:(jlongArray)jFormats
formatMap:(jobject)jFormatMap
{
self = [super init];
DLog2(@"[CDragSource init]: %@\n", self);
@ -100,27 +110,25 @@ static BOOL sNeedsEnter;
// Construct the object if we have a valid model for it:
if (control != nil) {
JNIEnv *env = [ThreadUtilities getJNIEnv];
fComponent = JNFNewGlobalRef(env, jcomponent);
fComponentPeer = JNFNewGlobalRef(env, jpeer);
fDragSourceContextPeer = JNFNewGlobalRef(env, jdragsourcecontextpeer);
fComponent = JNFNewGlobalRef(env, jComponent);
fDragSourceContextPeer = JNFNewGlobalRef(env, jDragSourceContextPeer);
fTransferable = JNFNewGlobalRef(env, jtransferable);
fTriggerEvent = JNFNewGlobalRef(env, jtrigger);
fCursor = JNFNewGlobalRef(env, jcursor);
fTransferable = JNFNewGlobalRef(env, jTransferable);
fTriggerEvent = JNFNewGlobalRef(env, jTrigger);
if (jnsdragimage) {
if (jDragImage) {
JNF_MEMBER_CACHE(nsImagePtr, CImageClass, "ptr", "J");
jlong imgPtr = JNFGetLongField(env, jnsdragimage, nsImagePtr);
jlong imgPtr = JNFGetLongField(env, jDragImage, nsImagePtr);
fDragImage = (NSImage*) jlong_to_ptr(imgPtr); // Double-casting prevents compiler 'd$|//
[fDragImage retain];
}
fDragImageOffset = NSMakePoint(jdragimageoffsetx, jdragimageoffsety);
fDragImageOffset = NSMakePoint(jDragImageOffsetX, jDragImageOffsetY);
fSourceActions = jsourceactions;
fFormats = JNFNewGlobalRef(env, jformats);
fFormatMap = JNFNewGlobalRef(env, jformatmap);
fSourceActions = jSourceActions;
fFormats = JNFNewGlobalRef(env, jFormats);
fFormatMap = JNFNewGlobalRef(env, jFormatMap);
fTriggerEventTimeStamp = timeStamp;
fDragPos = NSMakePoint(dragPosX, dragPosY);
@ -129,9 +137,8 @@ static BOOL sNeedsEnter;
// Set this object as a dragging source:
AWTView *awtView = [((NSWindow *) control) contentView];
fView = [awtView retain];
[awtView setDragSource:self];
fView = [(AWTView *) control retain];
[fView setDragSource:self];
// Let AWTEvent know Java drag is getting underway:
[NSEvent javaDraggingBegin];
@ -158,11 +165,6 @@ static BOOL sNeedsEnter;
fComponent = NULL;
}
if (fComponentPeer != NULL) {
JNFDeleteGlobalRef(env, fComponentPeer);
fComponentPeer = NULL;
}
if (fDragSourceContextPeer != NULL) {
JNFDeleteGlobalRef(env, fDragSourceContextPeer);
fDragSourceContextPeer = NULL;
@ -178,11 +180,6 @@ static BOOL sNeedsEnter;
fTriggerEvent = NULL;
}
if (fCursor != NULL) {
JNFDeleteGlobalRef(env, fCursor);
fCursor = NULL;
}
if (fFormats != NULL) {
JNFDeleteGlobalRef(env, fFormats);
fFormats = NULL;
@ -586,11 +583,6 @@ static BOOL sNeedsEnter;
{
AWT_ASSERT_NOT_APPKIT_THREAD;
// Set the drag cursor (or not 3839999)
//JNIEnv *env = [ThreadUtilities getJNIEnv];
//jobject gCursor = JNFNewGlobalRef(env, fCursor);
//[EventFactory setJavaCursor:gCursor withEnv:env];
[self performSelectorOnMainThread:@selector(doDrag) withObject:nil waitUntilDone:YES]; // AWT_THREADING Safe (called from unique asynchronous thread)
}

View File

@ -34,12 +34,13 @@
/*
* Class: sun_lwawt_macosx_CDragSourceContextPeer
* Method: createNativeDragSource
* Signature: (Ljava/awt/Component;Ljava/awt/peer/ComponentPeer;JLjava/awt/datatransfer/Transferable;Ljava/awt/event/InputEvent;IIIIJLjava/awt/Cursor;IJIII[JLjava/util/Map;)J
* Signature: (Ljava/awt/Component;JLjava/awt/datatransfer/Transferable;
Ljava/awt/event/InputEvent;IIIIJIJIII[JLjava/util/Map;)J
*/
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_createNativeDragSource
(JNIEnv *env, jobject jthis, jobject jcomponent, jobject jpeer, jlong jnativepeer, jobject jtransferable,
(JNIEnv *env, jobject jthis, jobject jcomponent, jlong jnativepeer, jobject jtransferable,
jobject jtrigger, jint jdragposx, jint jdragposy, jint jextmodifiers, jint jclickcount, jlong jtimestamp,
jobject jcursor, jobject jnsdragimage, jint jdragimageoffsetx, jint jdragimageoffsety,
jobject jnsdragimage, jint jdragimageoffsetx, jint jdragimageoffsety,
jint jsourceactions, jlongArray jformats, jobject jformatmap)
{
id controlObj = (id) jlong_to_ptr(jnativepeer);
@ -47,12 +48,22 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_createNativ
JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
dragSource = [[CDragSource alloc] init:jthis component:jcomponent peer:jpeer control:controlObj
transferable:jtransferable triggerEvent:jtrigger dragPosX:jdragposx
dragPosY:jdragposy modifiers:jextmodifiers clickCount:jclickcount timeStamp:jtimestamp
cursor:jcursor dragImage:jnsdragimage dragImageOffsetX:jdragimageoffsetx
dragImageOffsetY:jdragimageoffsety sourceActions:jsourceactions
formats:jformats formatMap:jformatmap];
dragSource = [[CDragSource alloc] init:jthis
component:jcomponent
control:controlObj
transferable:jtransferable
triggerEvent:jtrigger
dragPosX:jdragposx
dragPosY:jdragposy
modifiers:jextmodifiers
clickCount:jclickcount
timeStamp:jtimestamp
dragImage:jnsdragimage
dragImageOffsetX:jdragimageoffsetx
dragImageOffsetY:jdragimageoffsety
sourceActions:jsourceactions
formats:jformats
formatMap:jformatmap];
}];
JNF_COCOA_EXIT(env);
@ -94,19 +105,3 @@ JNF_COCOA_ENTER(env);
[dragSource removeFromView:env];
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CDragSourceContextPeer
* Method: setNativeCursor
* Signature: (JLjava/awt/Cursor;I)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_setNativeCursor
(JNIEnv *env, jobject jthis, jlong nativeDragSourceVal, jobject jcursor, jint jcursortype)
{
//AWT_ASSERT_NOT_APPKIT_THREAD;
//JNF_COCOA_ENTER(env);
// jobject gCursor = JNFNewGlobalRef(env, jcursor);
// [EventFactory setJavaCursor:gCursor withEnv:env];
//JNF_COCOA_EXIT(env);
}

View File

@ -81,9 +81,8 @@ extern JNFClassInfo jc_CDropTargetContextPeer;
fComponent = JNFNewGlobalRef(env, jcomponent);
fDropTarget = JNFNewGlobalRef(env, jdropTarget);
AWTView *awtView = [((NSWindow *) control) contentView];
fView = [awtView retain];
[awtView setDropTarget:self];
fView = [((AWTView *) control) retain];
[fView setDropTarget:self];
} else {
@ -177,6 +176,10 @@ extern JNFClassInfo jc_CDropTargetContextPeer;
{
DLog2(@"[CDropTarget dealloc]: %@\n", self);
if(sCurrentDropTarget == self) {
sCurrentDropTarget = nil;
}
[fView release];
fView = nil;
@ -490,7 +493,10 @@ extern JNFClassInfo jc_CDropTargetContextPeer;
JNF_MEMBER_CACHE(handleEnterMessageMethod, jc_CDropTargetContextPeer, "handleEnterMessage", "(Ljava/awt/Component;IIII[JJ)I");
if (sDraggingError == FALSE) {
// Double-casting self gets rid of 'different size' compiler warning:
actions = JNFCallIntMethod(env, fDropTargetContextPeer, handleEnterMessageMethod, fComponent, (jint) javaLocation.x, (jint) javaLocation.y, dropAction, actions, formats, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler)
// AWT_THREADING Safe (CToolkitThreadBlockedHandler)
actions = JNFCallIntMethod(env, fDropTargetContextPeer, handleEnterMessageMethod,
fComponent, (jint) javaLocation.x, (jint) javaLocation.y,
dropAction, actions, formats, ptr_to_jlong(self));
}
if (sDraggingError == FALSE) {
@ -510,11 +516,6 @@ extern JNFClassInfo jc_CDropTargetContextPeer;
// Remember the dragOp for no-op'd update messages:
sUpdateOperation = dragOp;
}
// If we are in the same process as the sender, make the sender post the appropriate message
if (sender) {
[[CDragSource currentDragSource] postDragEnter];
}
}
// 9-11-02 Note: the native event thread would not handle an exception gracefully:
@ -608,11 +609,9 @@ extern JNFClassInfo jc_CDropTargetContextPeer;
JNF_MEMBER_CACHE(handleExitMessageMethod, jc_CDropTargetContextPeer, "handleExitMessage", "(Ljava/awt/Component;J)V");
if (sDraggingError == FALSE) {
DLog3(@" - dragExit: loc native %f, %f\n", sDraggingLocation.x, sDraggingLocation.y);
JNFCallVoidMethod(env, fDropTargetContextPeer, handleExitMessageMethod, fComponent, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler)
// If we are in the same process as the sender, make the sender post the appropriate message
if (sender) {
[[CDragSource currentDragSource] postDragExit];
}
// AWT_THREADING Safe (CToolkitThreadBlockedHandler)
JNFCallVoidMethod(env, fDropTargetContextPeer,
handleExitMessageMethod, fComponent, ptr_to_jlong(self));
}
// 5-27-03 Note: [Radar 3270455]

View File

@ -278,7 +278,7 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer
* upcall from native code
*/
private void dragEnter(final int targetActions,
protected void dragEnter(final int targetActions,
final int modifiers,
final int x, final int y) {
postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER);
@ -356,10 +356,6 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer
public static void setDragDropInProgress(boolean b)
throws InvalidDnDOperationException {
if (dragDropInProgress == b) {
throw new InvalidDnDOperationException(getExceptionMessage(b));
}
synchronized (SunDragSourceContextPeer.class) {
if (dragDropInProgress == b) {
throw new InvalidDnDOperationException(getExceptionMessage(b));

View File

@ -0,0 +1,97 @@
/*
* 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 @summary JVM crash if the frame is disposed in DropTargetListener
* @author Petr Pchelko
* @library ../../regtesthelpers
* @build Util
* @compile DisposeFrameOnDragTest.java
* @run main/othervm DisposeFrameOnDragTest
*/
import java.awt.AWTException;
import java.awt.Point;
import java.awt.Robot;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.InputEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.TooManyListenersException;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import test.java.awt.regtesthelpers.Util;
public class DisposeFrameOnDragTest {
private static JTextArea textArea;
public static void main(String[] args) throws Throwable {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
constructTestUI();
}
});
Util.waitForIdle(null);
try {
Point loc = textArea.getLocationOnScreen();
Util.drag(new Robot(),
new Point((int) loc.x + 3, (int) loc.y + 3),
new Point((int) loc.x + 40, (int) loc.y + 40),
InputEvent.BUTTON1_MASK);
} catch (AWTException ex) {
throw new RuntimeException("Could not initiate a drag operation");
}
Util.waitForIdle(null);
}
private static void constructTestUI() {
final JFrame frame = new JFrame("Test frame");
textArea = new JTextArea("Drag Me!");
try {
textArea.getDropTarget().addDropTargetListener(new DropTargetAdapter() {
@Override
public void drop(DropTargetDropEvent dtde) {
//IGNORE
}
@Override
public void dragOver(DropTargetDragEvent dtde) {
frame.dispose();
}
});
} catch (TooManyListenersException ex) {
throw new RuntimeException(ex);
}
textArea.setSize(100, 100);
textArea.setDragEnabled(true);
textArea.select(0, textArea.getText().length());
frame.add(textArea);
frame.setBounds(100, 100, 100, 100);
frame.setVisible(true);
}
}