src/macosx/classes/sun/lwawt/macosx/CDropTargetContextPeer.java
Print this page
@@ -24,10 +24,11 @@
*/
package sun.lwawt.macosx;
import java.awt.*;
+import java.awt.dnd.DropTarget;
import sun.awt.dnd.SunDropTargetContextPeer;
import sun.awt.dnd.SunDropTargetEvent;
import javax.swing.*;
@@ -36,11 +37,11 @@
final class CDropTargetContextPeer extends SunDropTargetContextPeer {
private long fNativeDropTransfer = 0;
private long fNativeDataAvailable = 0;
private Object fNativeData = null;
- private boolean insideTarget = true;
+ private DropTarget insideTarget = null;
Object awtLockAccess = new Object();
static CDropTargetContextPeer getDropTargetContextPeer() {
return new CDropTargetContextPeer();
@@ -86,48 +87,74 @@
}
return fNativeData;
}
- // We need to take care of dragExit message because for some reason it is not being
- // generated for lightweight components
+ // We need to take care of dragEnter and dragExit messages because
+ // native system generates them only for heavyweights
@Override
protected void processMotionMessage(SunDropTargetEvent event, boolean operationChanged) {
- Component eventSource = (Component)event.getComponent();
- Point screenPoint = event.getPoint();
- SwingUtilities.convertPointToScreen(screenPoint, eventSource);
- Rectangle screenBounds = new Rectangle(eventSource.getLocationOnScreen().x,
- eventSource.getLocationOnScreen().y,
- eventSource.getWidth(), eventSource.getHeight());
- if(insideTarget) {
- if(!screenBounds.contains(screenPoint)) {
+ boolean eventInsideTarget = isEventInsideTarget(event);
+ if(event.getComponent().getDropTarget() == insideTarget) {
+ if(!eventInsideTarget) {
processExitMessage(event);
- insideTarget = false;
return;
}
} else {
- if(screenBounds.contains(screenPoint)) {
+ if(eventInsideTarget) {
processEnterMessage(event);
- insideTarget = true;
} else {
return;
}
}
super.processMotionMessage(event, operationChanged);
}
+ /**
+ * Could be called when DnD enters a heavyweight or synthesized in processMotionMessage
+ */
+ @Override
+ protected void processEnterMessage(SunDropTargetEvent event) {
+ Component c = event.getComponent();
+ DropTarget dt = event.getComponent().getDropTarget();
+ if (isEventInsideTarget(event)
+ && dt != insideTarget
+ && c.isShowing()
+ && dt != null
+ && dt.isActive()) {
+ insideTarget = dt;
+ super.processEnterMessage(event);
+ }
+ }
+
+ /**
+ * Could be called when DnD exits a heavyweight or synthesized in processMotionMessage
+ */
+ @Override
+ protected void processExitMessage(SunDropTargetEvent event) {
+ if(event.getComponent().getDropTarget() == insideTarget) {
+ insideTarget = null;
+ super.processExitMessage(event);
+ }
+ }
+
@Override
protected void processDropMessage(SunDropTargetEvent event) {
- Component eventSource = (Component)event.getComponent();
+ if(isEventInsideTarget(event)) {
+ super.processDropMessage(event);
+ insideTarget = null;
+ }
+ }
+
+ private boolean isEventInsideTarget(SunDropTargetEvent event) {
+ Component eventSource = event.getComponent();
Point screenPoint = event.getPoint();
SwingUtilities.convertPointToScreen(screenPoint, eventSource);
Rectangle screenBounds = new Rectangle(eventSource.getLocationOnScreen().x,
eventSource.getLocationOnScreen().y,
eventSource.getWidth(), eventSource.getHeight());
- if(screenBounds.contains(screenPoint)) {
- super.processDropMessage(event);
- }
+ return screenBounds.contains(screenPoint);
}
@Override
protected int postDropTargetEvent(Component component, int x, int y, int dropAction,
int actions, long[] formats, long nativeCtxt, int eventID,