/* * Copyright (c) 2000, 2010, 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 sun.awt.dnd; import java.awt.Component;import java.awt.Point; import java.awt.datatransfer.DataFlavor;import java.awt.datatransfer.Transferable;import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget;import java.awt.dnd.DropTargetContext;import java.awt.dnd.DropTargetListener;import java.awt.dnd.DropTargetEvent;import java.awt.dnd.DropTargetDragEvent;import java.awt.dnd.DropTargetDropEvent;import java.awt.dnd.InvalidDnDOperationException; import java.awt.dnd.peer.DropTargetContextPeer; import java.util.HashSet;import java.util.Map;import java.util.Arrays; import sun.util.logging.PlatformLogger; import java.io.IOException;import java.io.InputStream; import sun.awt.AppContext;import sun.awt.SunToolkit;import sun.awt.datatransfer.DataTransferer;import sun.awt.datatransfer.ToolkitThreadBlockedHandler;import sun.security.util.SecurityConstants; /** * <p> * The SunDropTargetContextPeer class is the generic class responsible for handling * the interaction between a windowing systems DnD system and Java. * </p> * * @since JDK1.3.1 * */ public abstract class SunDropTargetContextPeer implements DropTargetContextPeer, Transferable { /* * A boolean constant that requires the peer to wait until the * SunDropTargetEvent is processed and return the status back * to the native code. */ public static final boolean DISPATCH_SYNC = true; private DropTarget currentDT; private DropTargetContext currentDTC; private long[] currentT; private int currentA; // target actions private int currentSA; // source actions private int currentDA; // current drop action private int previousDA; private long nativeDragContext; private Transferable local; private boolean dragRejected = false; protected int dropStatus = STATUS_NONE; protected boolean dropComplete = false; // The flag is used to monitor whether the drop action is // handled by a user. That allows to distinct during // which operation getTransferData() method is invoked. boolean dropInProcess = false; /* * global lock */ protected static final Object _globalLock = new Object(); private static final PlatformLogger dndLog = PlatformLogger.getLogger("sun.awt.dnd.SunDropTargetContextPeer"); /* * a primitive mechanism for advertising intra-JVM Transferables */ protected static Transferable currentJVMLocalSourceTransferable = null; public static void setCurrentJVMLocalSourceTransferable(Transferable t) throws InvalidDnDOperationException { synchronized(_globalLock) { if (t != null && currentJVMLocalSourceTransferable != null) { throw new InvalidDnDOperationException(); } else { currentJVMLocalSourceTransferable = t; } } } /** * obtain the transferable iff the operation is in the same VM */ private static Transferable getJVMLocalSourceTransferable() { return currentJVMLocalSourceTransferable; } /* * constants used by dropAccept() or dropReject() */ protected final static int STATUS_NONE = 0; // none pending protected final static int STATUS_WAIT = 1; // drop pending protected final static int STATUS_ACCEPT = 2; protected final static int STATUS_REJECT = -1; /** * create the peer */ public SunDropTargetContextPeer() { super(); } /** * @return the DropTarget associated with this peer */ public DropTarget getDropTarget() { return currentDT; } /** * @param actions set the current actions */ public synchronized void setTargetActions(int actions) { currentA = actions & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK); } /** * @return the current target actions */ public int getTargetActions() { return currentA; } /** * get the Transferable associated with the drop */ public Transferable getTransferable() { return this; } /** * @return current DataFlavors available */ // NOTE: This method may be called by privileged threads. // DO NOT INVOKE CLIENT CODE ON THIS THREAD! public DataFlavor[] getTransferDataFlavors() { final Transferable localTransferable = local; if (localTransferable != null) { return localTransferable.getTransferDataFlavors(); } else { return DataTransferer.getInstance().getFlavorsForFormatsAsArray (currentT, DataTransferer.adaptFlavorMap (currentDT.getFlavorMap())); } } /** * @return if the flavor is supported */ public boolean isDataFlavorSupported(DataFlavor df) { Transferable localTransferable = local; if (localTransferable != null) { return localTransferable.isDataFlavorSupported(df); } else { return DataTransferer.getInstance().getFlavorsForFormats (currentT, DataTransferer.adaptFlavorMap (currentDT.getFlavorMap())). containsKey(df); } } /** * @return the data */ public Object getTransferData(DataFlavor df) throws UnsupportedFlavorException, IOException, InvalidDnDOperationException { SecurityManager sm = System.getSecurityManager(); try { if (!dropInProcess && sm != null) { sm.checkSystemClipboardAccess(); } } catch (Exception e) { Thread currentThread = Thread.currentThread(); currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e); return null; } Long lFormat = null; Transferable localTransferable = local; if (localTransferable != null) { return localTransferable.getTransferData(df); } if (dropStatus != STATUS_ACCEPT || dropComplete) { throw new InvalidDnDOperationException("No drop current"); } Map flavorMap = DataTransferer.getInstance().getFlavorsForFormats (currentT, DataTransferer.adaptFlavorMap (currentDT.getFlavorMap())); lFormat = (Long)flavorMap.get(df); if (lFormat == null) { throw new UnsupportedFlavorException(df); } if (df.isRepresentationClassRemote() && currentDA != DnDConstants.ACTION_LINK) { throw new InvalidDnDOperationException("only ACTION_LINK is permissable for transfer of java.rmi.Remote objects"); } final long format = lFormat.longValue(); Object ret = getNativeData(format); if (ret instanceof byte[]) { try { return DataTransferer.getInstance(). translateBytes((byte[])ret, df, format, this); } catch (IOException e) { throw new InvalidDnDOperationException(e.getMessage()); } } else if (ret instanceof InputStream) { try { return DataTransferer.getInstance(). translateStream((InputStream)ret, df, format, this); } catch (IOException e) { throw new InvalidDnDOperationException(e.getMessage()); } } else { throw new IOException("no native data was transfered"); } } protected abstract Object getNativeData(long format) throws IOException; /** * @return if the transfer is a local one */ public boolean isTransferableJVMLocal() { return local != null || getJVMLocalSourceTransferable() != null; } private int handleEnterMessage(final Component component, final int x, final int y, final int dropAction, final int actions, final long[] formats, final long nativeCtxt) { return postDropTargetEvent(component, x, y, dropAction, actions, formats, nativeCtxt, SunDropTargetEvent.MOUSE_ENTERED, SunDropTargetContextPeer.DISPATCH_SYNC); } /** * actual processing on EventQueue Thread */ protected void processEnterMessage(SunDropTargetEvent event) { Component c = (Component)event.getSource(); DropTarget dt = c.getDropTarget(); Point hots = event.getPoint(); local = getJVMLocalSourceTransferable(); if (currentDTC != null) { // some wreckage from last time currentDTC.removeNotify(); currentDTC = null; } if (c.isShowing() && dt != null && dt.isActive()) { currentDT = dt; currentDTC = currentDT.getDropTargetContext(); currentDTC.addNotify(this); currentA = dt.getDefaultActions(); try { ((DropTargetListener)dt).dragEnter(new DropTargetDragEvent(currentDTC, hots, currentDA, currentSA)); } catch (Exception e) { e.printStackTrace(); currentDA = DnDConstants.ACTION_NONE; } } else { currentDT = null; currentDTC = null; currentDA = DnDConstants.ACTION_NONE; currentSA = DnDConstants.ACTION_NONE; currentA = DnDConstants.ACTION_NONE; } } /** * upcall to handle exit messages */ private void handleExitMessage(final Component component, final long nativeCtxt) { /* * Even though the return value is irrelevant for this event, it is * dispatched synchronously to fix 4393148 properly. */ postDropTargetEvent(component, 0, 0, DnDConstants.ACTION_NONE, DnDConstants.ACTION_NONE, null, nativeCtxt, SunDropTargetEvent.MOUSE_EXITED, SunDropTargetContextPeer.DISPATCH_SYNC); } /** * */ protected void processExitMessage(SunDropTargetEvent event) { Component c = (Component)event.getSource(); DropTarget dt = c.getDropTarget(); DropTargetContext dtc = null; if (dt == null) { currentDT = null; currentT = null; if (currentDTC != null) { currentDTC.removeNotify(); } currentDTC = null; return; } if (dt != currentDT) { if (currentDTC != null) { currentDTC.removeNotify(); } currentDT = dt; currentDTC = dt.getDropTargetContext(); currentDTC.addNotify(this); } dtc = currentDTC; if (dt.isActive()) try { ((DropTargetListener)dt).dragExit(new DropTargetEvent(dtc)); } catch (Exception e) { e.printStackTrace(); } finally { currentA = DnDConstants.ACTION_NONE; currentSA = DnDConstants.ACTION_NONE; currentDA = DnDConstants.ACTION_NONE; currentDT = null; currentT = null; currentDTC.removeNotify(); currentDTC = null; local = null; dragRejected = false; } } private int handleMotionMessage(final Component component, final int x, final int y, final int dropAction, final int actions, final long[] formats, final long nativeCtxt) { return postDropTargetEvent(component, x, y, dropAction, actions, formats, nativeCtxt, SunDropTargetEvent.MOUSE_DRAGGED, SunDropTargetContextPeer.DISPATCH_SYNC); } /** * */ protected void processMotionMessage(SunDropTargetEvent event, boolean operationChanged) { Component c = (Component)event.getSource(); Point hots = event.getPoint(); int id = event.getID(); DropTarget dt = c.getDropTarget(); DropTargetContext dtc = null; if (c.isShowing() && (dt != null) && dt.isActive()) { if (currentDT != dt) { if (currentDTC != null) { currentDTC.removeNotify(); } currentDT = dt; currentDTC = null; } dtc = currentDT.getDropTargetContext(); if (dtc != currentDTC) { if (currentDTC != null) { currentDTC.removeNotify(); } currentDTC = dtc; currentDTC.addNotify(this); } currentA = currentDT.getDefaultActions(); try { DropTargetDragEvent dtde = new DropTargetDragEvent(dtc, hots, currentDA, currentSA); DropTargetListener dtl = (DropTargetListener)dt; if (operationChanged) { dtl.dropActionChanged(dtde); } else { dtl.dragOver(dtde); } if (dragRejected) { currentDA = DnDConstants.ACTION_NONE; } } catch (Exception e) { e.printStackTrace(); currentDA = DnDConstants.ACTION_NONE; } } else { currentDA = DnDConstants.ACTION_NONE; } } /** * upcall to handle the Drop message */ private void handleDropMessage(final Component component, final int x, final int y, final int dropAction, final int actions, final long[] formats, final long nativeCtxt) { postDropTargetEvent(component, x, y, dropAction, actions, formats, nativeCtxt, SunDropTargetEvent.MOUSE_DROPPED,Lines 1–500 of 924. Load more
/* * Copyright (c) 2000, 2010, 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 sun.awt.dnd; import java.awt.Component; import java.awt.Point; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetContext; import java.awt.dnd.DropTargetListener; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.InvalidDnDOperationException; import java.awt.dnd.peer.DropTargetContextPeer; import java.util.HashSet; import java.util.Map; import java.util.Arrays; import sun.util.logging.PlatformLogger; import java.io.IOException; import java.io.InputStream; import sun.awt.AppContext; import sun.awt.SunToolkit; import sun.awt.datatransfer.DataTransferer; import sun.awt.datatransfer.ToolkitThreadBlockedHandler; import sun.security.util.SecurityConstants; /** * <p> * The SunDropTargetContextPeer class is the generic class responsible for handling * the interaction between a windowing systems DnD system and Java. * </p> * * @since JDK1.3.1 * */ public abstract class SunDropTargetContextPeer implements DropTargetContextPeer, Transferable { /* * A boolean constant that requires the peer to wait until the * SunDropTargetEvent is processed and return the status back * to the native code. */ public static final boolean DISPATCH_SYNC = true; private DropTarget currentDT; private DropTargetContext currentDTC; private long[] currentT; private int currentA; // target actions private int currentSA; // source actions private int currentDA; // current drop action private int previousDA; private long nativeDragContext; private Transferable local; private boolean dragRejected = false; protected int dropStatus = STATUS_NONE; protected boolean dropComplete = false; // The flag is used to monitor whether the drop action is // handled by a user. That allows to distinct during // which operation getTransferData() method is invoked. boolean dropInProcess = false; /* * global lock */ protected static final Object _globalLock = new Object(); private static final PlatformLogger dndLog = PlatformLogger.getLogger("sun.awt.dnd.SunDropTargetContextPeer"); /* * a primitive mechanism for advertising intra-JVM Transferables */ protected static Transferable currentJVMLocalSourceTransferable = null; public static void setCurrentJVMLocalSourceTransferable(Transferable t) throws InvalidDnDOperationException { synchronized(_globalLock) { if (t != null && currentJVMLocalSourceTransferable != null) { throw new InvalidDnDOperationException(); } else { currentJVMLocalSourceTransferable = t; } } } /** * obtain the transferable iff the operation is in the same VM */ private static Transferable getJVMLocalSourceTransferable() { return currentJVMLocalSourceTransferable; } /* * constants used by dropAccept() or dropReject() */ protected final static int STATUS_NONE = 0; // none pending protected final static int STATUS_WAIT = 1; // drop pending protected final static int STATUS_ACCEPT = 2; protected final static int STATUS_REJECT = -1; /** * create the peer */ public SunDropTargetContextPeer() { super(); } /** * @return the DropTarget associated with this peer */ public DropTarget getDropTarget() { return currentDT; } /** * @param actions set the current actions */ public synchronized void setTargetActions(int actions) { currentA = actions & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK); } /** * @return the current target actions */ public int getTargetActions() { return currentA; } /** * get the Transferable associated with the drop */ public Transferable getTransferable() { return this; } /** * @return current DataFlavors available */ // NOTE: This method may be called by privileged threads. // DO NOT INVOKE CLIENT CODE ON THIS THREAD! public DataFlavor[] getTransferDataFlavors() { final Transferable localTransferable = local; if (localTransferable != null) { return localTransferable.getTransferDataFlavors(); } else { return DataTransferer.getInstance().getFlavorsForFormatsAsArray (currentT, DataTransferer.adaptFlavorMap (currentDT.getFlavorMap())); } } /** * @return if the flavor is supported */ public boolean isDataFlavorSupported(DataFlavor df) { Transferable localTransferable = local; if (localTransferable != null) { return localTransferable.isDataFlavorSupported(df); } else { return DataTransferer.getInstance().getFlavorsForFormats (currentT, DataTransferer.adaptFlavorMap (currentDT.getFlavorMap())). containsKey(df); } } /** * @return the data */ public Object getTransferData(DataFlavor df) throws UnsupportedFlavorException, IOException, InvalidDnDOperationException { SecurityManager sm = System.getSecurityManager(); try { if (!dropInProcess && sm != null) { sm.checkSystemClipboardAccess(); } } catch (Exception e) { Thread currentThread = Thread.currentThread(); currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e); return null; } Long lFormat = null; Transferable localTransferable = local; if (localTransferable != null) { return localTransferable.getTransferData(df); } if (dropStatus != STATUS_ACCEPT || dropComplete) { throw new InvalidDnDOperationException("No drop current"); } Map flavorMap = DataTransferer.getInstance().getFlavorsForFormats (currentT, DataTransferer.adaptFlavorMap (currentDT.getFlavorMap())); lFormat = (Long)flavorMap.get(df); if (lFormat == null) { throw new UnsupportedFlavorException(df); } if (df.isRepresentationClassRemote() && currentDA != DnDConstants.ACTION_LINK) { throw new InvalidDnDOperationException("only ACTION_LINK is permissable for transfer of java.rmi.Remote objects"); } final long format = lFormat.longValue(); Object ret = getNativeData(format); if (ret instanceof byte[]) { try { return DataTransferer.getInstance(). translateBytes((byte[])ret, df, format, this); } catch (IOException e) { throw new InvalidDnDOperationException(e.getMessage()); } } else if (ret instanceof InputStream) { try { return DataTransferer.getInstance(). translateStream((InputStream)ret, df, format, this); } catch (IOException e) { throw new InvalidDnDOperationException(e.getMessage()); } } else { throw new IOException("no native data was transfered"); } } protected abstract Object getNativeData(long format) throws IOException; /** * @return if the transfer is a local one */ public boolean isTransferableJVMLocal() { return local != null || getJVMLocalSourceTransferable() != null; } private int handleEnterMessage(final Component component, final int x, final int y, final int dropAction, final int actions, final long[] formats, final long nativeCtxt) { return postDropTargetEvent(component, x, y, dropAction, actions, formats, nativeCtxt, SunDropTargetEvent.MOUSE_ENTERED, SunDropTargetContextPeer.DISPATCH_SYNC); } /** * actual processing on EventQueue Thread */ protected void processEnterMessage(SunDropTargetEvent event) { Component c = (Component)event.getSource(); DropTarget dt = c.getDropTarget(); Point hots = event.getPoint(); local = getJVMLocalSourceTransferable(); if (currentDTC != null) { // some wreckage from last time currentDTC.removeNotify(); currentDTC = null; } if (c.isShowing() && dt != null && dt.isActive()) { currentDT = dt; currentDTC = currentDT.getDropTargetContext(); currentDTC.addNotify(this); currentA = dt.getDefaultActions(); try { ((DropTargetListener)dt).dragEnter(new DropTargetDragEvent(currentDTC, hots, currentDA, currentSA)); } catch (Exception e) { e.printStackTrace(); currentDA = DnDConstants.ACTION_NONE; } } else { currentDT = null; currentDTC = null; currentDA = DnDConstants.ACTION_NONE; currentSA = DnDConstants.ACTION_NONE; currentA = DnDConstants.ACTION_NONE; } } /** * upcall to handle exit messages */ private void handleExitMessage(final Component component, final long nativeCtxt) { /* * Even though the return value is irrelevant for this event, it is * dispatched synchronously to fix 4393148 properly. */ postDropTargetEvent(component, 0, 0, DnDConstants.ACTION_NONE, DnDConstants.ACTION_NONE, null, nativeCtxt, SunDropTargetEvent.MOUSE_EXITED, SunDropTargetContextPeer.DISPATCH_SYNC); } /** * */ protected void processExitMessage(SunDropTargetEvent event) { Component c = (Component)event.getSource(); DropTarget dt = c.getDropTarget(); DropTargetContext dtc = null; if (dt == null) { currentDT = null; currentT = null; if (currentDTC != null) { currentDTC.removeNotify(); } currentDTC = null; return; } if (dt != currentDT) { if (currentDTC != null) { currentDTC.removeNotify(); } currentDT = dt; currentDTC = dt.getDropTargetContext(); currentDTC.addNotify(this); } dtc = currentDTC; if (dt.isActive()) try { ((DropTargetListener)dt).dragExit(new DropTargetEvent(dtc)); } catch (Exception e) { e.printStackTrace(); } finally { currentA = DnDConstants.ACTION_NONE; currentSA = DnDConstants.ACTION_NONE; currentDA = DnDConstants.ACTION_NONE; currentDT = null; currentT = null; currentDTC.removeNotify(); currentDTC = null; local = null; dragRejected = false; } } private int handleMotionMessage(final Component component, final int x, final int y, final int dropAction, final int actions, final long[] formats, final long nativeCtxt) { return postDropTargetEvent(component, x, y, dropAction, actions, formats, nativeCtxt, SunDropTargetEvent.MOUSE_DRAGGED, SunDropTargetContextPeer.DISPATCH_SYNC); } /** * */ protected void processMotionMessage(SunDropTargetEvent event, boolean operationChanged) { Component c = (Component)event.getSource(); Point hots = event.getPoint(); int id = event.getID(); DropTarget dt = c.getDropTarget(); DropTargetContext dtc = null; if (c.isShowing() && (dt != null) && dt.isActive()) { if (currentDT != dt) { if (currentDTC != null) { currentDTC.removeNotify(); } currentDT = dt; currentDTC = null; } dtc = currentDT.getDropTargetContext(); if (dtc != currentDTC) { if (currentDTC != null) { currentDTC.removeNotify(); } currentDTC = dtc; currentDTC.addNotify(this); } currentA = currentDT.getDefaultActions(); try { DropTargetDragEvent dtde = new DropTargetDragEvent(dtc, hots, currentDA, currentSA); DropTargetListener dtl = (DropTargetListener)dt; if (operationChanged) { dtl.dropActionChanged(dtde); } else { dtl.dragOver(dtde); } if (dragRejected) { currentDA = DnDConstants.ACTION_NONE; } } catch (Exception e) { e.printStackTrace(); currentDA = DnDConstants.ACTION_NONE; } } else { currentDA = DnDConstants.ACTION_NONE; } } /** * upcall to handle the Drop message */ private void handleDropMessage(final Component component, final int x, final int y, final int dropAction, final int actions, final long[] formats, final long nativeCtxt) { postDropTargetEvent(component, x, y, dropAction, actions, formats, nativeCtxt, SunDropTargetEvent.MOUSE_DROPPED,