4874070: invoking DragSource's startDrag with an Image renders no image on drag
Reviewed-by: art, denis, alexp
This commit is contained in:
parent
79b63384b2
commit
fa9fcae42b
@ -179,6 +179,8 @@ FILES_cpp = \
|
||||
awt_Mlib.cpp \
|
||||
awt_new.cpp \
|
||||
awt_TrayIcon.cpp \
|
||||
awt_DCHolder.cpp \
|
||||
awt_ole.cpp \
|
||||
ShaderList.cpp \
|
||||
D3DBlitLoops.cpp \
|
||||
D3DBufImgOps.cpp \
|
||||
|
@ -249,13 +249,14 @@ ifeq ($(PLATFORM), windows)
|
||||
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv WINDOWS
|
||||
OTHER_LDLIBS = kernel32.lib user32.lib gdi32.lib winspool.lib \
|
||||
imm32.lib ole32.lib uuid.lib shell32.lib \
|
||||
comdlg32.lib winmm.lib comctl32.lib delayimp.lib \
|
||||
comdlg32.lib winmm.lib comctl32.lib \
|
||||
shlwapi.lib delayimp.lib \
|
||||
$(JVMLIB) \
|
||||
/DELAYLOAD:user32.dll /DELAYLOAD:gdi32.dll \
|
||||
/DELAYLOAD:shell32.dll /DELAYLOAD:winmm.dll \
|
||||
/DELAYLOAD:winspool.drv /DELAYLOAD:imm32.dll \
|
||||
/DELAYLOAD:ole32.dll /DELAYLOAD:comdlg32.dll \
|
||||
/DELAYLOAD:comctl32.dll
|
||||
/DELAYLOAD:comctl32.dll /DELAYLOAD:shlwapi.dll
|
||||
|
||||
clean:: awt.clean
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2009 Sun Microsystems, Inc. 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
|
||||
@ -627,6 +627,69 @@ public class TransferHandler implements Serializable {
|
||||
this(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* image for the {@code startDrag} method
|
||||
*
|
||||
* @see java.awt.dnd.DragGestureEvent#startDrag(Cursor dragCursor, Image dragImage, Point imageOffset, Transferable transferable, DragSourceListener dsl)
|
||||
*/
|
||||
private Image dragImage;
|
||||
|
||||
/**
|
||||
* anchor offset for the {@code startDrag} method
|
||||
*
|
||||
* @see java.awt.dnd.DragGestureEvent#startDrag(Cursor dragCursor, Image dragImage, Point imageOffset, Transferable transferable, DragSourceListener dsl)
|
||||
*/
|
||||
private Point dragImageOffset;
|
||||
|
||||
/**
|
||||
* Sets the drag image parameter. The image has to be prepared
|
||||
* for rendering by the moment of the call. The image is stored
|
||||
* by reference because of some performance reasons.
|
||||
*
|
||||
* @param img an image to drag
|
||||
*/
|
||||
public void setDragImage(Image img) {
|
||||
dragImage = img;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the drag image. If there is no image to drag,
|
||||
* the returned value is {@code null}.
|
||||
*
|
||||
* @return the reference to the drag image
|
||||
*/
|
||||
public Image getDragImage() {
|
||||
return dragImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an anchor offset for the image to drag.
|
||||
* It can not be {@code null}.
|
||||
*
|
||||
* @param p a {@code Point} object that corresponds
|
||||
* to coordinates of an anchor offset of the image
|
||||
* relative to the upper left corner of the image
|
||||
*/
|
||||
public void setDragImageOffset(Point p) {
|
||||
dragImageOffset = new Point(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an anchor offset for the image to drag.
|
||||
*
|
||||
* @return a {@code Point} object that corresponds
|
||||
* to coordinates of an anchor offset of the image
|
||||
* relative to the upper left corner of the image.
|
||||
* The point {@code (0,0)} returns by default.
|
||||
*/
|
||||
public Point getDragImageOffset() {
|
||||
if (dragImageOffset == null) {
|
||||
return new Point(0,0);
|
||||
}
|
||||
return new Point(dragImageOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the Swing drag support to be initiated. This is called by
|
||||
* the various UI implementations in the <code>javax.swing.plaf.basic</code>
|
||||
@ -1522,7 +1585,12 @@ public class TransferHandler implements Serializable {
|
||||
scrolls = c.getAutoscrolls();
|
||||
c.setAutoscrolls(false);
|
||||
try {
|
||||
dge.startDrag(null, t, this);
|
||||
Image im = th.getDragImage();
|
||||
if (im == null) {
|
||||
dge.startDrag(null, t, this);
|
||||
} else {
|
||||
dge.startDrag(null, im, th.getDragImageOffset(), t, this);
|
||||
}
|
||||
return;
|
||||
} catch (RuntimeException re) {
|
||||
c.setAutoscrolls(scrolls);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2009 Sun Microsystems, Inc. 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
|
||||
@ -67,6 +67,8 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer
|
||||
private DragGestureEvent trigger;
|
||||
private Component component;
|
||||
private Cursor cursor;
|
||||
private Image dragImage;
|
||||
private Point dragImageOffset;
|
||||
private long nativeCtxt;
|
||||
private DragSourceContext dragSourceContext;
|
||||
private int sourceActions;
|
||||
@ -120,6 +122,8 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer
|
||||
dragSourceContext = dsc;
|
||||
cursor = c;
|
||||
sourceActions = getDragSourceContext().getSourceActions();
|
||||
dragImage = di;
|
||||
dragImageOffset = p;
|
||||
|
||||
Transferable transferable = getDragSourceContext().getTransferable();
|
||||
SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable
|
||||
@ -168,6 +172,31 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the drag image. If there is no image to drag,
|
||||
* the returned value is {@code null}
|
||||
*
|
||||
* @return the reference to the drag image
|
||||
*/
|
||||
public Image getDragImage() {
|
||||
return dragImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an anchor offset for the image to drag.
|
||||
*
|
||||
* @return a {@code Point} object that corresponds
|
||||
* to coordinates of an anchor offset of the image
|
||||
* relative to the upper left corner of the image.
|
||||
* The point {@code (0,0)} returns by default.
|
||||
*/
|
||||
public Point getDragImageOffset() {
|
||||
if (dragImageOffset == null) {
|
||||
return new Point(0,0);
|
||||
}
|
||||
return new Point(dragImageOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* downcall into native code
|
||||
*/
|
||||
@ -317,6 +346,8 @@ public abstract class SunDragSourceContextPeer implements DragSourceContextPeer
|
||||
|
||||
startSecondaryEventLoop();
|
||||
setNativeContext(0);
|
||||
dragImage = null;
|
||||
dragImageOffset = null;
|
||||
}
|
||||
|
||||
public static void setDragDropInProgress(boolean b)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2009 Sun Microsystems, Inc. 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
|
||||
@ -56,6 +56,7 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.File;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
@ -130,6 +131,10 @@ public class WDataTransferer extends DataTransferer {
|
||||
public static final long CF_PNG = registerClipboardFormat("PNG");
|
||||
public static final long CF_JFIF = registerClipboardFormat("JFIF");
|
||||
|
||||
public static final long CF_FILEGROUPDESCRIPTORW = registerClipboardFormat("FileGroupDescriptorW");
|
||||
public static final long CF_FILEGROUPDESCRIPTORA = registerClipboardFormat("FileGroupDescriptor");
|
||||
//CF_FILECONTENTS supported as mandatory associated clipboard
|
||||
|
||||
private static final Long L_CF_LOCALE = (Long)
|
||||
predefinedClipboardNameMap.get(predefinedClipboardNames[CF_LOCALE]);
|
||||
|
||||
@ -203,6 +208,30 @@ public class WDataTransferer extends DataTransferer {
|
||||
str = new HTMLCodec(str, EHTMLReadMode.HTML_READ_SELECTION);
|
||||
}
|
||||
|
||||
if (format == CF_FILEGROUPDESCRIPTORA || format == CF_FILEGROUPDESCRIPTORW) {
|
||||
if (null != str ) {
|
||||
str.close();
|
||||
}
|
||||
if (bytes == null || !DataFlavor.javaFileListFlavor.equals(flavor)) {
|
||||
throw new IOException("data translation failed");
|
||||
}
|
||||
String st = new String(bytes, 0, bytes.length, "UTF-16LE");
|
||||
String[] filenames = st.split("\0");
|
||||
if( 0 == filenames.length ){
|
||||
return null;
|
||||
}
|
||||
|
||||
// Convert the strings to File objects
|
||||
File[] files = new File[filenames.length];
|
||||
for (int i = 0; i < filenames.length; ++i) {
|
||||
files[i] = new File(filenames[i]);
|
||||
//They are temp-files from memory Stream, so they have to be removed on exit
|
||||
files[i].deleteOnExit();
|
||||
}
|
||||
// Turn the list of Files into a List and return
|
||||
return Arrays.asList(files);
|
||||
}
|
||||
|
||||
if (format == CFSTR_INETURL &&
|
||||
URL.class.equals(flavor.getRepresentationClass()))
|
||||
{
|
||||
@ -233,7 +262,7 @@ public class WDataTransferer extends DataTransferer {
|
||||
}
|
||||
|
||||
public boolean isFileFormat(long format) {
|
||||
return format == CF_HDROP;
|
||||
return format == CF_HDROP || format == CF_FILEGROUPDESCRIPTORA || format == CF_FILEGROUPDESCRIPTORW;
|
||||
}
|
||||
|
||||
protected Long getFormatForNativeAsLong(String str) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. 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
|
||||
@ -27,6 +27,10 @@ package sun.awt.windows;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
|
||||
import java.awt.datatransfer.Transferable;
|
||||
|
||||
@ -88,11 +92,56 @@ final class WDragSourceContextPeer extends SunDragSourceContextPeer {
|
||||
throw new InvalidDnDOperationException("failed to create native peer");
|
||||
}
|
||||
|
||||
setNativeContext(nativeCtxtLocal);
|
||||
int[] imageData = null;
|
||||
Point op = null;
|
||||
|
||||
Image im = getDragImage();
|
||||
int imageWidth = -1;
|
||||
int imageHeight = -1;
|
||||
if (im != null) {
|
||||
//image is ready (partial images are ok)
|
||||
try{
|
||||
imageWidth = im.getWidth(null);
|
||||
imageHeight = im.getHeight(null);
|
||||
if (imageWidth < 0 || imageHeight < 0) {
|
||||
throw new InvalidDnDOperationException("drag image is not ready");
|
||||
}
|
||||
//We could get an exception from user code here.
|
||||
//"im" and "dragImageOffset" are user-defined objects
|
||||
op = getDragImageOffset(); //op could not be null here
|
||||
BufferedImage bi = new BufferedImage(
|
||||
imageWidth,
|
||||
imageHeight,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
bi.getGraphics().drawImage(im, 0, 0, null);
|
||||
|
||||
//we can get out-of-memory here
|
||||
imageData = ((DataBufferInt)bi.getData().getDataBuffer()).getData();
|
||||
} catch (Throwable ex) {
|
||||
throw new InvalidDnDOperationException("drag image creation problem: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
//We shouldn't have user-level exceptions since now.
|
||||
//Any exception leads to corrupted D'n'D state.
|
||||
setNativeContext(nativeCtxtLocal);
|
||||
WDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(trans);
|
||||
|
||||
doDragDrop(getNativeContext(), getCursor());
|
||||
if (imageData != null) {
|
||||
doDragDrop(
|
||||
getNativeContext(),
|
||||
getCursor(),
|
||||
imageData,
|
||||
imageWidth, imageHeight,
|
||||
op.x, op.y);
|
||||
} else {
|
||||
doDragDrop(
|
||||
getNativeContext(),
|
||||
getCursor(),
|
||||
null,
|
||||
-1, -1,
|
||||
0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,7 +159,12 @@ final class WDragSourceContextPeer extends SunDragSourceContextPeer {
|
||||
* downcall into native code
|
||||
*/
|
||||
|
||||
native void doDragDrop(long nativeCtxt, Cursor cursor);
|
||||
native void doDragDrop(
|
||||
long nativeCtxt,
|
||||
Cursor cursor,
|
||||
int[] imageData,
|
||||
int imgWidth, int imgHight,
|
||||
int offsetX, int offsetY);
|
||||
|
||||
protected native void setNativeCursor(long nativeCtxt, Cursor c, int cType);
|
||||
|
||||
|
@ -895,6 +895,8 @@ public class WToolkit extends SunToolkit implements Runnable {
|
||||
Integer.valueOf(50));
|
||||
desktopProperties.put("DnD.Autoscroll.interval",
|
||||
Integer.valueOf(50));
|
||||
desktopProperties.put("DnD.isDragImageSupported",
|
||||
Boolean.TRUE);
|
||||
desktopProperties.put("Shell.shellFolderManager",
|
||||
"sun.awt.shell.Win32ShellFolderManager2");
|
||||
}
|
||||
|
@ -73,3 +73,5 @@ LOCALE=application/x-java-text-encoding;class="[B"
|
||||
UniformResourceLocator=application/x-java-url;class=java.net.URL
|
||||
UniformResourceLocator=text/uri-list;eoln="\r\n";terminators=1
|
||||
UniformResourceLocator=text/plain;eoln="\r\n";terminators=1
|
||||
FileGroupDescriptorW=application/x-java-file-list;class=java.util.List
|
||||
FileGroupDescriptor=application/x-java-file-list;class=java.util.List
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2009 Sun Microsystems, Inc. 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
|
||||
@ -233,4 +233,122 @@ extern JavaVM *jvm;
|
||||
#define CHECK_ISNOT_TOOLKIT_THREAD()
|
||||
#endif
|
||||
|
||||
|
||||
struct EnvHolder
|
||||
{
|
||||
JavaVM *m_pVM;
|
||||
JNIEnv *m_env;
|
||||
bool m_isOwner;
|
||||
EnvHolder(
|
||||
JavaVM *pVM,
|
||||
LPCSTR name = "COM holder",
|
||||
jint ver = JNI_VERSION_1_2)
|
||||
: m_pVM(pVM),
|
||||
m_env((JNIEnv *)JNU_GetEnv(pVM, ver)),
|
||||
m_isOwner(false)
|
||||
{
|
||||
if (NULL == m_env) {
|
||||
JavaVMAttachArgs attachArgs;
|
||||
attachArgs.version = ver;
|
||||
attachArgs.name = const_cast<char *>(name);
|
||||
attachArgs.group = NULL;
|
||||
jint status = m_pVM->AttachCurrentThread(
|
||||
(void**)&m_env,
|
||||
&attachArgs);
|
||||
m_isOwner = (NULL!=m_env);
|
||||
}
|
||||
}
|
||||
~EnvHolder() {
|
||||
if (m_isOwner) {
|
||||
m_pVM->DetachCurrentThread();
|
||||
}
|
||||
}
|
||||
operator bool() const { return NULL!=m_env; }
|
||||
bool operator !() const { return NULL==m_env; }
|
||||
operator JNIEnv*() const { return m_env; }
|
||||
JNIEnv* operator ->() const { return m_env; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class JLocalRef {
|
||||
JNIEnv* m_env;
|
||||
T m_localJRef;
|
||||
|
||||
public:
|
||||
JLocalRef(JNIEnv* env, T localJRef = NULL)
|
||||
: m_env(env),
|
||||
m_localJRef(localJRef)
|
||||
{}
|
||||
T Detach() {
|
||||
T ret = m_localJRef;
|
||||
m_localJRef = NULL;
|
||||
return ret;
|
||||
}
|
||||
void Attach(T newValue) {
|
||||
if (m_localJRef) {
|
||||
m_env->DeleteLocalRef((jobject)m_localJRef);
|
||||
}
|
||||
m_localJRef = newValue;
|
||||
}
|
||||
|
||||
operator T() { return m_localJRef; }
|
||||
operator bool() { return NULL!=m_localJRef; }
|
||||
bool operator !() { return NULL==m_localJRef; }
|
||||
|
||||
~JLocalRef() {
|
||||
if (m_localJRef) {
|
||||
m_env->DeleteLocalRef((jobject)m_localJRef);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef JLocalRef<jobject> JLObject;
|
||||
typedef JLocalRef<jstring> JLString;
|
||||
typedef JLocalRef<jclass> JLClass;
|
||||
|
||||
/*
|
||||
* Class to encapsulate the extraction of the java string contents
|
||||
* into a buffer and the cleanup of the buffer
|
||||
*/
|
||||
class JavaStringBuffer
|
||||
{
|
||||
protected:
|
||||
LPWSTR m_pStr;
|
||||
jsize m_dwSize;
|
||||
|
||||
public:
|
||||
JavaStringBuffer(jsize cbTCharCount) {
|
||||
m_dwSize = cbTCharCount;
|
||||
m_pStr = (LPWSTR)safe_Malloc( (m_dwSize+1)*sizeof(WCHAR) );
|
||||
}
|
||||
|
||||
JavaStringBuffer(JNIEnv *env, jstring text) {
|
||||
if (NULL == text) {
|
||||
m_pStr = L"";
|
||||
m_dwSize = 0;
|
||||
} else {
|
||||
m_dwSize = env->GetStringLength(text);
|
||||
m_pStr = (LPWSTR)safe_Malloc( (m_dwSize+1)*sizeof(WCHAR) );
|
||||
env->GetStringRegion(text, 0, m_dwSize, reinterpret_cast<jchar *>(m_pStr));
|
||||
m_pStr[m_dwSize] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
~JavaStringBuffer() {
|
||||
free(m_pStr);
|
||||
}
|
||||
|
||||
void Resize(jsize cbTCharCount) {
|
||||
m_dwSize = cbTCharCount;
|
||||
m_pStr = (LPWSTR)safe_Realloc(m_pStr, (m_dwSize+1)*sizeof(WCHAR) );
|
||||
}
|
||||
//we are in UNICODE now, so LPWSTR:=:LPTSTR
|
||||
operator LPWSTR() { return m_pStr; }
|
||||
operator LPARAM() { return (LPARAM)m_pStr; }
|
||||
void *GetData() { return (void *)m_pStr; }
|
||||
jsize GetSize() { return m_dwSize; }
|
||||
};
|
||||
|
||||
|
||||
#endif /* _AWT_H_ */
|
||||
|
107
jdk/src/windows/native/sun/windows/awt_DCHolder.cpp
Normal file
107
jdk/src/windows/native/sun/windows/awt_DCHolder.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
#include "awt.h"
|
||||
#include "awt_ole.h"
|
||||
#include "awt_DCHolder.h" // main symbols
|
||||
|
||||
|
||||
////////////////////////
|
||||
// struct DCHolder
|
||||
|
||||
DCHolder::DCHolder()
|
||||
: m_hMemoryDC(NULL),
|
||||
m_iWidth(0),
|
||||
m_iHeight(0),
|
||||
m_bForImage(FALSE),
|
||||
m_hBitmap(NULL),
|
||||
m_hOldBitmap(NULL),
|
||||
m_pPoints(NULL)
|
||||
{}
|
||||
|
||||
void DCHolder::Create(
|
||||
HDC hRelDC,
|
||||
int iWidth,
|
||||
int iHeght,
|
||||
BOOL bForImage
|
||||
){
|
||||
OLE_DECL
|
||||
m_iWidth = iWidth;
|
||||
m_iHeight = iHeght;
|
||||
m_bForImage = bForImage;
|
||||
m_hMemoryDC = ::CreateCompatibleDC(hRelDC);
|
||||
//NB: can not throw an error in non-safe stack!!! Just conversion and logging!
|
||||
//OLE_WINERROR2HR just set OLE_HR without any throw!
|
||||
if (!m_hMemoryDC) {
|
||||
OLE_THROW_LASTERROR(_T("CreateCompatibleDC"))
|
||||
}
|
||||
m_hBitmap = m_bForImage
|
||||
? CreateJavaContextBitmap(hRelDC, m_iWidth, m_iHeight, &m_pPoints)
|
||||
: ::CreateCompatibleBitmap(hRelDC, m_iWidth, m_iHeight);
|
||||
if (!m_hBitmap) {
|
||||
OLE_THROW_LASTERROR(_T("CreateCompatibleBitmap"))
|
||||
}
|
||||
m_hOldBitmap = (HBITMAP)::SelectObject(m_hMemoryDC, m_hBitmap);
|
||||
if (!m_hOldBitmap) {
|
||||
OLE_THROW_LASTERROR(_T("SelectBMObject"))
|
||||
}
|
||||
}
|
||||
|
||||
DCHolder::~DCHolder(){
|
||||
if (m_hOldBitmap) {
|
||||
::SelectObject(m_hMemoryDC, m_hOldBitmap);
|
||||
}
|
||||
if (m_hBitmap) {
|
||||
::DeleteObject(m_hBitmap);
|
||||
}
|
||||
if (m_hMemoryDC) {
|
||||
::DeleteDC(m_hMemoryDC);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
HBITMAP DCHolder::CreateJavaContextBitmap(
|
||||
HDC hdc,
|
||||
int iWidth,
|
||||
int iHeight,
|
||||
void **ppPoints)
|
||||
{
|
||||
BITMAPINFO bitmapInfo = {0};
|
||||
bitmapInfo.bmiHeader.biWidth = iWidth;
|
||||
bitmapInfo.bmiHeader.biHeight = -iHeight;
|
||||
bitmapInfo.bmiHeader.biPlanes = 1;
|
||||
bitmapInfo.bmiHeader.biBitCount = 32;
|
||||
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bitmapInfo.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
return ::CreateDIBSection(
|
||||
hdc,
|
||||
(BITMAPINFO *)&bitmapInfo,
|
||||
DIB_RGB_COLORS,
|
||||
(void **)ppPoints,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
}
|
72
jdk/src/windows/native/sun/windows/awt_DCHolder.h
Normal file
72
jdk/src/windows/native/sun/windows/awt_DCHolder.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
#ifndef _AWT_DCHolder_H
|
||||
#define _AWT_DCHolder_H
|
||||
|
||||
struct DCHolder
|
||||
{
|
||||
HDC m_hMemoryDC;
|
||||
int m_iWidth;
|
||||
int m_iHeight;
|
||||
BOOL m_bForImage;
|
||||
HBITMAP m_hBitmap;
|
||||
HBITMAP m_hOldBitmap;
|
||||
void *m_pPoints;
|
||||
|
||||
DCHolder();
|
||||
~DCHolder();
|
||||
|
||||
void Create(
|
||||
HDC hRelDC,
|
||||
int iWidth,
|
||||
int iHeght,
|
||||
BOOL bForImage);
|
||||
|
||||
operator HDC()
|
||||
{
|
||||
if (NULL == m_hOldBitmap && NULL != m_hBitmap) {
|
||||
m_hOldBitmap = (HBITMAP)::SelectObject(m_hMemoryDC, m_hBitmap);
|
||||
}
|
||||
return m_hMemoryDC;
|
||||
}
|
||||
|
||||
operator HBITMAP()
|
||||
{
|
||||
if (NULL != m_hOldBitmap) {
|
||||
m_hBitmap = (HBITMAP)::SelectObject(m_hMemoryDC, m_hOldBitmap);
|
||||
m_hOldBitmap = NULL;
|
||||
}
|
||||
return m_hBitmap;
|
||||
}
|
||||
|
||||
static HBITMAP CreateJavaContextBitmap(
|
||||
HDC hdc,
|
||||
int iWidth,
|
||||
int iHeight,
|
||||
void **ppPoints);
|
||||
};
|
||||
|
||||
#endif //_AWT_DCHolder_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. 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
|
||||
@ -23,7 +23,25 @@
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
#include "awt.h"
|
||||
#pragma push_macro("bad_alloc")
|
||||
//"bad_alloc" would be introduced in STL as "std::zbad_alloc" and discarded by linker
|
||||
//by this action we avoid the conflict with AWT implementation of "bad_alloc"
|
||||
//we need <new> inclusion for STL "new" oprators set.
|
||||
#define bad_alloc zbad_alloc
|
||||
#include <new>
|
||||
#pragma pop_macro("bad_alloc")
|
||||
//"bad_alloc" is undefined from here
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUG)
|
||||
extern void * operator new(size_t size, const char * filename, int linenumber);
|
||||
void * operator new(size_t size) {return operator new(size, "stl", 1);}
|
||||
#endif
|
||||
|
||||
#include <awt.h>
|
||||
#include <memory.h>
|
||||
#include <shlobj.h>
|
||||
#include <map>
|
||||
|
||||
#include "jlong.h"
|
||||
#include "awt_DataTransferer.h"
|
||||
#include "awt_DnDDS.h"
|
||||
@ -37,8 +55,14 @@
|
||||
#include "sun_awt_dnd_SunDragSourceContextPeer.h"
|
||||
#include "sun_awt_windows_WDragSourceContextPeer.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include <shlobj.h>
|
||||
#include "awt_ole.h"
|
||||
#include "awt_DCHolder.h"
|
||||
|
||||
bool operator < (const FORMATETC &fr, const FORMATETC &fl) {
|
||||
return memcmp(&fr, &fl, sizeof(FORMATETC)) < 0;
|
||||
}
|
||||
|
||||
typedef std::map<FORMATETC, STGMEDIUM> CDataMap;
|
||||
|
||||
#define GALLOCFLG (GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT)
|
||||
#define JAVA_BUTTON_MASK (java_awt_event_InputEvent_BUTTON1_DOWN_MASK | \
|
||||
@ -50,19 +74,155 @@ DWORD __cdecl convertActionsToDROPEFFECT(jint actions);
|
||||
jint __cdecl convertDROPEFFECTToActions(DWORD effects);
|
||||
}
|
||||
|
||||
class PictureDragHelper
|
||||
{
|
||||
private:
|
||||
static CDataMap st;
|
||||
static IDragSourceHelper *pHelper;
|
||||
public:
|
||||
static HRESULT Create(
|
||||
JNIEnv* env,
|
||||
jintArray imageData,
|
||||
int imageWidth,
|
||||
int imageHeight,
|
||||
int anchorX,
|
||||
int anchorY,
|
||||
IDataObject *pIDataObject)
|
||||
{
|
||||
if (NULL == imageData) {
|
||||
return S_FALSE;
|
||||
}
|
||||
OLE_TRY
|
||||
OLE_HRT( CoCreateInstance(
|
||||
CLSID_DragDropHelper,
|
||||
NULL,
|
||||
CLSCTX_ALL,
|
||||
IID_IDragSourceHelper,
|
||||
(LPVOID*)&pHelper))
|
||||
|
||||
jintArray ia = imageData;
|
||||
jsize iPointCoint = env->GetArrayLength(ia);
|
||||
|
||||
DCHolder ph;
|
||||
ph.Create(NULL, imageWidth, imageHeight, TRUE);
|
||||
env->GetIntArrayRegion(ia, 0, iPointCoint, (jint*)ph.m_pPoints);
|
||||
|
||||
SHDRAGIMAGE sdi;
|
||||
sdi.sizeDragImage.cx = imageWidth;
|
||||
sdi.sizeDragImage.cy = imageHeight;
|
||||
sdi.ptOffset.x = anchorX;
|
||||
sdi.ptOffset.y = anchorY;
|
||||
sdi.crColorKey = 0xFFFFFFFF;
|
||||
sdi.hbmpDragImage = ph;
|
||||
|
||||
// this call assures that the bitmap will be dragged around
|
||||
OLE_HR = pHelper->InitializeFromBitmap(
|
||||
&sdi,
|
||||
pIDataObject
|
||||
);
|
||||
// in case of an error we need to destroy the image, else the helper object takes ownership
|
||||
if (FAILED(OLE_HR)) {
|
||||
DeleteObject(sdi.hbmpDragImage);
|
||||
}
|
||||
OLE_CATCH
|
||||
OLE_RETURN_HR
|
||||
}
|
||||
|
||||
static void Destroy()
|
||||
{
|
||||
if (NULL!=pHelper) {
|
||||
CleanFormatMap();
|
||||
pHelper->Release();
|
||||
pHelper = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void CleanFormatMap()
|
||||
{
|
||||
for (CDataMap::iterator i = st.begin(); st.end() != i; i = st.erase(i)) {
|
||||
::ReleaseStgMedium(&i->second);
|
||||
}
|
||||
}
|
||||
static void SetData(const FORMATETC &format, const STGMEDIUM &medium)
|
||||
{
|
||||
CDataMap::iterator i = st.find(format);
|
||||
if (st.end() != i) {
|
||||
::ReleaseStgMedium(&i->second);
|
||||
i->second = medium;
|
||||
} else {
|
||||
st[format] = medium;
|
||||
}
|
||||
}
|
||||
static const FORMATETC *FindFormat(const FORMATETC &format)
|
||||
{
|
||||
static FORMATETC fm = {0};
|
||||
CDataMap::iterator i = st.find(format);
|
||||
if (st.end() != i) {
|
||||
return &i->first;
|
||||
}
|
||||
for (i = st.begin(); st.end() != i; ++i) {
|
||||
if (i->first.cfFormat==format.cfFormat) {
|
||||
return &i->first;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static STGMEDIUM *FindData(const FORMATETC &format)
|
||||
{
|
||||
CDataMap::iterator i = st.find(format);
|
||||
if (st.end() != i) {
|
||||
return &i->second;
|
||||
}
|
||||
for (i = st.begin(); st.end() != i; ++i) {
|
||||
const FORMATETC &f = i->first;
|
||||
if (f.cfFormat==format.cfFormat && (f.tymed == (f.tymed & format.tymed))) {
|
||||
return &i->second;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
CDataMap PictureDragHelper::st;
|
||||
IDragSourceHelper *PictureDragHelper::pHelper = NULL;
|
||||
|
||||
extern const CLIPFORMAT CF_PERFORMEDDROPEFFECT = ::RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT);
|
||||
extern const CLIPFORMAT CF_FILEGROUPDESCRIPTORW = ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW);
|
||||
extern const CLIPFORMAT CF_FILEGROUPDESCRIPTORA = ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTORA);
|
||||
extern const CLIPFORMAT CF_FILECONTENTS = ::RegisterClipboardFormat(CFSTR_FILECONTENTS);
|
||||
|
||||
typedef struct {
|
||||
AwtDragSource* dragSource;
|
||||
jobject cursor;
|
||||
jintArray imageData;
|
||||
jint imageWidth;
|
||||
jint imageHeight;
|
||||
jint x;
|
||||
jint y;
|
||||
} StartDragRec;
|
||||
|
||||
/**
|
||||
* StartDrag
|
||||
*/
|
||||
|
||||
void AwtDragSource::StartDrag(AwtDragSource* self, jobject cursor) {
|
||||
void AwtDragSource::StartDrag(
|
||||
AwtDragSource* self,
|
||||
jobject cursor,
|
||||
jintArray imageData,
|
||||
jint imageWidth,
|
||||
jint imageHeight,
|
||||
jint x,
|
||||
jint y)
|
||||
{
|
||||
StartDragRec* sdrp = new StartDragRec;
|
||||
sdrp->dragSource = self;
|
||||
sdrp->imageData = imageData;
|
||||
sdrp->cursor = cursor;
|
||||
sdrp->imageWidth = imageWidth;
|
||||
sdrp->imageHeight = imageHeight;
|
||||
sdrp->x = x;
|
||||
sdrp->y = y;
|
||||
|
||||
AwtToolkit::GetInstance().WaitForSingleObject(self->m_mutex);
|
||||
|
||||
@ -82,6 +242,17 @@ void AwtDragSource::_DoDragDrop(void* param) {
|
||||
JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
jobject peer = env->NewLocalRef(dragSource->GetPeer());
|
||||
|
||||
if (sdrp->imageData) {
|
||||
PictureDragHelper::Create(
|
||||
env,
|
||||
sdrp->imageData,
|
||||
sdrp->imageWidth,
|
||||
sdrp->imageHeight,
|
||||
sdrp->x,
|
||||
sdrp->y,
|
||||
(IDataObject*)dragSource);
|
||||
env->DeleteGlobalRef(sdrp->imageData);
|
||||
}
|
||||
dragSource->SetCursor(sdrp->cursor);
|
||||
env->DeleteGlobalRef(sdrp->cursor);
|
||||
delete sdrp;
|
||||
@ -116,6 +287,7 @@ void AwtDragSource::_DoDragDrop(void* param) {
|
||||
DASSERT(AwtDropTarget::IsCurrentDnDDataObject(dragSource));
|
||||
AwtDropTarget::SetCurrentDnDDataObject(NULL);
|
||||
|
||||
PictureDragHelper::Destroy();
|
||||
dragSource->Release();
|
||||
}
|
||||
|
||||
@ -268,7 +440,10 @@ void AwtDragSource::LoadCache(jlongArray formats) {
|
||||
idx++;
|
||||
|
||||
// now make a copy, but with a TYMED of HGLOBAL
|
||||
memcpy(m_types + idx, m_types + idx - 1, sizeof(FORMATETC));
|
||||
m_types[idx] = m_types[idx-1];
|
||||
m_types[idx].tymed = TYMED_HGLOBAL;
|
||||
idx++;
|
||||
break;
|
||||
case CF_HDROP:
|
||||
m_types[idx].tymed = TYMED_HGLOBAL;
|
||||
idx++;
|
||||
@ -348,6 +523,14 @@ AwtDragSource::MatchFormatEtc(FORMATETC __RPC_FAR *pFormatEtcIn,
|
||||
FORMATETC *cacheEnt) {
|
||||
TRY;
|
||||
|
||||
const FORMATETC *pFormat = PictureDragHelper::FindFormat(*pFormatEtcIn);
|
||||
if (NULL != pFormat) {
|
||||
if (NULL != cacheEnt) {
|
||||
*cacheEnt = *pFormat;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if ((pFormatEtcIn->tymed & (TYMED_HGLOBAL | TYMED_ISTREAM | TYMED_ENHMF |
|
||||
TYMED_MFPICT)) == 0) {
|
||||
return DV_E_TYMED;
|
||||
@ -357,8 +540,7 @@ AwtDragSource::MatchFormatEtc(FORMATETC __RPC_FAR *pFormatEtcIn,
|
||||
return DV_E_DVASPECT;
|
||||
}
|
||||
|
||||
FORMATETC tmp;
|
||||
memcpy(&tmp, pFormatEtcIn, sizeof(FORMATETC));
|
||||
FORMATETC tmp = *pFormatEtcIn;
|
||||
|
||||
static const DWORD supportedTymeds[] =
|
||||
{ TYMED_ISTREAM, TYMED_HGLOBAL, TYMED_ENHMF, TYMED_MFPICT };
|
||||
@ -367,22 +549,22 @@ AwtDragSource::MatchFormatEtc(FORMATETC __RPC_FAR *pFormatEtcIn,
|
||||
for (int i = 0; i < nSupportedTymeds; i++) {
|
||||
/*
|
||||
* Fix for BugTraq Id 4426805.
|
||||
* Match only if the tymed is supported by the requestor.
|
||||
* Match only if the tymed is supported by the requester.
|
||||
*/
|
||||
if ((pFormatEtcIn->tymed & supportedTymeds[i]) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp.tymed = supportedTymeds[i];
|
||||
FORMATETC *cp = (FORMATETC *)bsearch((const void *)&tmp,
|
||||
pFormat = (const FORMATETC *)bsearch((const void *)&tmp,
|
||||
(const void *)m_types,
|
||||
(size_t) m_ntypes,
|
||||
(size_t) sizeof(FORMATETC),
|
||||
_compar
|
||||
);
|
||||
if (cp != (FORMATETC *)NULL) {
|
||||
if (NULL != pFormat) {
|
||||
if (cacheEnt != (FORMATETC *)NULL) {
|
||||
memcpy(cacheEnt, cp, sizeof(FORMATETC));
|
||||
*cacheEnt = *pFormat;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
@ -481,7 +663,7 @@ HRESULT __stdcall AwtDragSource::QueryContinueDrag(BOOL fEscapeKeyPressed, DWOR
|
||||
|
||||
//CR 6480706 - MS Bug on hold
|
||||
HCURSOR hNeedCursor;
|
||||
if(
|
||||
if (
|
||||
m_bRestoreNodropCustomCursor &&
|
||||
m_cursor != NULL &&
|
||||
(hNeedCursor = m_cursor->GetHCursor()) != ::GetCursor() )
|
||||
@ -579,6 +761,19 @@ HRESULT __stdcall AwtDragSource::GiveFeedback(DWORD dwEffect) {
|
||||
HRESULT __stdcall AwtDragSource::GetData(FORMATETC __RPC_FAR *pFormatEtc,
|
||||
STGMEDIUM __RPC_FAR *pmedium) {
|
||||
TRY;
|
||||
STGMEDIUM *pPicMedia = PictureDragHelper::FindData(*pFormatEtc);
|
||||
if (NULL != pPicMedia) {
|
||||
*pmedium = *pPicMedia;
|
||||
//return outside, so AddRef the instance of pstm or hGlobal!
|
||||
if (pmedium->tymed == TYMED_ISTREAM) {
|
||||
pmedium->pstm->AddRef();
|
||||
pmedium->pUnkForRelease = (IUnknown *)NULL;
|
||||
} else if (pmedium->tymed == TYMED_HGLOBAL) {
|
||||
AddRef();
|
||||
pmedium->pUnkForRelease = (IDropSource *)this;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT res = GetProcessId(pFormatEtc, pmedium);
|
||||
if (res == S_OK) {
|
||||
@ -870,8 +1065,6 @@ HRESULT __stdcall AwtDragSource::GetCanonicalFormatEtc(FORMATETC __RPC_FAR *pFo
|
||||
*/
|
||||
|
||||
HRESULT __stdcall AwtDragSource::SetData(FORMATETC __RPC_FAR *pFormatEtc, STGMEDIUM __RPC_FAR *pmedium, BOOL fRelease) {
|
||||
static CLIPFORMAT CF_PERFORMEDDROPEFFECT = ::RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT);
|
||||
|
||||
if (pFormatEtc->cfFormat == CF_PERFORMEDDROPEFFECT && pmedium->tymed == TYMED_HGLOBAL) {
|
||||
m_dwPerformedDropEffect = *(DWORD*)::GlobalLock(pmedium->hGlobal);
|
||||
::GlobalUnlock(pmedium->hGlobal);
|
||||
@ -880,6 +1073,12 @@ HRESULT __stdcall AwtDragSource::SetData(FORMATETC __RPC_FAR *pFormatEtc, STGMED
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (fRelease) {
|
||||
//we are copying pmedium as a structure for further use, so no any release!
|
||||
PictureDragHelper::SetData(*pFormatEtc, *pmedium);
|
||||
return S_OK;
|
||||
}
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
@ -1538,12 +1737,28 @@ Java_sun_awt_windows_WDragSourceContextPeer_createDragSource(
|
||||
* doDragDrop
|
||||
*/
|
||||
|
||||
JNIEXPORT void JNICALL Java_sun_awt_windows_WDragSourceContextPeer_doDragDrop(JNIEnv* env, jobject self, jlong nativeCtxt, jobject cursor) {
|
||||
JNIEXPORT void JNICALL Java_sun_awt_windows_WDragSourceContextPeer_doDragDrop(
|
||||
JNIEnv* env,
|
||||
jobject self,
|
||||
jlong nativeCtxt,
|
||||
jobject cursor,
|
||||
jintArray imageData,
|
||||
jint imageWidth, jint imageHeight,
|
||||
jint x, jint y)
|
||||
{
|
||||
TRY;
|
||||
|
||||
cursor = env->NewGlobalRef(cursor);
|
||||
if (NULL != imageData) {
|
||||
imageData = (jintArray)env->NewGlobalRef(imageData);
|
||||
}
|
||||
|
||||
AwtDragSource::StartDrag((AwtDragSource*)nativeCtxt, cursor);
|
||||
AwtDragSource::StartDrag(
|
||||
(AwtDragSource*)nativeCtxt,
|
||||
cursor,
|
||||
imageData,
|
||||
imageWidth, imageHeight,
|
||||
x, y);
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. 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
|
||||
@ -84,7 +84,14 @@ class AwtDragSource : virtual public IDropSource, virtual public IDataObject {
|
||||
|
||||
// AwtDragSource
|
||||
|
||||
static void StartDrag(AwtDragSource* self, jobject cursor);
|
||||
static void StartDrag(
|
||||
AwtDragSource* self,
|
||||
jobject cursor,
|
||||
jintArray imageData,
|
||||
jint imageWidth,
|
||||
jint imageHeight,
|
||||
jint x,
|
||||
jint y);
|
||||
|
||||
HRESULT ChangeCursor();
|
||||
void SetCursor(jobject cursor);
|
||||
@ -268,4 +275,9 @@ class AwtDragSource : virtual public IDropSource, virtual public IDataObject {
|
||||
static jfieldID awtIEmods;
|
||||
};
|
||||
|
||||
extern const CLIPFORMAT CF_PERFORMEDDROPEFFECT;
|
||||
extern const CLIPFORMAT CF_FILEGROUPDESCRIPTORA;
|
||||
extern const CLIPFORMAT CF_FILEGROUPDESCRIPTORW;
|
||||
extern const CLIPFORMAT CF_FILECONTENTS;
|
||||
|
||||
#endif /* AWT_DND_DS_H */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. 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
|
||||
@ -24,24 +24,27 @@
|
||||
*/
|
||||
|
||||
#include "awt.h"
|
||||
#include <shlwapi.h>
|
||||
#include <shellapi.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "awt_DataTransferer.h"
|
||||
#include "awt_DnDDT.h"
|
||||
#include "awt_DnDDS.h"
|
||||
#include "awt_Toolkit.h"
|
||||
#include "java_awt_dnd_DnDConstants.h"
|
||||
#include "sun_awt_windows_WDropTargetContextPeer.h"
|
||||
#include "awt_Container.h"
|
||||
#include "alloc.h"
|
||||
#include "awt_ole.h"
|
||||
#include "awt_DnDDT.h"
|
||||
#include "awt_DnDDS.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
// forwards
|
||||
|
||||
extern "C" {
|
||||
DWORD __cdecl convertActionsToDROPEFFECT(jint actions);
|
||||
jint __cdecl convertDROPEFFECTToActions(DWORD effects);
|
||||
|
||||
DWORD __cdecl mapModsToDROPEFFECT(DWORD, DWORD);
|
||||
DWORD __cdecl convertActionsToDROPEFFECT(jint actions);
|
||||
jint __cdecl convertDROPEFFECTToActions(DWORD effects);
|
||||
DWORD __cdecl mapModsToDROPEFFECT(DWORD, DWORD);
|
||||
} // extern "C"
|
||||
|
||||
|
||||
@ -64,6 +67,7 @@ AwtDropTarget::AwtDropTarget(JNIEnv* env, AwtComponent* component) {
|
||||
m_dtcp = NULL;
|
||||
m_cfFormats = NULL;
|
||||
m_mutex = ::CreateMutex(NULL, FALSE, NULL);
|
||||
m_pIDropTargetHelper = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,6 +133,13 @@ ULONG __stdcall AwtDropTarget::Release() {
|
||||
|
||||
HRESULT __stdcall AwtDropTarget::DragEnter(IDataObject __RPC_FAR *pDataObj, DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect) {
|
||||
TRY;
|
||||
if (NULL != m_pIDropTargetHelper) {
|
||||
m_pIDropTargetHelper->DragEnter(
|
||||
m_window,
|
||||
pDataObj,
|
||||
(LPPOINT)&pt,
|
||||
*pdwEffect);
|
||||
}
|
||||
|
||||
AwtInterfaceLocker _lk(this);
|
||||
|
||||
@ -200,6 +211,12 @@ HRESULT __stdcall AwtDropTarget::DragEnter(IDataObject __RPC_FAR *pDataObj, DWOR
|
||||
|
||||
HRESULT __stdcall AwtDropTarget::DragOver(DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect) {
|
||||
TRY;
|
||||
if (NULL != m_pIDropTargetHelper) {
|
||||
m_pIDropTargetHelper->DragOver(
|
||||
(LPPOINT)&pt,
|
||||
*pdwEffect
|
||||
);
|
||||
}
|
||||
|
||||
AwtInterfaceLocker _lk(this);
|
||||
|
||||
@ -250,6 +267,9 @@ HRESULT __stdcall AwtDropTarget::DragOver(DWORD grfKeyState, POINTL pt, DWORD __
|
||||
|
||||
HRESULT __stdcall AwtDropTarget::DragLeave() {
|
||||
TRY_NO_VERIFY;
|
||||
if (NULL != m_pIDropTargetHelper) {
|
||||
m_pIDropTargetHelper->DragLeave();
|
||||
}
|
||||
|
||||
AwtInterfaceLocker _lk(this);
|
||||
|
||||
@ -288,7 +308,13 @@ HRESULT __stdcall AwtDropTarget::DragLeave() {
|
||||
|
||||
HRESULT __stdcall AwtDropTarget::Drop(IDataObject __RPC_FAR *pDataObj, DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect) {
|
||||
TRY;
|
||||
|
||||
if (NULL != m_pIDropTargetHelper) {
|
||||
m_pIDropTargetHelper->Drop(
|
||||
pDataObj,
|
||||
(LPPOINT)&pt,
|
||||
*pdwEffect
|
||||
);
|
||||
}
|
||||
AwtInterfaceLocker _lk(this);
|
||||
|
||||
JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
@ -410,9 +436,22 @@ void AwtDropTarget::RegisterTarget(WORD show) {
|
||||
// if we are'nt yet visible, defer until the parent is!
|
||||
|
||||
if (show) {
|
||||
res = ::RegisterDragDrop(m_window, (IDropTarget*)this);
|
||||
OLE_TRY
|
||||
OLE_HRT(CoCreateInstance(
|
||||
CLSID_DragDropHelper,
|
||||
NULL,
|
||||
CLSCTX_ALL,
|
||||
IID_IDropTargetHelper,
|
||||
(LPVOID*)&m_pIDropTargetHelper
|
||||
))
|
||||
OLE_HRT(::RegisterDragDrop(m_window, (IDropTarget*)this))
|
||||
OLE_CATCH
|
||||
res = OLE_HR;
|
||||
} else {
|
||||
res = ::RevokeDragDrop(m_window);
|
||||
if (NULL != m_pIDropTargetHelper) {
|
||||
m_pIDropTargetHelper->Release();
|
||||
}
|
||||
}
|
||||
|
||||
if (res == S_OK) m_registered = show;
|
||||
@ -454,303 +493,489 @@ void AwtDropTarget::_GetData(void* param) {
|
||||
* Returns the data object being transferred.
|
||||
*/
|
||||
|
||||
jobject AwtDropTarget::GetData(jlong fmt) {
|
||||
JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
if (env->EnsureLocalCapacity(1) < 0) {
|
||||
return (jobject)NULL;
|
||||
}
|
||||
|
||||
HRESULT AwtDropTarget::ExtractNativeData(
|
||||
jlong fmt,
|
||||
LONG lIndex,
|
||||
STGMEDIUM *pmedium)
|
||||
{
|
||||
FORMATETC format = { (unsigned short)fmt };
|
||||
STGMEDIUM stgmedium;
|
||||
HRESULT hResult = E_FAIL;
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
|
||||
static const DWORD supportedTymeds[] = { TYMED_ISTREAM, TYMED_ENHMF,
|
||||
TYMED_GDI, TYMED_MFPICT,
|
||||
TYMED_FILE, TYMED_HGLOBAL };
|
||||
static const int nSupportedTymeds = 6;
|
||||
|
||||
for (int i = 0; i < nSupportedTymeds; i++) {
|
||||
static const DWORD supportedTymeds[] = {
|
||||
TYMED_ISTREAM,
|
||||
TYMED_ENHMF,
|
||||
TYMED_GDI,
|
||||
TYMED_MFPICT,
|
||||
TYMED_FILE,
|
||||
TYMED_HGLOBAL
|
||||
};
|
||||
|
||||
for (int i = 0; i < sizeof(supportedTymeds)/sizeof(supportedTymeds[0]); ++i) {
|
||||
// Only TYMED_HGLOBAL is supported for CF_LOCALE.
|
||||
if (fmt == CF_LOCALE && supportedTymeds[i] != TYMED_HGLOBAL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
format.tymed = supportedTymeds[i];
|
||||
FORMATETC *cpp = (FORMATETC *)bsearch(
|
||||
(const void *)&format,
|
||||
(const void *)m_formats,
|
||||
(size_t)m_nformats,
|
||||
(size_t)sizeof(FORMATETC),
|
||||
_compar);
|
||||
|
||||
FORMATETC *cpp = (FORMATETC *)bsearch((const void *)&format,
|
||||
(const void *)m_formats,
|
||||
(size_t) m_nformats,
|
||||
(size_t) sizeof(FORMATETC),
|
||||
_compar
|
||||
);
|
||||
|
||||
if (cpp == (FORMATETC *)NULL) {
|
||||
if (NULL == cpp) {
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(&format, cpp, sizeof(FORMATETC));
|
||||
format = *cpp;
|
||||
format.lindex = lIndex;
|
||||
|
||||
hResult = m_dataObject->GetData(&format, &stgmedium);
|
||||
|
||||
if (hResult == S_OK) {
|
||||
break;
|
||||
hr = m_dataObject->GetData(&format, pmedium);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Failed to retrieve data.
|
||||
if (hResult != S_OK) {
|
||||
return (jobject)NULL;
|
||||
HRESULT CheckRetValue(
|
||||
JNIEnv* env,
|
||||
jobject ret)
|
||||
{
|
||||
if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
|
||||
return E_UNEXPECTED;
|
||||
} else if (JNU_IsNull(env, ret)) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
jobject AwtDropTarget::ConvertNativeData(JNIEnv* env, jlong fmt, STGMEDIUM *pmedium) /*throw std::bad_alloc */
|
||||
{
|
||||
jobject ret = NULL;
|
||||
jbyteArray paletteDataLocal = NULL;
|
||||
|
||||
switch (stgmedium.tymed) {
|
||||
HRESULT hr = S_OK;
|
||||
switch (pmedium->tymed) {
|
||||
case TYMED_HGLOBAL: {
|
||||
if (fmt == CF_LOCALE) {
|
||||
LCID *lcid = (LCID *)::GlobalLock(stgmedium.hGlobal);
|
||||
if (lcid == NULL) {
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
return NULL;
|
||||
LCID *lcid = (LCID *)::GlobalLock(pmedium->hGlobal);
|
||||
if (NULL == lcid) {
|
||||
hr = E_INVALIDARG;
|
||||
} else {
|
||||
try{
|
||||
ret = AwtDataTransferer::LCIDToTextEncoding(env, *lcid);
|
||||
hr = CheckRetValue(env, ret);
|
||||
} catch (std::bad_alloc&) {
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
::GlobalUnlock(pmedium->hGlobal);
|
||||
}
|
||||
try {
|
||||
ret = AwtDataTransferer::LCIDToTextEncoding(env, *lcid);
|
||||
} catch (...) {
|
||||
::GlobalUnlock(stgmedium.hGlobal);
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
throw;
|
||||
}
|
||||
::GlobalUnlock(stgmedium.hGlobal);
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
} else {
|
||||
::SetLastError(0); // clear error
|
||||
// Warning C4244.
|
||||
// Cast SIZE_T (__int64 on 64-bit/unsigned int on 32-bit)
|
||||
// to jsize (long).
|
||||
SIZE_T globalSize = ::GlobalSize(stgmedium.hGlobal);
|
||||
SIZE_T globalSize = ::GlobalSize(pmedium->hGlobal);
|
||||
jsize size = (globalSize <= INT_MAX) ? (jsize)globalSize : INT_MAX;
|
||||
if (size == 0 && ::GetLastError() != 0) {
|
||||
::SetLastError(0); // clear error
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
return (jobject)NULL; // failed
|
||||
hr = E_INVALIDARG;
|
||||
} else {
|
||||
jbyteArray bytes = env->NewByteArray(size);
|
||||
if (NULL == bytes) {
|
||||
hr = E_OUTOFMEMORY;
|
||||
} else {
|
||||
LPVOID data = ::GlobalLock(pmedium->hGlobal);
|
||||
if (NULL == data) {
|
||||
hr = E_INVALIDARG;
|
||||
} else {
|
||||
env->SetByteArrayRegion(bytes, 0, size, (jbyte *)data);
|
||||
ret = bytes;
|
||||
//bytes is not null here => no CheckRetValue call
|
||||
::GlobalUnlock(pmedium->hGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jbyteArray bytes = env->NewByteArray(size);
|
||||
if (bytes == NULL) {
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
LPVOID data = ::GlobalLock(stgmedium.hGlobal);
|
||||
env->SetByteArrayRegion(bytes, 0, size, (jbyte *)data);
|
||||
::GlobalUnlock(stgmedium.hGlobal);
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
|
||||
ret = bytes;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYMED_FILE: {
|
||||
jobject local = JNU_NewStringPlatform(env, stgmedium.lpszFileName);
|
||||
jobject local = JNU_NewStringPlatform(
|
||||
env,
|
||||
pmedium->lpszFileName);
|
||||
jstring fileName = (jstring)env->NewGlobalRef(local);
|
||||
env->DeleteLocalRef(local);
|
||||
|
||||
STGMEDIUM *stgm = NULL;
|
||||
try {
|
||||
//on success stgm would be deallocated by JAVA call freeStgMedium
|
||||
stgm = (STGMEDIUM *)safe_Malloc(sizeof(STGMEDIUM));
|
||||
memcpy(stgm, pmedium, sizeof(STGMEDIUM));
|
||||
// Warning C4311.
|
||||
// Cast pointer to jlong (__int64).
|
||||
ret = call_dTCgetfs(env, fileName, (jlong)stgm);
|
||||
hr = CheckRetValue(env, ret);
|
||||
} catch (std::bad_alloc&) {
|
||||
env->DeleteGlobalRef(fileName);
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
throw;
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(stgm, &stgmedium, sizeof(STGMEDIUM));
|
||||
|
||||
// Warning C4311.
|
||||
// Cast pointer to jlong (__int64).
|
||||
ret = call_dTCgetfs(env, fileName, (jlong)stgm);
|
||||
try {
|
||||
if (JNU_IsNull(env, ret) ||
|
||||
!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
|
||||
env->DeleteGlobalRef(fileName);
|
||||
free((void*)stgm);
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
return (jobject)NULL;
|
||||
}
|
||||
} catch (std::bad_alloc&) {
|
||||
if (FAILED(hr)) {
|
||||
//free just on error
|
||||
env->DeleteGlobalRef(fileName);
|
||||
free((void*)stgm);
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
throw;
|
||||
free(stgm);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TYMED_ISTREAM: {
|
||||
WDTCPIStreamWrapper* istream = new WDTCPIStreamWrapper(&stgmedium);
|
||||
|
||||
// Warning C4311.
|
||||
// Cast pointer to jlong (__int64).
|
||||
ret = call_dTCgetis(env, (jlong)istream);
|
||||
try {
|
||||
if (JNU_IsNull(env, ret) ||
|
||||
!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
|
||||
istream->Close();
|
||||
return (jobject)NULL;
|
||||
}
|
||||
} catch (std::bad_alloc&) {
|
||||
istream->Close();
|
||||
throw;
|
||||
}
|
||||
break;
|
||||
WDTCPIStreamWrapper* istream = NULL;
|
||||
try {
|
||||
istream = new WDTCPIStreamWrapper(pmedium);
|
||||
// Warning C4311.
|
||||
// Cast pointer to jlong (__int64).
|
||||
ret = call_dTCgetis(env, (jlong)istream);
|
||||
hr = CheckRetValue(env, ret);
|
||||
} catch (std::bad_alloc&) {
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
if (FAILED(hr) && NULL!=istream) {
|
||||
//free just on error
|
||||
istream->Close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TYMED_GDI:
|
||||
// Currently support only CF_PALETTE for TYMED_GDI.
|
||||
switch (fmt) {
|
||||
case CF_PALETTE: {
|
||||
ret = AwtDataTransferer::GetPaletteBytes(stgmedium.hBitmap,
|
||||
0, TRUE);
|
||||
break;
|
||||
if (CF_PALETTE == fmt) {
|
||||
ret = AwtDataTransferer::GetPaletteBytes(
|
||||
pmedium->hBitmap,
|
||||
0,
|
||||
TRUE);
|
||||
hr = CheckRetValue(env, ret);
|
||||
}
|
||||
}
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
break;
|
||||
case TYMED_MFPICT:
|
||||
case TYMED_ENHMF: {
|
||||
HENHMETAFILE hEnhMetaFile = NULL;
|
||||
LPBYTE lpEmfBits = NULL;
|
||||
|
||||
if (stgmedium.tymed == TYMED_MFPICT) {
|
||||
if (pmedium->tymed == TYMED_MFPICT ) {
|
||||
//let's create ENHMF from MFPICT to simplify treatment
|
||||
LPMETAFILEPICT lpMetaFilePict =
|
||||
(LPMETAFILEPICT)::GlobalLock(stgmedium.hMetaFilePict);
|
||||
UINT uSize = ::GetMetaFileBitsEx(lpMetaFilePict->hMF, 0, NULL);
|
||||
DASSERT(uSize != 0);
|
||||
|
||||
try {
|
||||
LPBYTE lpMfBits = (LPBYTE)safe_Malloc(uSize);
|
||||
VERIFY(::GetMetaFileBitsEx(lpMetaFilePict->hMF, uSize,
|
||||
lpMfBits) == uSize);
|
||||
hEnhMetaFile = ::SetWinMetaFileBits(uSize,
|
||||
lpMfBits,
|
||||
NULL,
|
||||
lpMetaFilePict);
|
||||
free(lpMfBits);
|
||||
} catch (...) {
|
||||
::GlobalUnlock(stgmedium.hMetaFilePict);
|
||||
throw;
|
||||
(LPMETAFILEPICT)::GlobalLock(pmedium->hMetaFilePict);
|
||||
if (NULL == lpMetaFilePict) {
|
||||
hr = E_INVALIDARG;
|
||||
} else {
|
||||
UINT uSize = ::GetMetaFileBitsEx(lpMetaFilePict->hMF, 0, NULL);
|
||||
if (0 == uSize) {
|
||||
hr = E_INVALIDARG;
|
||||
} else {
|
||||
try{
|
||||
LPBYTE lpMfBits = (LPBYTE)safe_Malloc(uSize);
|
||||
VERIFY(::GetMetaFileBitsEx(
|
||||
lpMetaFilePict->hMF,
|
||||
uSize,
|
||||
lpMfBits) == uSize);
|
||||
hEnhMetaFile = ::SetWinMetaFileBits(
|
||||
uSize,
|
||||
lpMfBits,
|
||||
NULL,
|
||||
lpMetaFilePict);
|
||||
free(lpMfBits);
|
||||
} catch (std::bad_alloc&) {
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
::GlobalUnlock(pmedium->hMetaFilePict);
|
||||
}
|
||||
::GlobalUnlock(stgmedium.hMetaFilePict);
|
||||
} else {
|
||||
hEnhMetaFile = stgmedium.hEnhMetaFile;
|
||||
hEnhMetaFile = pmedium->hEnhMetaFile;
|
||||
}
|
||||
|
||||
try {
|
||||
paletteDataLocal =
|
||||
AwtDataTransferer::GetPaletteBytes(hEnhMetaFile,
|
||||
OBJ_ENHMETAFILE,
|
||||
FALSE);
|
||||
if (NULL == hEnhMetaFile) {
|
||||
hr = E_INVALIDARG;
|
||||
} else {
|
||||
try {
|
||||
paletteDataLocal = AwtDataTransferer::GetPaletteBytes(
|
||||
hEnhMetaFile,
|
||||
OBJ_ENHMETAFILE,
|
||||
FALSE);
|
||||
//paletteDataLocal can be NULL here - it is not a error!
|
||||
|
||||
UINT uEmfSize = ::GetEnhMetaFileBits(hEnhMetaFile, 0, NULL);
|
||||
DASSERT(uEmfSize != 0);
|
||||
UINT uEmfSize = ::GetEnhMetaFileBits(hEnhMetaFile, 0, NULL);
|
||||
DASSERT(uEmfSize != 0);
|
||||
|
||||
lpEmfBits = (LPBYTE)safe_Malloc(uEmfSize);
|
||||
VERIFY(::GetEnhMetaFileBits(hEnhMetaFile, uEmfSize,
|
||||
lpEmfBits) == uEmfSize);
|
||||
LPBYTE lpEmfBits = (LPBYTE)safe_Malloc(uEmfSize);
|
||||
//no chance to throw exception before catch => no more try-blocks
|
||||
//and no leaks on lpEmfBits
|
||||
|
||||
if (stgmedium.tymed == TYMED_MFPICT) {
|
||||
::DeleteEnhMetaFile(hEnhMetaFile);
|
||||
} else {
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
}
|
||||
hEnhMetaFile = NULL;
|
||||
VERIFY(::GetEnhMetaFileBits(
|
||||
hEnhMetaFile,
|
||||
uEmfSize,
|
||||
lpEmfBits) == uEmfSize);
|
||||
|
||||
jbyteArray bytes = env->NewByteArray(uEmfSize);
|
||||
if (bytes == NULL) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
env->SetByteArrayRegion(bytes, 0, uEmfSize, (jbyte*)lpEmfBits);
|
||||
free(lpEmfBits);
|
||||
lpEmfBits = NULL;
|
||||
|
||||
ret = bytes;
|
||||
} catch (...) {
|
||||
if (!JNU_IsNull(env, paletteDataLocal)) {
|
||||
env->DeleteLocalRef(paletteDataLocal);
|
||||
paletteDataLocal = NULL;
|
||||
}
|
||||
if (hEnhMetaFile != NULL) {
|
||||
if (stgmedium.tymed == TYMED_MFPICT) {
|
||||
::DeleteEnhMetaFile(hEnhMetaFile);
|
||||
jbyteArray bytes = env->NewByteArray(uEmfSize);
|
||||
if (NULL == bytes) {
|
||||
hr = E_OUTOFMEMORY;
|
||||
} else {
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
env->SetByteArrayRegion(bytes, 0, uEmfSize, (jbyte*)lpEmfBits);
|
||||
ret = bytes;
|
||||
//bytes is not null here => no CheckRetValue call
|
||||
}
|
||||
hEnhMetaFile = NULL;
|
||||
}
|
||||
if (lpEmfBits != NULL) {
|
||||
free(lpEmfBits);
|
||||
lpEmfBits = NULL;
|
||||
} catch (std::bad_alloc&) {
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
if (pmedium->tymed == TYMED_MFPICT) {
|
||||
//because we create it manually
|
||||
::DeleteEnhMetaFile(hEnhMetaFile);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYMED_ISTORAGE:
|
||||
default:
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
return (jobject)NULL;
|
||||
hr = E_NOTIMPL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == NULL) {
|
||||
return (jobject)NULL;
|
||||
if (FAILED(hr)) {
|
||||
//clear exception garbage for hr = E_UNEXPECTED
|
||||
ret = NULL;
|
||||
} else {
|
||||
switch (fmt) {
|
||||
case CF_METAFILEPICT:
|
||||
case CF_ENHMETAFILE:
|
||||
// If we failed to retrieve palette entries from metafile,
|
||||
// fall through and try CF_PALETTE format.
|
||||
case CF_DIB: {
|
||||
if (JNU_IsNull(env, paletteDataLocal)) {
|
||||
jobject paletteData = GetData(CF_PALETTE);
|
||||
|
||||
if (JNU_IsNull(env, paletteData)) {
|
||||
paletteDataLocal =
|
||||
AwtDataTransferer::GetPaletteBytes(NULL, 0, TRUE);
|
||||
} else {
|
||||
// GetData() returns a global ref.
|
||||
// We want to deal with local ref.
|
||||
paletteDataLocal = (jbyteArray)env->NewLocalRef(paletteData);
|
||||
env->DeleteGlobalRef(paletteData);
|
||||
}
|
||||
}
|
||||
DASSERT(!JNU_IsNull(env, paletteDataLocal) &&
|
||||
!JNU_IsNull(env, ret));
|
||||
|
||||
jobject concat = AwtDataTransferer::ConcatData(env, paletteDataLocal, ret);
|
||||
env->DeleteLocalRef(ret);
|
||||
ret = concat;
|
||||
hr = CheckRetValue(env, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (fmt) {
|
||||
case CF_METAFILEPICT:
|
||||
case CF_ENHMETAFILE:
|
||||
// If we failed to retrieve palette entries from metafile,
|
||||
// fall through and try CF_PALETTE format.
|
||||
case CF_DIB: {
|
||||
if (JNU_IsNull(env, paletteDataLocal)) {
|
||||
jobject paletteData = GetData(CF_PALETTE);
|
||||
if (!JNU_IsNull(env, paletteDataLocal) ) {
|
||||
env->DeleteLocalRef(paletteDataLocal);
|
||||
}
|
||||
jobject global = NULL;
|
||||
if (SUCCEEDED(hr)) {
|
||||
global = env->NewGlobalRef(ret);
|
||||
env->DeleteLocalRef(ret);
|
||||
} else if (E_UNEXPECTED == hr) {
|
||||
//internal Java non-GPF exception
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
} else if (E_OUTOFMEMORY == hr) {
|
||||
throw std::bad_alloc();
|
||||
} //NULL returns for all other cases
|
||||
return global;
|
||||
}
|
||||
|
||||
if (JNU_IsNull(env, paletteData)) {
|
||||
paletteDataLocal =
|
||||
AwtDataTransferer::GetPaletteBytes(NULL, 0, TRUE);
|
||||
} else {
|
||||
// GetData() returns a global ref.
|
||||
// We want to deal with local ref.
|
||||
paletteDataLocal = (jbyteArray)env->NewLocalRef(paletteData);
|
||||
env->DeleteGlobalRef(paletteData);
|
||||
HRESULT AwtDropTarget::SaveIndexToFile(LPCTSTR pFileName, UINT lIndex)
|
||||
{
|
||||
OLE_TRY
|
||||
STGMEDIUM stgmedium;
|
||||
OLE_HRT( ExtractNativeData(CF_FILECONTENTS, lIndex, &stgmedium) );
|
||||
OLE_NEXT_TRY
|
||||
IStreamPtr spSrc;
|
||||
if (TYMED_HGLOBAL == stgmedium.tymed) {
|
||||
OLE_HRT( CreateStreamOnHGlobal(
|
||||
stgmedium.hGlobal,
|
||||
FALSE,
|
||||
&spSrc
|
||||
));
|
||||
} else if(TYMED_ISTREAM == stgmedium.tymed) {
|
||||
spSrc = stgmedium.pstm;
|
||||
}
|
||||
if (NULL == spSrc) {
|
||||
OLE_HRT(E_INVALIDARG);
|
||||
}
|
||||
IStreamPtr spDst;
|
||||
OLE_HRT(SHCreateStreamOnFile(
|
||||
pFileName,
|
||||
STGM_WRITE | STGM_CREATE,
|
||||
&spDst
|
||||
));
|
||||
STATSTG si = {0};
|
||||
OLE_HRT( spSrc->Stat(&si, STATFLAG_NONAME ) );
|
||||
OLE_HRT( spSrc->CopyTo(spDst, si.cbSize, NULL, NULL) );
|
||||
OLE_CATCH
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
OLE_CATCH
|
||||
OLE_RETURN_HR;
|
||||
}
|
||||
|
||||
|
||||
HRESULT GetTempPathWithSlash(JNIEnv *env, _bstr_t &bsTempPath) /*throws _com_error*/
|
||||
{
|
||||
static _bstr_t _bsPath;
|
||||
|
||||
OLE_TRY
|
||||
if (0 == _bsPath.length()) {
|
||||
BOOL bSafeEmergency = TRUE;
|
||||
TCHAR szPath[MAX_PATH*2];
|
||||
JLClass systemCls(env, env->FindClass("java/lang/System"));
|
||||
if (systemCls) {
|
||||
jmethodID idGetProperty = env->GetStaticMethodID(
|
||||
systemCls,
|
||||
"getProperty",
|
||||
"(Ljava/lang/String;)Ljava/lang/String;");
|
||||
if (0 != idGetProperty) {
|
||||
static TCHAR param[] = _T("java.io.tmpdir");
|
||||
JLString tempdir(env, JNU_NewStringPlatform(env, param));
|
||||
if (tempdir) {
|
||||
JLString jsTempPath(env, (jstring)env->CallStaticObjectMethod(
|
||||
systemCls,
|
||||
idGetProperty,
|
||||
(jstring)tempdir
|
||||
));
|
||||
if (jsTempPath) {
|
||||
_bsPath = (LPCWSTR)JavaStringBuffer(env, jsTempPath);
|
||||
OLE_HRT(SHGetFolderPath(
|
||||
NULL,
|
||||
CSIDL_WINDOWS,
|
||||
NULL,
|
||||
0,
|
||||
szPath));
|
||||
_tcscat(szPath, _T("\\"));
|
||||
//Dead environment block leads to fact that windows folder becomes temporary path.
|
||||
//For example while jtreg execution %TEMP%, %TMP% and etc. aren't defined.
|
||||
bSafeEmergency = ( 0 == _tcsicmp(_bsPath, szPath) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DASSERT(!JNU_IsNull(env, paletteDataLocal) &&
|
||||
!JNU_IsNull(env, ret));
|
||||
|
||||
jobject concat = AwtDataTransferer::ConcatData(env, paletteDataLocal, ret);
|
||||
|
||||
if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
env->DeleteLocalRef(ret);
|
||||
env->DeleteLocalRef(paletteDataLocal);
|
||||
return (jobject)NULL;
|
||||
if (bSafeEmergency) {
|
||||
OLE_HRT(SHGetFolderPath(
|
||||
NULL,
|
||||
CSIDL_INTERNET_CACHE|CSIDL_FLAG_CREATE,
|
||||
NULL,
|
||||
0,
|
||||
szPath));
|
||||
_tcscat(szPath, _T("\\"));
|
||||
_bsPath = szPath;
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(ret);
|
||||
env->DeleteLocalRef(paletteDataLocal);
|
||||
ret = concat;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
OLE_CATCH
|
||||
bsTempPath = _bsPath;
|
||||
OLE_RETURN_HR
|
||||
}
|
||||
|
||||
jobject global = env->NewGlobalRef(ret);
|
||||
env->DeleteLocalRef(ret);
|
||||
jobject AwtDropTarget::ConvertMemoryMappedData(JNIEnv* env, jlong fmt, STGMEDIUM *pmedium) /*throw std::bad_alloc */
|
||||
{
|
||||
jobject retObj = NULL;
|
||||
OLE_TRY
|
||||
if (TYMED_HGLOBAL != pmedium->tymed) {
|
||||
OLE_HRT(E_INVALIDARG);
|
||||
}
|
||||
FILEGROUPDESCRIPTORA *pfgdHead = (FILEGROUPDESCRIPTORA *)::GlobalLock(pmedium->hGlobal);
|
||||
if (NULL == pfgdHead) {
|
||||
OLE_HRT(E_INVALIDARG);
|
||||
}
|
||||
OLE_NEXT_TRY
|
||||
if (0 == pfgdHead->cItems) {
|
||||
OLE_HRT(E_INVALIDARG);
|
||||
}
|
||||
IStreamPtr spFileNames;
|
||||
OLE_HRT( CreateStreamOnHGlobal(
|
||||
NULL,
|
||||
TRUE,
|
||||
&spFileNames
|
||||
));
|
||||
|
||||
_bstr_t sbTempDir;
|
||||
OLE_HRT( GetTempPathWithSlash(env, sbTempDir) );
|
||||
FILEDESCRIPTORA *pfgdA = pfgdHead->fgd;
|
||||
FILEDESCRIPTORW *pfgdW = (FILEDESCRIPTORW *)pfgdA;
|
||||
for (UINT i = 0; i < pfgdHead->cItems; ++i) {
|
||||
_bstr_t stFullName(sbTempDir);
|
||||
if(CF_FILEGROUPDESCRIPTORA == fmt) {
|
||||
stFullName += pfgdA->cFileName; //as CHAR
|
||||
++pfgdA;
|
||||
} else {
|
||||
stFullName += pfgdW->cFileName; //as WCHAR
|
||||
++pfgdW;
|
||||
}
|
||||
OLE_HRT(SaveIndexToFile(
|
||||
stFullName,
|
||||
i));
|
||||
//write to stream with zero terminator
|
||||
OLE_HRT( spFileNames->Write((LPCTSTR)stFullName, (stFullName.length() + 1)*sizeof(TCHAR), NULL) );
|
||||
}
|
||||
OLE_HRT( spFileNames->Write(_T(""), sizeof(TCHAR), NULL) );
|
||||
STATSTG st;
|
||||
OLE_HRT( spFileNames->Stat(&st, STATFLAG_NONAME) );
|
||||
|
||||
//empty lists was forbidden: pfgdHead->cItems > 0
|
||||
jbyteArray bytes = env->NewByteArray(st.cbSize.LowPart);
|
||||
if (NULL == bytes) {
|
||||
OLE_HRT(E_OUTOFMEMORY);
|
||||
} else {
|
||||
HGLOBAL glob;
|
||||
OLE_HRT(GetHGlobalFromStream(spFileNames, &glob));
|
||||
jbyte *pFileListWithDoubleZeroTerminator = (jbyte *)::GlobalLock(glob);
|
||||
env->SetByteArrayRegion(bytes, 0, st.cbSize.LowPart, pFileListWithDoubleZeroTerminator);
|
||||
::GlobalUnlock(pFileListWithDoubleZeroTerminator);
|
||||
retObj = bytes;
|
||||
}
|
||||
//std::bad_alloc could happen in JStringBuffer
|
||||
//no leaks due to wrapper
|
||||
OLE_CATCH_BAD_ALLOC
|
||||
::GlobalUnlock(pmedium->hGlobal);
|
||||
OLE_CATCH
|
||||
jobject global = NULL;
|
||||
if (SUCCEEDED(OLE_HR)) {
|
||||
global = env->NewGlobalRef(retObj);
|
||||
env->DeleteLocalRef(retObj);
|
||||
} else if (E_OUTOFMEMORY == OLE_HR) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
return global;
|
||||
}
|
||||
|
||||
jobject AwtDropTarget::GetData(jlong fmt)
|
||||
{
|
||||
JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
if (env->EnsureLocalCapacity(1) < 0) {
|
||||
return (jobject)NULL;
|
||||
}
|
||||
jobject ret = NULL;
|
||||
OLE_TRY
|
||||
STGMEDIUM stgmedium;
|
||||
OLE_HRT( ExtractNativeData(fmt, -1, &stgmedium) );
|
||||
OLE_NEXT_TRY
|
||||
if (CF_FILEGROUPDESCRIPTORA == fmt ||
|
||||
CF_FILEGROUPDESCRIPTORW == fmt)
|
||||
{
|
||||
ret = ConvertMemoryMappedData(env, fmt, &stgmedium);
|
||||
} else {
|
||||
ret = ConvertNativeData(env, fmt, &stgmedium);
|
||||
}
|
||||
OLE_CATCH_BAD_ALLOC
|
||||
::ReleaseStgMedium(&stgmedium);
|
||||
OLE_CATCH
|
||||
if (E_OUTOFMEMORY == OLE_HR) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -791,14 +1016,14 @@ void AwtDropTarget::LoadCache(IDataObject* pDataObj) {
|
||||
ULONG actual = 1;
|
||||
|
||||
res = pEnumFormatEtc->Next((ULONG)1, &tmp, &actual);
|
||||
|
||||
if (res == S_FALSE) break;
|
||||
if (res == S_FALSE)
|
||||
break;
|
||||
|
||||
if (!(tmp.cfFormat >= 1 &&
|
||||
tmp.ptd == NULL &&
|
||||
tmp.lindex == -1 &&
|
||||
(tmp.lindex == -1 || CF_FILECONTENTS==tmp.cfFormat) &&
|
||||
tmp.dwAspect == DVASPECT_CONTENT &&
|
||||
(tmp.tymed == TYMED_HGLOBAL ||
|
||||
( tmp.tymed == TYMED_HGLOBAL ||
|
||||
tmp.tymed == TYMED_FILE ||
|
||||
tmp.tymed == TYMED_ISTREAM ||
|
||||
tmp.tymed == TYMED_GDI ||
|
||||
@ -806,7 +1031,8 @@ void AwtDropTarget::LoadCache(IDataObject* pDataObj) {
|
||||
tmp.tymed == TYMED_ENHMF
|
||||
) // but not ISTORAGE
|
||||
)
|
||||
) continue;
|
||||
)
|
||||
continue;
|
||||
|
||||
if (m_dataObject->QueryGetData(&tmp) != S_OK) continue;
|
||||
|
||||
@ -1005,6 +1231,7 @@ WDTCPIStreamWrapper::WDTCPIStreamWrapper(STGMEDIUM* stgmedium) {
|
||||
|
||||
m_stgmedium = *stgmedium;
|
||||
m_istream = stgmedium->pstm;
|
||||
m_istream->AddRef();
|
||||
m_mutex = ::CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
if (javaIOExceptionClazz == (jclass)NULL) {
|
||||
@ -1024,7 +1251,7 @@ WDTCPIStreamWrapper::WDTCPIStreamWrapper(STGMEDIUM* stgmedium) {
|
||||
|
||||
WDTCPIStreamWrapper::~WDTCPIStreamWrapper() {
|
||||
::CloseHandle(m_mutex);
|
||||
|
||||
m_istream->Release();
|
||||
::ReleaseStgMedium(&m_stgmedium);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2009 Sun Microsystems, Inc. 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
|
||||
@ -27,7 +27,7 @@
|
||||
#define AWT_DND_DT_H
|
||||
|
||||
#include <Ole2.h>
|
||||
|
||||
#include <shlobj.h>
|
||||
#include <jni.h>
|
||||
#include <jni_util.h>
|
||||
|
||||
@ -106,6 +106,11 @@ class AwtDropTarget : virtual public IDropTarget {
|
||||
|
||||
virtual void UnloadCache();
|
||||
|
||||
virtual HRESULT ExtractNativeData(jlong fmt, LONG lIndex, STGMEDIUM *pmedium);
|
||||
virtual HRESULT SaveIndexToFile(LPCTSTR pFileName, UINT lIndex);
|
||||
virtual jobject ConvertNativeData(JNIEnv* env, jlong fmt, STGMEDIUM *pmedium);
|
||||
virtual jobject ConvertMemoryMappedData(JNIEnv* env, jlong fmt, STGMEDIUM *pmedium);
|
||||
|
||||
private:
|
||||
typedef struct _RegisterTargetRec {
|
||||
AwtDropTarget* dropTarget;
|
||||
@ -152,11 +157,12 @@ class AwtDropTarget : virtual public IDropTarget {
|
||||
|
||||
// external COM references
|
||||
|
||||
IDataObject __RPC_FAR *m_dataObject;
|
||||
IDataObject *m_dataObject;
|
||||
IDropTargetHelper *m_pIDropTargetHelper;
|
||||
|
||||
// static members
|
||||
|
||||
static IDataObject __RPC_FAR *sm_pCurrentDnDDataObject;
|
||||
static IDataObject *sm_pCurrentDnDDataObject;
|
||||
|
||||
// method references
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2009 Sun Microsystems, Inc. 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
|
||||
@ -289,24 +289,6 @@ jmethodID AwtToolkit::getDefaultToolkitMID;
|
||||
jmethodID AwtToolkit::getFontMetricsMID;
|
||||
jmethodID AwtToolkit::insetsMID;
|
||||
|
||||
/************************************************************************
|
||||
* JavaStringBuffer method
|
||||
*/
|
||||
|
||||
JavaStringBuffer::JavaStringBuffer(JNIEnv *env, jstring jstr) {
|
||||
if (jstr != NULL) {
|
||||
int length = env->GetStringLength(jstr);
|
||||
buffer = new TCHAR[length + 1];
|
||||
LPCTSTR tmp = JNU_GetStringPlatformChars(env, jstr, NULL);
|
||||
_tcscpy(buffer, tmp);
|
||||
JNU_ReleaseStringPlatformChars(env, jstr, tmp);
|
||||
} else {
|
||||
buffer = new TCHAR[1];
|
||||
buffer[0] = _T('\0');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* AwtToolkit methods
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2009 Sun Microsystems, Inc. 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
|
||||
@ -466,20 +466,6 @@ public:
|
||||
void UninstallMouseLowLevelHook();
|
||||
};
|
||||
|
||||
/*
|
||||
* Class to encapsulate the extraction of the java string contents
|
||||
* into a buffer and the cleanup of the buffer
|
||||
*/
|
||||
class JavaStringBuffer {
|
||||
public:
|
||||
JavaStringBuffer(JNIEnv *env, jstring jstr);
|
||||
INLINE ~JavaStringBuffer() { delete[] buffer; }
|
||||
INLINE operator LPTSTR() { return buffer; }
|
||||
INLINE operator LPARAM() { return (LPARAM)buffer; } /* for SendMessage */
|
||||
|
||||
private:
|
||||
LPTSTR buffer;
|
||||
};
|
||||
|
||||
/* creates an instance of T and assigns it to the argument, but only if
|
||||
the argument is initially NULL. Supposed to be thread-safe.
|
||||
|
86
jdk/src/windows/native/sun/windows/awt_ole.cpp
Normal file
86
jdk/src/windows/native/sun/windows/awt_ole.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
#include "awt_ole.h"
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
|
||||
namespace SUN_DBG_NS{
|
||||
//WIN32 debug channel approach
|
||||
//inline void DbgOut(LPCTSTR lpStr) { ::OutputDebugString(lpStr); }
|
||||
|
||||
//Java debug channel approach
|
||||
inline void DbgOut(LPCTSTR lpStr) { DTRACE_PRINT(_B(lpStr)); }
|
||||
|
||||
LPCTSTR CreateTimeStamp(LPTSTR lpBuffer, size_t iBufferSize)
|
||||
{
|
||||
struct _timeb tb;
|
||||
_ftime(&tb);
|
||||
size_t len = _tcsftime(lpBuffer, iBufferSize, _T("%b %d %H:%M:%S"), localtime(&tb.time));
|
||||
if (len && len+4 < iBufferSize) {
|
||||
if (_sntprintf(lpBuffer+len, iBufferSize-len-1, _T(".%03d"), tb.millitm) < 0) {
|
||||
lpBuffer[iBufferSize-len-1] = 0;
|
||||
}
|
||||
}
|
||||
return lpBuffer;
|
||||
}
|
||||
|
||||
#define DTRACE_BUF_LEN 1024
|
||||
void snvTrace(LPCTSTR lpszFormat, va_list argList)
|
||||
{
|
||||
TCHAR szBuffer[DTRACE_BUF_LEN];
|
||||
if (_vsntprintf( szBuffer, DTRACE_BUF_LEN, lpszFormat, argList ) < 0) {
|
||||
szBuffer[DTRACE_BUF_LEN-1] = 0;
|
||||
}
|
||||
TCHAR szTime[32];
|
||||
CreateTimeStamp(szTime, sizeof(szTime));
|
||||
_tcscat(szTime, _T(" "));
|
||||
TCHAR szBuffer1[DTRACE_BUF_LEN];
|
||||
size_t iFormatLen = _tcslen(lpszFormat);
|
||||
BOOL bErrorReport = iFormatLen>6 && _tcscmp(lpszFormat + iFormatLen - 6, _T("[%08x]"))==0;
|
||||
size_t iTimeLen = _tcslen(szTime);
|
||||
if (_sntprintf(
|
||||
szBuffer1 + iTimeLen,
|
||||
DTRACE_BUF_LEN - iTimeLen - 1, //reserver for \n
|
||||
_T("P:%04d T:%04d ") TRACE_SUFFIX _T("%s%s"),
|
||||
::GetCurrentProcessId(),
|
||||
::GetCurrentThreadId(),
|
||||
bErrorReport?_T("Error:"):_T(""),
|
||||
szBuffer) < 0)
|
||||
{
|
||||
_tcscpy(szBuffer1 + DTRACE_BUF_LEN - 5, _T("...")); //reserver for \n
|
||||
}
|
||||
memcpy(szBuffer1, szTime, iTimeLen*sizeof(TCHAR));
|
||||
_tcscat(szBuffer1, _T("\n"));
|
||||
DbgOut( szBuffer1 );
|
||||
}
|
||||
void snTrace(LPCTSTR lpszFormat, ... )
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, lpszFormat);
|
||||
snvTrace(lpszFormat, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
}//SUN_DBG_NS namespace end
|
194
jdk/src/windows/native/sun/windows/awt_ole.h
Normal file
194
jdk/src/windows/native/sun/windows/awt_ole.h
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
#ifndef AWT_OLE_H
|
||||
#define AWT_OLE_H
|
||||
|
||||
#include "awt.h"
|
||||
#include <ole2.h>
|
||||
#include <comdef.h>
|
||||
#include <comutil.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define _SUN_DEBUG
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SUN_DBG_NS
|
||||
#ifdef _LIB
|
||||
#define SUN_DBG_NS SUN_dbg_lib
|
||||
#else
|
||||
#define SUN_DBG_NS SUN_dbg_glb
|
||||
#endif //_LIB
|
||||
#endif //SUN_DBG_NS
|
||||
|
||||
|
||||
#ifndef TRACE_SUFFIX
|
||||
#define TRACE_SUFFIX
|
||||
#endif
|
||||
|
||||
namespace SUN_DBG_NS{
|
||||
LPCTSTR CreateTimeStamp(LPTSTR lpBuffer, size_t iBufferSize);
|
||||
inline void snTraceEmp(LPCTSTR, ...) { }
|
||||
void snvTrace(LPCTSTR lpszFormat, va_list argList);
|
||||
void snTrace(LPCTSTR lpszFormat, ... );
|
||||
}//SUN_DBG_NS namespace end
|
||||
|
||||
#define STRACE1 SUN_DBG_NS::snTrace
|
||||
#ifdef _SUN_DEBUG
|
||||
#define STRACE SUN_DBG_NS::snTrace
|
||||
#else
|
||||
#define STRACE SUN_DBG_NS::snTraceEmp
|
||||
#endif
|
||||
#define STRACE0 SUN_DBG_NS::snTraceEmp
|
||||
|
||||
struct CLogEntryPoint1 {
|
||||
LPCTSTR m_lpTitle;
|
||||
CLogEntryPoint1(LPCTSTR lpTitle):m_lpTitle(lpTitle) { STRACE(_T("{%s"), m_lpTitle); }
|
||||
~CLogEntryPoint1(){ STRACE(_T("}%s"), m_lpTitle); }
|
||||
};
|
||||
struct CLogEntryPoint0 {
|
||||
LPCTSTR m_lpTitle;
|
||||
CLogEntryPoint0(LPCTSTR lpTitle):m_lpTitle(lpTitle) { STRACE0(_T("{%s"), m_lpTitle); }
|
||||
~CLogEntryPoint0(){ STRACE0(_T("}%s"), m_lpTitle); }
|
||||
};
|
||||
|
||||
#define SEP1(msg) CLogEntryPoint1 _ep1_(msg);
|
||||
#define SEP0(msg) CLogEntryPoint0 _ep0_(msg);
|
||||
#ifdef _SUN_DEBUG
|
||||
#define SEP(msg) CLogEntryPoint1 _ep1_(msg);
|
||||
#else
|
||||
#define SEP(msg) CLogEntryPoint0 _ep0_(msg);
|
||||
#endif
|
||||
|
||||
|
||||
#define OLE_BAD_COOKIE ((DWORD)-1)
|
||||
|
||||
#define OLE_TRACENOTIMPL(msg)\
|
||||
STRACE(_T("Warning:%s"), msg);\
|
||||
return E_NOTIMPL;
|
||||
|
||||
#define OLE_TRACEOK(msg)\
|
||||
STRACE0(_T("Info:%s"), msg);\
|
||||
return S_OK;
|
||||
|
||||
|
||||
#define OLE_DECL\
|
||||
HRESULT _hr_ = S_OK;
|
||||
|
||||
#define OLE_NEXT_TRY\
|
||||
try {
|
||||
|
||||
#define OLE_TRY\
|
||||
OLE_DECL\
|
||||
try {
|
||||
|
||||
#define OLE_HRT(fnc)\
|
||||
_hr_ = fnc;\
|
||||
if (FAILED(_hr_)) {\
|
||||
STRACE1(_T("Error:%08x in ") _T(#fnc), _hr_);\
|
||||
_com_raise_error(_hr_);\
|
||||
}
|
||||
|
||||
#define OLE_WINERROR2HR(msg, erCode)\
|
||||
_hr_ = erCode;\
|
||||
STRACE1(_T("OSError:%d in ") msg, _hr_);\
|
||||
_hr_ = HRESULT_FROM_WIN32(_hr_);
|
||||
|
||||
#define OLE_THROW_LASTERROR(msg)\
|
||||
OLE_WINERROR2HR(msg, ::GetLastError())\
|
||||
_com_raise_error(_hr_);
|
||||
|
||||
#define OLE_CHECK_NOTNULL(x)\
|
||||
if (!(x)) {\
|
||||
STRACE1(_T("Null pointer:") _T(#x));\
|
||||
_com_raise_error(_hr_ = E_POINTER);\
|
||||
}
|
||||
|
||||
#define OLE_CHECK_NOTNULLSP(x)\
|
||||
if (!bool(x)) {\
|
||||
STRACE1(_T("Null pointer:") _T(#x));\
|
||||
_com_raise_error(_hr_ = E_POINTER);\
|
||||
}
|
||||
|
||||
#define OLE_HRW32(fnc)\
|
||||
_hr_ = fnc;\
|
||||
if (ERROR_SUCCESS != _hr_) {\
|
||||
STRACE1(_T("OSError:%d in ") _T(#fnc), _hr_);\
|
||||
_com_raise_error(_hr_ = HRESULT_FROM_WIN32(_hr_));\
|
||||
}
|
||||
|
||||
#define OLE_HRW32_BOOL(fnc)\
|
||||
if (!fnc) {\
|
||||
OLE_THROW_LASTERROR(_T(#fnc))\
|
||||
}
|
||||
|
||||
#define OLE_CATCH\
|
||||
} catch (_com_error &e) {\
|
||||
_hr_ = e.Error();\
|
||||
STRACE1(_T("COM Error:%08x %s"), _hr_, e.ErrorMessage());\
|
||||
}
|
||||
|
||||
#define OLE_CATCH_BAD_ALLOC\
|
||||
} catch (_com_error &e) {\
|
||||
_hr_ = e.Error();\
|
||||
STRACE1(_T("COM Error:%08x %s"), _hr_, e.ErrorMessage());\
|
||||
} catch (std::bad_alloc&) {\
|
||||
_hr_ = E_OUTOFMEMORY;\
|
||||
STRACE1(_T("Error: Out of Memory"));\
|
||||
}
|
||||
|
||||
#define OLE_CATCH_ALL\
|
||||
} catch (_com_error &e) {\
|
||||
_hr_ = e.Error();\
|
||||
STRACE1(_T("COM Error:%08x %s"), _hr_, e.ErrorMessage());\
|
||||
} catch(...) {\
|
||||
_hr_ = E_FAIL;\
|
||||
STRACE1(_T("Error: General Pritection Failor"));\
|
||||
}
|
||||
|
||||
#define OLE_RETURN_SUCCESS return SUCCEEDED(_hr_);
|
||||
#define OLE_RETURN_HR return _hr_;
|
||||
#define OLE_HR _hr_
|
||||
|
||||
#define _B(x) _bstr_t(x)
|
||||
#define _BT(x) (LPCTSTR)_bstr_t(x)
|
||||
#define _V(x) _variant_t(x)
|
||||
#define _VV(vrt) _variant_t(vrt, false)
|
||||
#define _VE _variant_t()
|
||||
#define _VB(b) _variant_t(bool(b))
|
||||
|
||||
struct OLEHolder
|
||||
{
|
||||
OLEHolder()
|
||||
: m_hr(::OleInitialize(NULL))
|
||||
{}
|
||||
|
||||
~OLEHolder(){}
|
||||
operator bool() const { return S_OK==SUCCEEDED(m_hr); }
|
||||
HRESULT m_hr;
|
||||
};
|
||||
|
||||
#endif//AWT_OLE_H
|
@ -0,0 +1,20 @@
|
||||
<html>
|
||||
<!--
|
||||
@test
|
||||
@bug 6242241
|
||||
@summary Tests basic DnD functionality in an applet
|
||||
@author Your Name: Alexey Utkin area=dnd
|
||||
@run applet/manual=yesno DnDFileGroupDescriptor.html
|
||||
-->
|
||||
<head>
|
||||
<title> DnDToWordpadTest </title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>DnDFileGroupDescriptor<br>Bug ID: 6242241</h1>
|
||||
|
||||
<p> See the dialog box (usually in upper left corner) for instructions</p>
|
||||
|
||||
<APPLET CODE="DnDFileGroupDescriptor.class" WIDTH=200 HEIGHT=200></APPLET>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
test
|
||||
@bug 6242241
|
||||
@summary Tests basic DnD functionality in an applet
|
||||
@author Your Name: Alexey Utkin area=dnd
|
||||
@run applet/manual=yesno DnDFileGroupDescriptor.html
|
||||
*/
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.awt.*;
|
||||
|
||||
public class DnDFileGroupDescriptor extends Applet {
|
||||
public void init() {
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
String[] instructions = {
|
||||
"The applet window contains a red field.",
|
||||
"1. Start MS Outlook program. Find and open ",
|
||||
" the mail form with attachments.",
|
||||
"2. Select attachments from the mail and drag into a red field of applet.",
|
||||
" When the mouse enters the field during the drag, the application ",
|
||||
" should change the cursor form to OLE-copy and field color to yellow.",
|
||||
"3. Release the mouse button (drop attachments) over the field.",
|
||||
"",
|
||||
"File paths in temporary folder should appear.",
|
||||
"",
|
||||
"You should be able to repeat this operation multiple times.",
|
||||
"Please, select \"Pass\" just in case of success or \"Fail\" for another."
|
||||
};
|
||||
Sysout.createDialogWithInstructions( instructions );
|
||||
}
|
||||
|
||||
public void start() {
|
||||
Panel mainPanel;
|
||||
Component dropTarget;
|
||||
|
||||
mainPanel = new Panel();
|
||||
mainPanel.setLayout(new BorderLayout());
|
||||
|
||||
mainPanel.setBackground(Color.blue);
|
||||
dropTarget = new DnDTarget(Color.red, Color.yellow);
|
||||
|
||||
mainPanel.add(dropTarget, "Center");
|
||||
add(mainPanel);
|
||||
|
||||
setSize(200,200);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
Standard Test Machinery
|
||||
DO NOT modify anything below -- it's a standard
|
||||
chunk of code whose purpose is to make user
|
||||
interaction uniform, and thereby make it simpler
|
||||
to read and understand someone else's test.
|
||||
****************************************************/
|
||||
|
||||
class Sysout
|
||||
{
|
||||
private static TestDialog dialog;
|
||||
|
||||
public static void createDialogWithInstructions( String[] instructions )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
dialog.printInstructions( instructions );
|
||||
dialog.show();
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
public static void createDialog( )
|
||||
{
|
||||
dialog = new TestDialog( new Frame(), "Instructions" );
|
||||
String[] defInstr = { "Instructions will appear here. ", "" } ;
|
||||
dialog.printInstructions( defInstr );
|
||||
dialog.show();
|
||||
println( "Any messages for the tester will display here." );
|
||||
}
|
||||
|
||||
|
||||
public static void printInstructions( String[] instructions )
|
||||
{
|
||||
dialog.printInstructions( instructions );
|
||||
}
|
||||
|
||||
|
||||
public static void println( String messageIn )
|
||||
{
|
||||
dialog.displayMessage( messageIn );
|
||||
}
|
||||
|
||||
}// Sysout class
|
||||
|
||||
class TestDialog extends Dialog
|
||||
{
|
||||
|
||||
TextArea instructionsText;
|
||||
TextArea messageText;
|
||||
int maxStringLength = 80;
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public TestDialog( Frame frame, String name )
|
||||
{
|
||||
super( frame, name );
|
||||
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
|
||||
add( "North", instructionsText );
|
||||
|
||||
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
|
||||
add("South", messageText);
|
||||
|
||||
pack();
|
||||
|
||||
show();
|
||||
}// TestDialog()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void printInstructions( String[] instructions )
|
||||
{
|
||||
//Clear out any current instructions
|
||||
instructionsText.setText( "" );
|
||||
|
||||
//Go down array of instruction strings
|
||||
|
||||
String printStr, remainingStr;
|
||||
for( int i=0; i < instructions.length; i++ )
|
||||
{
|
||||
//chop up each into pieces maxSringLength long
|
||||
remainingStr = instructions[ i ];
|
||||
while( remainingStr.length() > 0 )
|
||||
{
|
||||
//if longer than max then chop off first max chars to print
|
||||
if( remainingStr.length() >= maxStringLength )
|
||||
{
|
||||
//Try to chop on a word boundary
|
||||
int posOfSpace = remainingStr.
|
||||
lastIndexOf( ' ', maxStringLength - 1 );
|
||||
|
||||
if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
|
||||
|
||||
printStr = remainingStr.substring( 0, posOfSpace + 1 );
|
||||
remainingStr = remainingStr.substring( posOfSpace + 1 );
|
||||
}
|
||||
//else just print
|
||||
else
|
||||
{
|
||||
printStr = remainingStr;
|
||||
remainingStr = "";
|
||||
}
|
||||
|
||||
instructionsText.append( printStr + "\n" );
|
||||
|
||||
}// while
|
||||
|
||||
}// for
|
||||
|
||||
}//printInstructions()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void displayMessage( String messageIn )
|
||||
{
|
||||
messageText.append( messageIn + "\n" );
|
||||
}
|
||||
|
||||
}// TestDialog class
|
108
jdk/test/java/awt/dnd/DnDFileGroupDescriptor/DnDTarget.java
Normal file
108
jdk/test/java/awt/dnd/DnDFileGroupDescriptor/DnDTarget.java
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Panel is a DropTarget
|
||||
*
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.dnd.*;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
class DnDTarget extends Panel implements DropTargetListener {
|
||||
//private int dragOperation = DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE;
|
||||
Color bgColor;
|
||||
Color htColor;
|
||||
|
||||
DnDTarget(Color bgColor, Color htColor) {
|
||||
super();
|
||||
setLayout(new FlowLayout());
|
||||
this.bgColor = bgColor;
|
||||
this.htColor = htColor;
|
||||
setBackground(bgColor);
|
||||
setDropTarget(new DropTarget(this, this));
|
||||
add(new Label("drop here"));
|
||||
}
|
||||
|
||||
boolean check(DropTargetDragEvent dtde)
|
||||
{
|
||||
if (dtde.getCurrentDataFlavorsAsList().contains(DataFlavor.javaFileListFlavor)) {
|
||||
dtde.acceptDrag(DnDConstants.ACTION_COPY);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void dragEnter(DropTargetDragEvent dtde) {
|
||||
if(check(dtde)){
|
||||
setBackground(htColor);
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public void dragOver(DropTargetDragEvent dtde) {
|
||||
check(dtde);
|
||||
}
|
||||
|
||||
public void dropActionChanged(DropTargetDragEvent dtde) {
|
||||
check(dtde);
|
||||
}
|
||||
|
||||
public void dragExit(DropTargetEvent e) {
|
||||
setBackground(bgColor);
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void dragScroll(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dragScroll");
|
||||
}
|
||||
|
||||
public void drop(DropTargetDropEvent dtde) {
|
||||
System.out.println("[Target] drop");
|
||||
boolean success = false;
|
||||
dtde.acceptDrop(DnDConstants.ACTION_COPY);
|
||||
if( dtde.getCurrentDataFlavorsAsList().contains(DataFlavor.javaFileListFlavor) ){
|
||||
System.out.println("[Target] DROP OK!");
|
||||
try {
|
||||
Transferable transfer = dtde.getTransferable();
|
||||
java.util.List<File> fl = (java.util.List<File>)transfer.getTransferData(DataFlavor.javaFileListFlavor);
|
||||
for(File f : fl){
|
||||
add(new Button(f.getCanonicalPath()));
|
||||
System.out.println("[Target] drop file:" + f.getCanonicalPath());
|
||||
}
|
||||
validate();
|
||||
} catch(Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
setBackground(bgColor);
|
||||
repaint();
|
||||
success = true;
|
||||
}
|
||||
dtde.dropComplete(success);
|
||||
}
|
||||
}
|
235
jdk/test/java/awt/dnd/ImageDecoratedDnD/DnDSource.java
Normal file
235
jdk/test/java/awt/dnd/ImageDecoratedDnD/DnDSource.java
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* AWT Button is a DragSource and also a transferable object
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.dnd.*;
|
||||
import java.io.*;
|
||||
|
||||
class DnDSource extends Button implements Transferable,
|
||||
DragGestureListener,
|
||||
DragSourceListener {
|
||||
private DataFlavor df;
|
||||
private transient int dropAction;
|
||||
private final int dragOperation = DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE | DnDConstants.ACTION_LINK;
|
||||
DragSource dragSource = new DragSource();
|
||||
|
||||
DnDSource(String label) {
|
||||
super(label);
|
||||
setBackground(Color.yellow);
|
||||
setForeground(Color.blue);
|
||||
df = new DataFlavor(DnDSource.class, "DnDSource");
|
||||
|
||||
dragSource.createDefaultDragGestureRecognizer(
|
||||
this,
|
||||
dragOperation,
|
||||
this
|
||||
);
|
||||
dragSource.addDragSourceListener(this);
|
||||
}
|
||||
|
||||
public void changeCursor(
|
||||
DragSourceContext dsc,
|
||||
int ra
|
||||
) {
|
||||
java.awt.Cursor c = null;
|
||||
if ((ra & DnDConstants.ACTION_LINK) == DnDConstants.ACTION_LINK)
|
||||
c = DragSource.DefaultLinkDrop;
|
||||
else if ((ra & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE)
|
||||
c = MyCursor.MOVE;//DragSource.DefaultMoveDrop;
|
||||
else if ((ra & DnDConstants.ACTION_COPY) == DnDConstants.ACTION_COPY)
|
||||
c = MyCursor.COPY;
|
||||
else
|
||||
c = MyCursor.NO_DROP;
|
||||
dsc.setCursor(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* a Drag gesture has been recognized
|
||||
*/
|
||||
|
||||
public void dragGestureRecognized(DragGestureEvent dge) {
|
||||
System.out.println("starting Drag");
|
||||
try {
|
||||
if (DragSource.isDragImageSupported()) {
|
||||
System.out.println("starting Imaged Drag");
|
||||
dge.startDrag(
|
||||
null,
|
||||
new ImageGenerator(50, 100, new Color(0xff, 0xff, 0xff, 0x00) ) {
|
||||
@Override public void paint(Graphics gr) {
|
||||
gr.translate(width/2, height/2);
|
||||
((Graphics2D)gr).setStroke(new BasicStroke(3));
|
||||
int R = width/4+5;
|
||||
gr.setColor(new Color(0x00, 0x00, 0xff, 0x7F));
|
||||
gr.fillRect(-R, -R, 2*R, 2*R);
|
||||
gr.setColor(new Color(0x00, 0x00, 0xff, 0xff));
|
||||
gr.drawRect(-R, -R, 2*R, 2*R);
|
||||
|
||||
|
||||
gr.translate(10, -10);
|
||||
R -= 5;
|
||||
gr.setColor(Color.RED);
|
||||
gr.fillOval(-R, -R, 2*R, 2*R);
|
||||
gr.setColor(Color.MAGENTA);
|
||||
gr.drawOval(-R, -R, 2*R, 2*R);
|
||||
}
|
||||
}.getImage(),
|
||||
new Point(15, 40),
|
||||
this,
|
||||
this);
|
||||
} else {
|
||||
dge.startDrag(
|
||||
null,
|
||||
this,
|
||||
this);
|
||||
}
|
||||
} catch (InvalidDnDOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* as the hotspot enters a platform dependent drop site
|
||||
*/
|
||||
|
||||
public void dragEnter(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dragEnter");
|
||||
changeCursor(
|
||||
dsde.getDragSourceContext(),
|
||||
dsde.getUserAction() & dsde.getDropAction()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* as the hotspot moves over a platform dependent drop site
|
||||
*/
|
||||
public void dragOver(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dragOver");
|
||||
changeCursor(
|
||||
dsde.getDragSourceContext(),
|
||||
dsde.getUserAction() & dsde.getDropAction()
|
||||
);
|
||||
dropAction = dsde.getUserAction() & dsde.getDropAction();
|
||||
System.out.println("dropAction = " + dropAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* as the hotspot exits a platform dependent drop site
|
||||
*/
|
||||
public void dragExit(DragSourceEvent dse) {
|
||||
System.out.println("[Source] dragExit");
|
||||
changeCursor(
|
||||
dse.getDragSourceContext(),
|
||||
DnDConstants.ACTION_NONE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* as the operation changes
|
||||
*/
|
||||
public void dragGestureChanged(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dragGestureChanged");
|
||||
changeCursor(
|
||||
dsde.getDragSourceContext(),
|
||||
dsde.getUserAction() & dsde.getDropAction()
|
||||
);
|
||||
dropAction = dsde.getUserAction() & dsde.getDropAction();
|
||||
System.out.println("dropAction = " + dropAction);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* as the operation completes
|
||||
*/
|
||||
public void dragDropEnd(DragSourceDropEvent dsde) {
|
||||
System.out.println("[Source] dragDropEnd");
|
||||
}
|
||||
|
||||
public void dropActionChanged(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dropActionChanged");
|
||||
dropAction = dsde.getUserAction() & dsde.getDropAction();
|
||||
System.out.println("dropAction = " + dropAction);
|
||||
}
|
||||
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return new DataFlavor[]{df};
|
||||
}
|
||||
|
||||
public boolean isDataFlavorSupported(DataFlavor sdf) {
|
||||
return df.equals(sdf);
|
||||
}
|
||||
|
||||
public Object getTransferData(DataFlavor tdf) throws UnsupportedFlavorException, IOException {
|
||||
Object copy = null;
|
||||
if( !df.equals(tdf) ){
|
||||
throw new UnsupportedFlavorException(tdf);
|
||||
}
|
||||
Container parent = getParent();
|
||||
switch (dropAction) {
|
||||
case DnDConstants.ACTION_COPY:
|
||||
try {
|
||||
copy = this.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
|
||||
oos.writeObject(this);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||
try {
|
||||
copy = ois.readObject();
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
parent.add(this);
|
||||
return copy;
|
||||
|
||||
case DnDConstants.ACTION_MOVE:
|
||||
synchronized (this) {
|
||||
if (parent != null) {
|
||||
parent.remove(this);
|
||||
Label label = new Label("[empty]");
|
||||
label.setBackground(Color.cyan);
|
||||
label.setBounds(this.getBounds());
|
||||
parent.add(label);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
||||
case DnDConstants.ACTION_LINK:
|
||||
return this;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
113
jdk/test/java/awt/dnd/ImageDecoratedDnD/DnDTarget.java
Normal file
113
jdk/test/java/awt/dnd/ImageDecoratedDnD/DnDTarget.java
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Panel is a DropTarget
|
||||
*
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.dnd.*;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
class DnDTarget extends Panel implements DropTargetListener {
|
||||
private int dragOperation = DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE;
|
||||
Color bgColor;
|
||||
Color htColor;
|
||||
|
||||
DnDTarget(Color bgColor, Color htColor) {
|
||||
super();
|
||||
this.bgColor = bgColor;
|
||||
this.htColor = htColor;
|
||||
setBackground(bgColor);
|
||||
setDropTarget(new DropTarget(this, this));
|
||||
}
|
||||
|
||||
|
||||
public void dragEnter(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dragEnter");
|
||||
setBackground(htColor);
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void dragOver(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dragOver");
|
||||
}
|
||||
|
||||
public void dragExit(DropTargetEvent e) {
|
||||
System.out.println("[Target] dragExit");
|
||||
setBackground(bgColor);
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void dragScroll(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dragScroll");
|
||||
}
|
||||
|
||||
public void dropActionChanged(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dropActionChanged");
|
||||
}
|
||||
|
||||
public void drop(DropTargetDropEvent dtde) {
|
||||
System.out.println("[Target] drop");
|
||||
boolean success = false;
|
||||
if ((dtde.getDropAction() & dragOperation) == 0) {
|
||||
dtde.rejectDrop();
|
||||
Label label = new Label("[no links here :) ]");
|
||||
label.setBackground(Color.cyan);
|
||||
add(label);
|
||||
} else {
|
||||
dtde.acceptDrop(dragOperation);
|
||||
DataFlavor[] dfs = dtde.getCurrentDataFlavors();
|
||||
if (dfs != null && dfs.length >= 1){
|
||||
Transferable transfer = dtde.getTransferable();
|
||||
try {
|
||||
Button button = (Button)transfer.getTransferData(dfs[0]);
|
||||
if( button != null ){
|
||||
add(button);
|
||||
success = true;
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
System.out.println(ioe.getMessage());
|
||||
return;
|
||||
} catch (UnsupportedFlavorException ufe) {
|
||||
System.out.println(ufe.getMessage());
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
setBackground(bgColor);
|
||||
dtde.dropComplete(success);
|
||||
|
||||
invalidate();
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<html>
|
||||
<!--
|
||||
@test %W% %E%
|
||||
@bug 4874070
|
||||
@summary Tests basic DnD functionality
|
||||
@author Your Name: Alexey Utkin area=dnd
|
||||
@run applet/manual=yesno ImageDecoratedDnD.html
|
||||
-->
|
||||
<head>
|
||||
<title> ImageDecoratedDnD </title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>ImageDecoratedDnD<br>Bug ID: 4874070</h1>
|
||||
|
||||
<p> See the dialog box (usually in upper left corner) for instructions</p>
|
||||
|
||||
<APPLET CODE="ImageDecoratedDnD.class" WIDTH=200 HEIGHT=200></APPLET>
|
||||
</body>
|
||||
</html>
|
199
jdk/test/java/awt/dnd/ImageDecoratedDnD/ImageDecoratedDnD.java
Normal file
199
jdk/test/java/awt/dnd/ImageDecoratedDnD/ImageDecoratedDnD.java
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
test %W% %E%
|
||||
@bug 4874070
|
||||
@summary Tests basic DnD functionality
|
||||
@author Your Name: Alexey Utkin area=dnd
|
||||
@run applet/manual=yesno ImageDecoratedDnD.html
|
||||
*/
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.awt.*;
|
||||
import java.awt.dnd.DragSource;
|
||||
|
||||
|
||||
|
||||
public class ImageDecoratedDnD extends Applet {
|
||||
//Declare things used in the test, like buttons and labels here
|
||||
|
||||
public void init() {
|
||||
//Create instructions for the user here, as well as set up
|
||||
// the environment -- set the layout manager, add buttons,
|
||||
// etc.
|
||||
this.setLayout(new BorderLayout());
|
||||
|
||||
String[] instructions =
|
||||
{
|
||||
"A Frame, which contains a yellow button labeled \"Drag ME!\" and ",
|
||||
"a red panel, will appear below. ",
|
||||
"1. Click on the button and drag to the red panel. ",
|
||||
"2. When the mouse enters the red panel during the drag, the panel ",
|
||||
"should turn yellow. On the systems that supports pictured drag, ",
|
||||
"the image under the drag-cursor should appear (ancor is shifted ",
|
||||
"from top-left corner of the picture inside the picture to 10pt in both dimensions ). ",
|
||||
"In WIN32 systems the image under cursor would be visible ONLY over ",
|
||||
"the drop targets with activated extended OLE D\'n\'D support (that are ",
|
||||
"the desktop and IE ).",
|
||||
"3. Release the mouse button.",
|
||||
"The panel should turn red again and a yellow button labeled ",
|
||||
"\"Drag ME!\" should appear inside the panel. You should be able ",
|
||||
"to repeat this operation multiple times."
|
||||
};
|
||||
Sysout.createDialogWithInstructions(instructions);
|
||||
|
||||
}//End init()
|
||||
|
||||
public void start() {
|
||||
Frame f = new Frame("Use keyboard for DnD change");
|
||||
Panel mainPanel;
|
||||
Component dragSource, dropTarget;
|
||||
|
||||
f.setBounds(0, 400, 200, 200);
|
||||
f.setLayout(new BorderLayout());
|
||||
|
||||
mainPanel = new Panel();
|
||||
mainPanel.setLayout(new BorderLayout());
|
||||
|
||||
mainPanel.setBackground(Color.blue);
|
||||
|
||||
dropTarget = new DnDTarget(Color.red, Color.yellow);
|
||||
dragSource = new DnDSource("Drag ME! (" + (DragSource.isDragImageSupported()?"with ":"without") + " image)" );
|
||||
|
||||
mainPanel.add(dragSource, "North");
|
||||
mainPanel.add(dropTarget, "Center");
|
||||
f.add(mainPanel, BorderLayout.CENTER);
|
||||
|
||||
f.setVisible(true);
|
||||
}// start()
|
||||
}// class DnDAcceptanceTest
|
||||
|
||||
|
||||
/**
|
||||
* *************************************************
|
||||
* Standard Test Machinery
|
||||
* DO NOT modify anything below -- it's a standard
|
||||
* chunk of code whose purpose is to make user
|
||||
* interaction uniform, and thereby make it simpler
|
||||
* to read and understand someone else's test.
|
||||
* **************************************************
|
||||
*/
|
||||
class Sysout {
|
||||
private static TestDialog dialog;
|
||||
|
||||
public static void createDialogWithInstructions(String[] instructions) {
|
||||
dialog = new TestDialog(new Frame(), "Instructions");
|
||||
dialog.printInstructions(instructions);
|
||||
dialog.show();
|
||||
println("Any messages for the tester will display here.");
|
||||
}
|
||||
|
||||
public static void createDialog() {
|
||||
dialog = new TestDialog(new Frame(), "Instructions");
|
||||
String[] defInstr = {"Instructions will appear here. ", ""};
|
||||
dialog.printInstructions(defInstr);
|
||||
dialog.show();
|
||||
println("Any messages for the tester will display here.");
|
||||
}
|
||||
|
||||
|
||||
public static void printInstructions(String[] instructions) {
|
||||
dialog.printInstructions(instructions);
|
||||
}
|
||||
|
||||
|
||||
public static void println(String messageIn) {
|
||||
dialog.displayMessage(messageIn);
|
||||
}
|
||||
|
||||
}// Sysout class
|
||||
|
||||
|
||||
class TestDialog extends Dialog {
|
||||
|
||||
TextArea instructionsText;
|
||||
TextArea messageText;
|
||||
int maxStringLength = 80;
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public TestDialog(Frame frame, String name) {
|
||||
super(frame, name);
|
||||
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||
instructionsText = new TextArea("", 15, maxStringLength, scrollBoth);
|
||||
add("North", instructionsText);
|
||||
|
||||
messageText = new TextArea("", 5, maxStringLength, scrollBoth);
|
||||
add("South", messageText);
|
||||
|
||||
pack();
|
||||
|
||||
show();
|
||||
}// TestDialog()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void printInstructions(String[] instructions) {
|
||||
//Clear out any current instructions
|
||||
instructionsText.setText("");
|
||||
|
||||
//Go down array of instruction strings
|
||||
|
||||
String printStr, remainingStr;
|
||||
for (int i = 0; i < instructions.length; i++) {
|
||||
//chop up each into pieces maxSringLength long
|
||||
remainingStr = instructions[i];
|
||||
while (remainingStr.length() > 0) {
|
||||
//if longer than max then chop off first max chars to print
|
||||
if (remainingStr.length() >= maxStringLength) {
|
||||
//Try to chop on a word boundary
|
||||
int posOfSpace = remainingStr.
|
||||
lastIndexOf(' ', maxStringLength - 1);
|
||||
|
||||
if (posOfSpace <= 0) posOfSpace = maxStringLength - 1;
|
||||
|
||||
printStr = remainingStr.substring(0, posOfSpace + 1);
|
||||
remainingStr = remainingStr.substring(posOfSpace + 1);
|
||||
}
|
||||
//else just print
|
||||
else {
|
||||
printStr = remainingStr;
|
||||
remainingStr = "";
|
||||
}
|
||||
|
||||
instructionsText.append(printStr + "\n");
|
||||
|
||||
}// while
|
||||
|
||||
}// for
|
||||
|
||||
}//printInstructions()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void displayMessage(String messageIn) {
|
||||
messageText.append(messageIn + "\n");
|
||||
}
|
||||
|
||||
}// TestDialog class
|
||||
|
59
jdk/test/java/awt/dnd/ImageDecoratedDnD/ImageGenerator.java
Normal file
59
jdk/test/java/awt/dnd/ImageDecoratedDnD/ImageGenerator.java
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Image generator for cursor and drag
|
||||
*/
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public abstract class ImageGenerator
|
||||
{
|
||||
public int width;
|
||||
public int height;
|
||||
private final BufferedImage bi;
|
||||
public ImageGenerator(int _width, int _height, Color bgColor)
|
||||
{
|
||||
width = _width;
|
||||
height = _height;
|
||||
bi = new BufferedImage(
|
||||
width,
|
||||
height,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics gr = bi.getGraphics();
|
||||
if(null==bgColor){
|
||||
bgColor = Color.WHITE;
|
||||
}
|
||||
gr.setColor(bgColor);
|
||||
gr.fillRect(0, 0, width, height);
|
||||
paint(gr);
|
||||
gr.dispose();
|
||||
}
|
||||
public Image getImage() { return bi; }
|
||||
|
||||
public abstract void paint(Graphics gr);
|
||||
}
|
86
jdk/test/java/awt/dnd/ImageDecoratedDnD/MyCursor.java
Normal file
86
jdk/test/java/awt/dnd/ImageDecoratedDnD/MyCursor.java
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* An interface provides a set of custom cursors
|
||||
*/
|
||||
|
||||
public interface MyCursor {
|
||||
public static final java.awt.Cursor NO_DROP = Toolkit.getDefaultToolkit().createCustomCursor(
|
||||
new ImageGenerator(32, 32, new Color(0xff, 0xff, 0xff, 0x00) ) {
|
||||
@Override public void paint(Graphics gr) {
|
||||
gr.setColor(Color.GREEN);
|
||||
((Graphics2D)gr).setStroke(new BasicStroke(3));
|
||||
|
||||
gr.translate(width/2, height/2);
|
||||
int R = width/4;
|
||||
gr.drawOval(-R, -R, 2*R, 2*R);
|
||||
gr.drawLine(-R, R, R, -R);
|
||||
}
|
||||
}.getImage(),
|
||||
new Point(0, 0),
|
||||
"My NoDrop Cursor"
|
||||
);
|
||||
public static final java.awt.Cursor MOVE = Toolkit.getDefaultToolkit().createCustomCursor(
|
||||
new ImageGenerator(32, 32, new Color(0xff, 0xff, 0xff, 0x00) ) {
|
||||
@Override public void paint(Graphics gr) {
|
||||
gr.setColor(Color.GREEN);
|
||||
((Graphics2D)gr).setStroke(new BasicStroke(3));
|
||||
|
||||
gr.drawLine(0, 0, width, height);
|
||||
gr.drawLine(0, 0, width/2, 0);
|
||||
gr.drawLine(0, 0, 0, height/2);
|
||||
}
|
||||
}.getImage(),
|
||||
new Point(0, 0),
|
||||
"My Move Cursor"
|
||||
);
|
||||
public static final java.awt.Cursor COPY = Toolkit.getDefaultToolkit().createCustomCursor(
|
||||
new ImageGenerator(32, 32, new Color(0xff, 0xff, 0xff, 0x00) ) {
|
||||
@Override public void paint(Graphics gr) {
|
||||
gr.setColor(Color.GREEN);
|
||||
((Graphics2D)gr).setStroke(new BasicStroke(3));
|
||||
//arrow
|
||||
gr.drawLine(0, 0, width/2, height/2);
|
||||
gr.drawLine(0, 0, width/2, 0);
|
||||
gr.drawLine(0, 0, 0, height/2);
|
||||
//plus
|
||||
gr.drawRect(width/2 - 1, height/2 -1, width/2 - 1, height/2 - 1);
|
||||
gr.drawLine(width*3/4 - 1, height/2 - 1, width*3/4 - 1, height);
|
||||
gr.drawLine(width/2 - 1, height*3/4 - 1, width, height*3/4 - 1);
|
||||
}
|
||||
}.getImage(),
|
||||
new Point(0, 0),
|
||||
"My Copy Cursor"
|
||||
);
|
||||
}
|
||||
|
235
jdk/test/java/awt/dnd/ImageDecoratedDnDInOut/DnDSource.java
Normal file
235
jdk/test/java/awt/dnd/ImageDecoratedDnDInOut/DnDSource.java
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* AWT Button is a DragSource and also a transferable object
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.dnd.*;
|
||||
import java.io.*;
|
||||
|
||||
class DnDSource extends Button implements Transferable,
|
||||
DragGestureListener,
|
||||
DragSourceListener {
|
||||
private DataFlavor df;
|
||||
private transient int dropAction;
|
||||
private final int dragOperation = DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE | DnDConstants.ACTION_LINK;
|
||||
DragSource dragSource = new DragSource();
|
||||
|
||||
DnDSource(String label) {
|
||||
super(label);
|
||||
setBackground(Color.yellow);
|
||||
setForeground(Color.blue);
|
||||
df = new DataFlavor(DnDSource.class, "DnDSource");
|
||||
|
||||
dragSource.createDefaultDragGestureRecognizer(
|
||||
this,
|
||||
dragOperation,
|
||||
this
|
||||
);
|
||||
dragSource.addDragSourceListener(this);
|
||||
}
|
||||
|
||||
public void changeCursor(
|
||||
DragSourceContext dsc,
|
||||
int ra
|
||||
) {
|
||||
java.awt.Cursor c = null;
|
||||
if ((ra & DnDConstants.ACTION_LINK) == DnDConstants.ACTION_LINK)
|
||||
c = DragSource.DefaultLinkDrop;
|
||||
else if ((ra & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE)
|
||||
c = MyCursor.MOVE;//DragSource.DefaultMoveDrop;
|
||||
else if ((ra & DnDConstants.ACTION_COPY) == DnDConstants.ACTION_COPY)
|
||||
c = MyCursor.COPY;
|
||||
else
|
||||
c = MyCursor.NO_DROP;
|
||||
dsc.setCursor(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* a Drag gesture has been recognized
|
||||
*/
|
||||
|
||||
public void dragGestureRecognized(DragGestureEvent dge) {
|
||||
System.out.println("starting Drag");
|
||||
try {
|
||||
if (DragSource.isDragImageSupported()) {
|
||||
System.out.println("starting Imaged Drag");
|
||||
dge.startDrag(
|
||||
null,
|
||||
new ImageGenerator(50, 100, new Color(0xff, 0xff, 0xff, 0x00) ) {
|
||||
@Override public void paint(Graphics gr) {
|
||||
gr.translate(width/2, height/2);
|
||||
((Graphics2D)gr).setStroke(new BasicStroke(3));
|
||||
int R = width/4+5;
|
||||
gr.setColor(Color.BLUE);
|
||||
gr.fillRect(-R, -R, 2*R, 2*R);
|
||||
gr.setColor(Color.CYAN);
|
||||
gr.drawRect(-R, -R, 2*R, 2*R);
|
||||
|
||||
|
||||
gr.translate(10, 10);
|
||||
R -= 5;
|
||||
gr.setColor(Color.RED);
|
||||
gr.fillOval(-R, -R, 2*R, 2*R);
|
||||
gr.setColor(Color.MAGENTA);
|
||||
gr.drawOval(-R, -R, 2*R, 2*R);
|
||||
}
|
||||
}.getImage(),
|
||||
new Point(15, 40),
|
||||
this,
|
||||
this);
|
||||
} else {
|
||||
dge.startDrag(
|
||||
null,
|
||||
this,
|
||||
this);
|
||||
}
|
||||
} catch (InvalidDnDOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* as the hotspot enters a platform dependent drop site
|
||||
*/
|
||||
|
||||
public void dragEnter(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dragEnter");
|
||||
changeCursor(
|
||||
dsde.getDragSourceContext(),
|
||||
dsde.getUserAction() & dsde.getDropAction()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* as the hotspot moves over a platform dependent drop site
|
||||
*/
|
||||
public void dragOver(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dragOver");
|
||||
changeCursor(
|
||||
dsde.getDragSourceContext(),
|
||||
dsde.getUserAction() & dsde.getDropAction()
|
||||
);
|
||||
dropAction = dsde.getUserAction() & dsde.getDropAction();
|
||||
System.out.println("dropAction = " + dropAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* as the hotspot exits a platform dependent drop site
|
||||
*/
|
||||
public void dragExit(DragSourceEvent dse) {
|
||||
System.out.println("[Source] dragExit");
|
||||
changeCursor(
|
||||
dse.getDragSourceContext(),
|
||||
DnDConstants.ACTION_NONE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* as the operation changes
|
||||
*/
|
||||
public void dragGestureChanged(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dragGestureChanged");
|
||||
changeCursor(
|
||||
dsde.getDragSourceContext(),
|
||||
dsde.getUserAction() & dsde.getDropAction()
|
||||
);
|
||||
dropAction = dsde.getUserAction() & dsde.getDropAction();
|
||||
System.out.println("dropAction = " + dropAction);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* as the operation completes
|
||||
*/
|
||||
public void dragDropEnd(DragSourceDropEvent dsde) {
|
||||
System.out.println("[Source] dragDropEnd");
|
||||
}
|
||||
|
||||
public void dropActionChanged(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dropActionChanged");
|
||||
dropAction = dsde.getUserAction() & dsde.getDropAction();
|
||||
System.out.println("dropAction = " + dropAction);
|
||||
}
|
||||
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return new DataFlavor[]{df};
|
||||
}
|
||||
|
||||
public boolean isDataFlavorSupported(DataFlavor sdf) {
|
||||
return df.equals(sdf);
|
||||
}
|
||||
|
||||
public Object getTransferData(DataFlavor tdf) throws UnsupportedFlavorException, IOException {
|
||||
Object copy = null;
|
||||
if( !df.equals(tdf) ){
|
||||
throw new UnsupportedFlavorException(tdf);
|
||||
}
|
||||
Container parent = getParent();
|
||||
switch (dropAction) {
|
||||
case DnDConstants.ACTION_COPY:
|
||||
try {
|
||||
copy = this.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
|
||||
oos.writeObject(this);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||
try {
|
||||
copy = ois.readObject();
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
parent.add(this);
|
||||
return copy;
|
||||
|
||||
case DnDConstants.ACTION_MOVE:
|
||||
synchronized (this) {
|
||||
if (parent != null) {
|
||||
parent.remove(this);
|
||||
Label label = new Label("[empty]");
|
||||
label.setBackground(Color.cyan);
|
||||
label.setBounds(this.getBounds());
|
||||
parent.add(label);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
||||
case DnDConstants.ACTION_LINK:
|
||||
return this;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
113
jdk/test/java/awt/dnd/ImageDecoratedDnDInOut/DnDTarget.java
Normal file
113
jdk/test/java/awt/dnd/ImageDecoratedDnDInOut/DnDTarget.java
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Panel is a DropTarget
|
||||
*
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.dnd.*;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
class DnDTarget extends Panel implements DropTargetListener {
|
||||
private int dragOperation = DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE;
|
||||
Color bgColor;
|
||||
Color htColor;
|
||||
|
||||
DnDTarget(Color bgColor, Color htColor) {
|
||||
super();
|
||||
this.bgColor = bgColor;
|
||||
this.htColor = htColor;
|
||||
setBackground(bgColor);
|
||||
setDropTarget(new DropTarget(this, this));
|
||||
}
|
||||
|
||||
|
||||
public void dragEnter(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dragEnter");
|
||||
setBackground(htColor);
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void dragOver(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dragOver");
|
||||
}
|
||||
|
||||
public void dragExit(DropTargetEvent e) {
|
||||
System.out.println("[Target] dragExit");
|
||||
setBackground(bgColor);
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void dragScroll(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dragScroll");
|
||||
}
|
||||
|
||||
public void dropActionChanged(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dropActionChanged");
|
||||
}
|
||||
|
||||
public void drop(DropTargetDropEvent dtde) {
|
||||
System.out.println("[Target] drop");
|
||||
boolean success = false;
|
||||
if ((dtde.getDropAction() & dragOperation) == 0) {
|
||||
dtde.rejectDrop();
|
||||
Label label = new Label("[no links here :) ]");
|
||||
label.setBackground(Color.cyan);
|
||||
add(label);
|
||||
} else {
|
||||
dtde.acceptDrop(dragOperation);
|
||||
DataFlavor[] dfs = dtde.getCurrentDataFlavors();
|
||||
if (dfs != null && dfs.length >= 1){
|
||||
Transferable transfer = dtde.getTransferable();
|
||||
try {
|
||||
Button button = (Button)transfer.getTransferData(dfs[0]);
|
||||
if( button != null ){
|
||||
add(button);
|
||||
success = true;
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
System.out.println(ioe.getMessage());
|
||||
return;
|
||||
} catch (UnsupportedFlavorException ufe) {
|
||||
System.out.println(ufe.getMessage());
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
setBackground(bgColor);
|
||||
dtde.dropComplete(success);
|
||||
|
||||
invalidate();
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<html>
|
||||
<!--
|
||||
@test %W% %E%
|
||||
@bug 4874070
|
||||
@summary Tests basic DnD functionality
|
||||
@author Your Name: Alexey Utkin area=dnd
|
||||
@run applet ImageDecoratedDnDInOut.html
|
||||
-->
|
||||
<head>
|
||||
<title> ImageDecoratedDnDInOut </title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>ImageDecoratedDnDInOut<br>Bug ID: 4874070</h1>
|
||||
|
||||
<p> See the dialog box (usually in upper left corner) for instructions</p>
|
||||
|
||||
<APPLET CODE="ImageDecoratedDnDInOut.class" WIDTH=200 HEIGHT=200></APPLET>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
test %W% %E%
|
||||
@bug 4874070
|
||||
@summary Tests basic DnD functionality
|
||||
@author Your Name: Alexey Utkin area=dnd
|
||||
@run applet ImageDecoratedDnDInOut.html
|
||||
*/
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.awt.*;
|
||||
import java.awt.Robot;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.dnd.DragSource;
|
||||
|
||||
|
||||
public class ImageDecoratedDnDInOut extends Applet {
|
||||
//Declare things used in the test, like buttons and labels here
|
||||
|
||||
public void init() {
|
||||
//Create instructions for the user here, as well as set up
|
||||
// the environment -- set the layout manager, add buttons,
|
||||
// etc.
|
||||
this.setLayout(new BorderLayout());
|
||||
|
||||
String[] instructions =
|
||||
{
|
||||
"Automatic test.",
|
||||
"A Frame, which contains a yellow button labeled \"Drag ME!\" and ",
|
||||
"a red panel, will appear below. ",
|
||||
"1. The button would be clicked and dragged to the red panel. ",
|
||||
"2. When the mouse enters the red panel during the drag, the panel ",
|
||||
"should turn yellow. On the systems that supports pictured drag, ",
|
||||
"the image under the drag-cursor should appear (ancor is shifted ",
|
||||
"from top-left corner of the picture inside the picture to 10pt in both dimensions ). ",
|
||||
"In WIN32 systems the image under cursor would be visible ONLY over ",
|
||||
"the drop targets with activated extended OLE D\'n\'D support (that are ",
|
||||
"the desktop and IE ).",
|
||||
"3. The mouse would be released.",
|
||||
"The panel should turn red again and a yellow button labeled ",
|
||||
"\"Drag ME!\" should appear inside the panel. "
|
||||
};
|
||||
Sysout.createDialogWithInstructions(instructions);
|
||||
|
||||
}//End init()
|
||||
|
||||
public void start() {
|
||||
Frame f = new Frame("Use keyboard for DnD change");
|
||||
Panel mainPanel;
|
||||
Component dragSource, dropTarget;
|
||||
|
||||
f.setBounds(0, 400, 200, 200);
|
||||
f.setLayout(new BorderLayout());
|
||||
|
||||
mainPanel = new Panel();
|
||||
mainPanel.setLayout(new BorderLayout());
|
||||
|
||||
mainPanel.setBackground(Color.blue);
|
||||
|
||||
dropTarget = new DnDTarget(Color.red, Color.yellow);
|
||||
dragSource = new DnDSource("Drag ME! (" + (DragSource.isDragImageSupported()?"with ":"without") + " image)" );
|
||||
|
||||
mainPanel.add(dragSource, "North");
|
||||
mainPanel.add(dropTarget, "Center");
|
||||
f.add(mainPanel, BorderLayout.CENTER);
|
||||
|
||||
f.setVisible(true);
|
||||
try {
|
||||
Point sourcePoint = dragSource.getLocationOnScreen();
|
||||
Dimension d = dragSource.getSize();
|
||||
sourcePoint.translate(d.width / 2, d.height / 2);
|
||||
|
||||
Robot robot = new Robot();
|
||||
robot.mouseMove(sourcePoint.x, sourcePoint.y);
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
Thread.sleep(2000);
|
||||
for(int i = 0; i <100; ++i) {
|
||||
robot.mouseMove(
|
||||
sourcePoint.x + d.width / 2 + 10,
|
||||
sourcePoint.y + d.height);
|
||||
Thread.sleep(100);
|
||||
|
||||
robot.mouseMove(sourcePoint.x, sourcePoint.y);
|
||||
Thread.sleep(100);
|
||||
|
||||
robot.mouseMove(
|
||||
sourcePoint.x,
|
||||
sourcePoint.y + d.height);
|
||||
Thread.sleep(100);
|
||||
}
|
||||
sourcePoint.y += d.height;
|
||||
robot.mouseMove(sourcePoint.x, sourcePoint.y);
|
||||
Thread.sleep(100);
|
||||
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
Thread.sleep(4000);
|
||||
} catch( Exception e){
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("test failed: drop was not successful with exception " + e);
|
||||
}
|
||||
|
||||
}// start()
|
||||
}// class DnDAcceptanceTest
|
||||
|
||||
|
||||
/**
|
||||
* *************************************************
|
||||
* Standard Test Machinery
|
||||
* DO NOT modify anything below -- it's a standard
|
||||
* chunk of code whose purpose is to make user
|
||||
* interaction uniform, and thereby make it simpler
|
||||
* to read and understand someone else's test.
|
||||
* **************************************************
|
||||
*/
|
||||
class Sysout {
|
||||
private static TestDialog dialog;
|
||||
|
||||
public static void createDialogWithInstructions(String[] instructions) {
|
||||
dialog = new TestDialog(new Frame(), "Instructions");
|
||||
dialog.printInstructions(instructions);
|
||||
dialog.show();
|
||||
println("Any messages for the tester will display here.");
|
||||
}
|
||||
|
||||
public static void createDialog() {
|
||||
dialog = new TestDialog(new Frame(), "Instructions");
|
||||
String[] defInstr = {"Instructions will appear here. ", ""};
|
||||
dialog.printInstructions(defInstr);
|
||||
dialog.show();
|
||||
println("Any messages for the tester will display here.");
|
||||
}
|
||||
|
||||
|
||||
public static void printInstructions(String[] instructions) {
|
||||
dialog.printInstructions(instructions);
|
||||
}
|
||||
|
||||
|
||||
public static void println(String messageIn) {
|
||||
dialog.displayMessage(messageIn);
|
||||
}
|
||||
|
||||
}// Sysout class
|
||||
|
||||
|
||||
class TestDialog extends Dialog {
|
||||
|
||||
TextArea instructionsText;
|
||||
TextArea messageText;
|
||||
int maxStringLength = 80;
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public TestDialog(Frame frame, String name) {
|
||||
super(frame, name);
|
||||
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||
instructionsText = new TextArea("", 15, maxStringLength, scrollBoth);
|
||||
add("North", instructionsText);
|
||||
|
||||
messageText = new TextArea("", 5, maxStringLength, scrollBoth);
|
||||
add("South", messageText);
|
||||
|
||||
pack();
|
||||
|
||||
show();
|
||||
}// TestDialog()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void printInstructions(String[] instructions) {
|
||||
//Clear out any current instructions
|
||||
instructionsText.setText("");
|
||||
|
||||
//Go down array of instruction strings
|
||||
|
||||
String printStr, remainingStr;
|
||||
for (int i = 0; i < instructions.length; i++) {
|
||||
//chop up each into pieces maxSringLength long
|
||||
remainingStr = instructions[i];
|
||||
while (remainingStr.length() > 0) {
|
||||
//if longer than max then chop off first max chars to print
|
||||
if (remainingStr.length() >= maxStringLength) {
|
||||
//Try to chop on a word boundary
|
||||
int posOfSpace = remainingStr.
|
||||
lastIndexOf(' ', maxStringLength - 1);
|
||||
|
||||
if (posOfSpace <= 0) posOfSpace = maxStringLength - 1;
|
||||
|
||||
printStr = remainingStr.substring(0, posOfSpace + 1);
|
||||
remainingStr = remainingStr.substring(posOfSpace + 1);
|
||||
}
|
||||
//else just print
|
||||
else {
|
||||
printStr = remainingStr;
|
||||
remainingStr = "";
|
||||
}
|
||||
|
||||
instructionsText.append(printStr + "\n");
|
||||
|
||||
}// while
|
||||
|
||||
}// for
|
||||
|
||||
}//printInstructions()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void displayMessage(String messageIn) {
|
||||
messageText.append(messageIn + "\n");
|
||||
}
|
||||
|
||||
}// TestDialog class
|
||||
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Image generator for cursor and drag
|
||||
*/
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public abstract class ImageGenerator
|
||||
{
|
||||
public int width;
|
||||
public int height;
|
||||
private final BufferedImage bi;
|
||||
public ImageGenerator(int _width, int _height, Color bgColor)
|
||||
{
|
||||
width = _width;
|
||||
height = _height;
|
||||
bi = new BufferedImage(
|
||||
width,
|
||||
height,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics gr = bi.getGraphics();
|
||||
if(null==bgColor){
|
||||
bgColor = Color.WHITE;
|
||||
}
|
||||
gr.setColor(bgColor);
|
||||
gr.fillRect(0, 0, width, height);
|
||||
paint(gr);
|
||||
gr.dispose();
|
||||
}
|
||||
public Image getImage() { return bi; }
|
||||
|
||||
public abstract void paint(Graphics gr);
|
||||
}
|
86
jdk/test/java/awt/dnd/ImageDecoratedDnDInOut/MyCursor.java
Normal file
86
jdk/test/java/awt/dnd/ImageDecoratedDnDInOut/MyCursor.java
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* An interface provides a set of custom cursors
|
||||
*/
|
||||
|
||||
public interface MyCursor {
|
||||
public static final java.awt.Cursor NO_DROP = Toolkit.getDefaultToolkit().createCustomCursor(
|
||||
new ImageGenerator(32, 32, new Color(0xff, 0xff, 0xff, 0x00) ) {
|
||||
@Override public void paint(Graphics gr) {
|
||||
gr.setColor(Color.GREEN);
|
||||
((Graphics2D)gr).setStroke(new BasicStroke(3));
|
||||
|
||||
gr.translate(width/2, height/2);
|
||||
int R = width/4;
|
||||
gr.drawOval(-R, -R, 2*R, 2*R);
|
||||
gr.drawLine(-R, R, R, -R);
|
||||
}
|
||||
}.getImage(),
|
||||
new Point(0, 0),
|
||||
"My NoDrop Cursor"
|
||||
);
|
||||
public static final java.awt.Cursor MOVE = Toolkit.getDefaultToolkit().createCustomCursor(
|
||||
new ImageGenerator(32, 32, new Color(0xff, 0xff, 0xff, 0x00) ) {
|
||||
@Override public void paint(Graphics gr) {
|
||||
gr.setColor(Color.GREEN);
|
||||
((Graphics2D)gr).setStroke(new BasicStroke(3));
|
||||
|
||||
gr.drawLine(0, 0, width, height);
|
||||
gr.drawLine(0, 0, width/2, 0);
|
||||
gr.drawLine(0, 0, 0, height/2);
|
||||
}
|
||||
}.getImage(),
|
||||
new Point(0, 0),
|
||||
"My Move Cursor"
|
||||
);
|
||||
public static final java.awt.Cursor COPY = Toolkit.getDefaultToolkit().createCustomCursor(
|
||||
new ImageGenerator(32, 32, new Color(0xff, 0xff, 0xff, 0x00) ) {
|
||||
@Override public void paint(Graphics gr) {
|
||||
gr.setColor(Color.GREEN);
|
||||
((Graphics2D)gr).setStroke(new BasicStroke(3));
|
||||
//arrow
|
||||
gr.drawLine(0, 0, width/2, height/2);
|
||||
gr.drawLine(0, 0, width/2, 0);
|
||||
gr.drawLine(0, 0, 0, height/2);
|
||||
//plus
|
||||
gr.drawRect(width/2 - 1, height/2 -1, width/2 - 1, height/2 - 1);
|
||||
gr.drawLine(width*3/4 - 1, height/2 - 1, width*3/4 - 1, height);
|
||||
gr.drawLine(width/2 - 1, height*3/4 - 1, width, height*3/4 - 1);
|
||||
}
|
||||
}.getImage(),
|
||||
new Point(0, 0),
|
||||
"My Copy Cursor"
|
||||
);
|
||||
}
|
||||
|
273
jdk/test/java/awt/dnd/ImageDecoratedDnDNegative/DnDSource.java
Normal file
273
jdk/test/java/awt/dnd/ImageDecoratedDnDNegative/DnDSource.java
Normal file
@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* AWT Button is a DragSource and also a transferable object
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.*;
|
||||
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.MemoryImageSource;
|
||||
|
||||
import java.awt.dnd.*;
|
||||
import java.io.*;
|
||||
|
||||
class DnDSource extends Button implements Transferable,
|
||||
DragGestureListener,
|
||||
DragSourceListener {
|
||||
private DataFlavor df;
|
||||
private transient int dropAction;
|
||||
private final int dragOperation = DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE | DnDConstants.ACTION_LINK;
|
||||
DragSource dragSource = new DragSource();
|
||||
|
||||
DnDSource(String label) {
|
||||
super(label);
|
||||
setBackground(Color.yellow);
|
||||
setForeground(Color.blue);
|
||||
df = new DataFlavor(DnDSource.class, "DnDSource");
|
||||
|
||||
dragSource.createDefaultDragGestureRecognizer(
|
||||
this,
|
||||
dragOperation,
|
||||
this
|
||||
);
|
||||
dragSource.addDragSourceListener(this);
|
||||
}
|
||||
|
||||
public void changeCursor(
|
||||
DragSourceContext dsc,
|
||||
int ra
|
||||
) {
|
||||
java.awt.Cursor c = null;
|
||||
if ((ra & DnDConstants.ACTION_LINK) == DnDConstants.ACTION_LINK)
|
||||
c = DragSource.DefaultLinkDrop;
|
||||
else if ((ra & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE)
|
||||
c = MyCursor.MOVE;//DragSource.DefaultMoveDrop;
|
||||
else if ((ra & DnDConstants.ACTION_COPY) == DnDConstants.ACTION_COPY)
|
||||
c = MyCursor.COPY;
|
||||
else
|
||||
c = MyCursor.NO_DROP;
|
||||
dsc.setCursor(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* a Drag gesture has been recognized
|
||||
*/
|
||||
int iProblem = 0;
|
||||
String[] problem = {"unready", "throw exeption", "good"};
|
||||
public void dragGestureRecognized(DragGestureEvent dge) {
|
||||
System.out.println("starting Drag");
|
||||
if( !DragSource.isDragImageSupported() ) {
|
||||
dge.startDrag(
|
||||
null,
|
||||
this,
|
||||
this);
|
||||
} else {
|
||||
setLabel("Drag ME! (with " + problem[iProblem] + " image)");
|
||||
int w = 100;
|
||||
int h = 100;
|
||||
int pix[] = new int[w * h];
|
||||
int index = 0;
|
||||
for (int y = 0; y < h; y++) {
|
||||
int red = (y * 255) / (h - 1);
|
||||
for (int x = 0; x < w; x++) {
|
||||
int blue = (x * 255) / (w - 1);
|
||||
pix[index++] = (255 << 24) | (red << 16) | blue;
|
||||
}
|
||||
}
|
||||
try{
|
||||
dge.startDrag(
|
||||
null,
|
||||
Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(w, h, pix, 0, w)
|
||||
{
|
||||
@Override
|
||||
public void startProduction(ImageConsumer ic)
|
||||
{
|
||||
switch(iProblem){
|
||||
case 0:
|
||||
//incomplite
|
||||
break;
|
||||
case 1:
|
||||
//exception
|
||||
throw new RuntimeException("test exception 1");
|
||||
default:
|
||||
super.startProduction(ic);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
),
|
||||
new Point(15, 40) {
|
||||
@Override
|
||||
public double getX() {
|
||||
if(2==iProblem){
|
||||
//never happen
|
||||
throw new RuntimeException("test exception 2");
|
||||
}
|
||||
return x;
|
||||
}
|
||||
@Override
|
||||
public Point getLocation(){
|
||||
//never happen
|
||||
throw new RuntimeException("test exception 3");
|
||||
}
|
||||
},
|
||||
this,
|
||||
this);
|
||||
}catch(InvalidDnDOperationException e){
|
||||
if( iProblem<=2 ){
|
||||
System.err.println("good exception: " + e.getMessage() );
|
||||
} else {
|
||||
System.err.println("bad exception");
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
} finally {
|
||||
++iProblem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* as the hotspot enters a platform dependent drop site
|
||||
*/
|
||||
|
||||
public void dragEnter(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dragEnter");
|
||||
changeCursor(
|
||||
dsde.getDragSourceContext(),
|
||||
dsde.getUserAction() & dsde.getDropAction()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* as the hotspot moves over a platform dependent drop site
|
||||
*/
|
||||
public void dragOver(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dragOver");
|
||||
changeCursor(
|
||||
dsde.getDragSourceContext(),
|
||||
dsde.getUserAction() & dsde.getDropAction()
|
||||
);
|
||||
dropAction = dsde.getUserAction() & dsde.getDropAction();
|
||||
System.out.println("dropAction = " + dropAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* as the hotspot exits a platform dependent drop site
|
||||
*/
|
||||
public void dragExit(DragSourceEvent dse) {
|
||||
System.out.println("[Source] dragExit");
|
||||
changeCursor(
|
||||
dse.getDragSourceContext(),
|
||||
DnDConstants.ACTION_NONE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* as the operation changes
|
||||
*/
|
||||
public void dragGestureChanged(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dragGestureChanged");
|
||||
changeCursor(
|
||||
dsde.getDragSourceContext(),
|
||||
dsde.getUserAction() & dsde.getDropAction()
|
||||
);
|
||||
dropAction = dsde.getUserAction() & dsde.getDropAction();
|
||||
System.out.println("dropAction = " + dropAction);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* as the operation completes
|
||||
*/
|
||||
public void dragDropEnd(DragSourceDropEvent dsde) {
|
||||
System.out.println("[Source] dragDropEnd");
|
||||
}
|
||||
|
||||
public void dropActionChanged(DragSourceDragEvent dsde) {
|
||||
System.out.println("[Source] dropActionChanged");
|
||||
dropAction = dsde.getUserAction() & dsde.getDropAction();
|
||||
System.out.println("dropAction = " + dropAction);
|
||||
}
|
||||
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return new DataFlavor[]{df};
|
||||
}
|
||||
|
||||
public boolean isDataFlavorSupported(DataFlavor sdf) {
|
||||
return df.equals(sdf);
|
||||
}
|
||||
|
||||
public Object getTransferData(DataFlavor tdf) throws UnsupportedFlavorException, IOException {
|
||||
Object copy = null;
|
||||
if( !df.equals(tdf) ){
|
||||
throw new UnsupportedFlavorException(tdf);
|
||||
}
|
||||
Container parent = getParent();
|
||||
switch (dropAction) {
|
||||
case DnDConstants.ACTION_COPY:
|
||||
try {
|
||||
copy = this.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
|
||||
oos.writeObject(this);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||
try {
|
||||
copy = ois.readObject();
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
parent.add(this);
|
||||
return copy;
|
||||
|
||||
case DnDConstants.ACTION_MOVE:
|
||||
synchronized (this) {
|
||||
if (parent != null) {
|
||||
parent.remove(this);
|
||||
Label label = new Label("[empty]");
|
||||
label.setBackground(Color.cyan);
|
||||
label.setBounds(this.getBounds());
|
||||
parent.add(label);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
||||
case DnDConstants.ACTION_LINK:
|
||||
return this;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
113
jdk/test/java/awt/dnd/ImageDecoratedDnDNegative/DnDTarget.java
Normal file
113
jdk/test/java/awt/dnd/ImageDecoratedDnDNegative/DnDTarget.java
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Panel is a DropTarget
|
||||
*
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.dnd.*;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
class DnDTarget extends Panel implements DropTargetListener {
|
||||
private int dragOperation = DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE;
|
||||
Color bgColor;
|
||||
Color htColor;
|
||||
|
||||
DnDTarget(Color bgColor, Color htColor) {
|
||||
super();
|
||||
this.bgColor = bgColor;
|
||||
this.htColor = htColor;
|
||||
setBackground(bgColor);
|
||||
setDropTarget(new DropTarget(this, this));
|
||||
}
|
||||
|
||||
|
||||
public void dragEnter(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dragEnter");
|
||||
setBackground(htColor);
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void dragOver(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dragOver");
|
||||
}
|
||||
|
||||
public void dragExit(DropTargetEvent e) {
|
||||
System.out.println("[Target] dragExit");
|
||||
setBackground(bgColor);
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void dragScroll(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dragScroll");
|
||||
}
|
||||
|
||||
public void dropActionChanged(DropTargetDragEvent e) {
|
||||
System.out.println("[Target] dropActionChanged");
|
||||
}
|
||||
|
||||
public void drop(DropTargetDropEvent dtde) {
|
||||
System.out.println("[Target] drop");
|
||||
boolean success = false;
|
||||
if ((dtde.getDropAction() & dragOperation) == 0) {
|
||||
dtde.rejectDrop();
|
||||
Label label = new Label("[no links here :) ]");
|
||||
label.setBackground(Color.cyan);
|
||||
add(label);
|
||||
} else {
|
||||
dtde.acceptDrop(dragOperation);
|
||||
DataFlavor[] dfs = dtde.getCurrentDataFlavors();
|
||||
if (dfs != null && dfs.length >= 1){
|
||||
Transferable transfer = dtde.getTransferable();
|
||||
try {
|
||||
Button button = (Button)transfer.getTransferData(dfs[0]);
|
||||
if( button != null ){
|
||||
add(button);
|
||||
success = true;
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
System.out.println(ioe.getMessage());
|
||||
return;
|
||||
} catch (UnsupportedFlavorException ufe) {
|
||||
System.out.println(ufe.getMessage());
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
setBackground(bgColor);
|
||||
dtde.dropComplete(success);
|
||||
|
||||
invalidate();
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<html>
|
||||
<!--
|
||||
@test %W% %E%
|
||||
@bug 4874070
|
||||
@summary Tests basic DnD functionality
|
||||
@author Your Name: Alexey Utkin area=dnd
|
||||
@run applet ImageDecoratedDnDNegative.html
|
||||
-->
|
||||
<head>
|
||||
<title> ImageDecoratedDnDNegative </title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>ImageDecoratedDnDInOut<br>Bug ID: 4874070</h1>
|
||||
|
||||
<p> See the dialog box (usually in upper left corner) for the test description</p>
|
||||
|
||||
<APPLET CODE="ImageDecoratedDnDNegative.class" WIDTH=200 HEIGHT=200></APPLET>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
test %W% %E%
|
||||
@bug 4874070
|
||||
@summary Tests basic DnD functionality
|
||||
@author Your Name: Alexey Utkin area=dnd
|
||||
@run applet ImageDecoratedDnDNegative.html
|
||||
*/
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.awt.*;
|
||||
import java.awt.Robot;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.geom.Point2D;
|
||||
|
||||
|
||||
import java.awt.dnd.DragSource;
|
||||
|
||||
|
||||
public class ImageDecoratedDnDNegative extends Applet {
|
||||
//Declare things used in the test, like buttons and labels here
|
||||
|
||||
public void init() {
|
||||
//Create instructions for the user here, as well as set up
|
||||
// the environment -- set the layout manager, add buttons,
|
||||
// etc.
|
||||
this.setLayout(new BorderLayout());
|
||||
|
||||
String[] instructions =
|
||||
{
|
||||
"Automatic test.",
|
||||
"A Frame, which contains a yellow button labeled \"Drag ME!\" and ",
|
||||
"a red panel, will appear below. ",
|
||||
"1. The button would be clicked and dragged to the red panel. ",
|
||||
"2. When the mouse enters the red panel during the drag, the panel ",
|
||||
"should turn yellow. On the systems that supports pictured drag, ",
|
||||
"the image under the drag-cursor should appear (ancor is shifted ",
|
||||
"from top-left corner of the picture inside the picture to 10pt in both dimensions ). ",
|
||||
"In WIN32 systems the image under cursor would be visible ONLY over ",
|
||||
"the drop targets with activated extended OLE D\'n\'D support (that are ",
|
||||
"the desktop and IE ).",
|
||||
"3. The mouse would be released.",
|
||||
"The panel should turn red again and a yellow button labeled ",
|
||||
"\"Drag ME!\" should appear inside the panel. You should be able ",
|
||||
"to repeat this operation multiple times."
|
||||
};
|
||||
Sysout.createDialogWithInstructions(instructions);
|
||||
|
||||
}//End init()
|
||||
|
||||
public void moveTo(
|
||||
Robot r,
|
||||
Point b,
|
||||
Point e)
|
||||
{
|
||||
Point2D.Double ee = new Point2D.Double(e.getX(), e.getY());
|
||||
Point2D.Double bb = new Point2D.Double(b.getX(), b.getY());
|
||||
final int count = (int)(ee.distance(bb));
|
||||
Point2D.Double c = new Point2D.Double(bb.getX(), bb.getY());
|
||||
for(int i=0; i<count; ++i){
|
||||
c.setLocation(
|
||||
bb.getX() + (ee.getX()-bb.getX())*i/count,
|
||||
bb.getY() + (ee.getY()-bb.getY())*i/count);
|
||||
r.mouseMove(
|
||||
(int)c.getX(),
|
||||
(int)c.getY());
|
||||
r.delay(5);
|
||||
}
|
||||
r.mouseMove(
|
||||
(int)ee.getX(),
|
||||
(int)ee.getY());
|
||||
r.delay(5);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
Frame f = new Frame("Use keyboard for DnD change");
|
||||
Panel mainPanel;
|
||||
Component dragSource, dropTarget;
|
||||
|
||||
f.setBounds(0, 400, 200, 200);
|
||||
f.setLayout(new BorderLayout());
|
||||
|
||||
mainPanel = new Panel();
|
||||
mainPanel.setLayout(new BorderLayout());
|
||||
|
||||
mainPanel.setBackground(Color.blue);
|
||||
|
||||
dropTarget = new DnDTarget(Color.red, Color.yellow);
|
||||
dragSource = new DnDSource("Drag ME! (" + (DragSource.isDragImageSupported()?"with ":"without") + " image)" );
|
||||
|
||||
mainPanel.add(dragSource, "North");
|
||||
mainPanel.add(dropTarget, "Center");
|
||||
f.add(mainPanel, BorderLayout.CENTER);
|
||||
|
||||
f.setVisible(true);
|
||||
|
||||
Point sourcePoint = dragSource.getLocationOnScreen();
|
||||
Dimension d = dragSource.getSize();
|
||||
sourcePoint.translate(d.width / 2, d.height / 2);
|
||||
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.mouseMove(sourcePoint.x, sourcePoint.y);
|
||||
Point start = new Point(
|
||||
sourcePoint.x,
|
||||
sourcePoint.y);
|
||||
Point out = new Point(
|
||||
sourcePoint.x + d.width / 2 + 10,
|
||||
sourcePoint.y + d.height);
|
||||
|
||||
Point cur = start;
|
||||
for(int i = 2; i < 5; ++i){
|
||||
moveTo(robot, cur, start);
|
||||
robot.delay(500);
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
robot.delay(500);
|
||||
moveTo(robot, start, out);
|
||||
robot.keyPress(KeyEvent.VK_CONTROL);
|
||||
Point drop = new Point(
|
||||
(int)start.getX(),
|
||||
(int)start.getY() + (d.height + 5) * i );
|
||||
moveTo(robot, out, drop);
|
||||
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
robot.delay(10);
|
||||
robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||
robot.delay(1000);
|
||||
|
||||
cur = drop;
|
||||
}
|
||||
} catch( Exception e){
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("test failed: drop was not successful with exception " + e);
|
||||
}
|
||||
}// start()
|
||||
}// class DnDAcceptanceTest
|
||||
|
||||
|
||||
/**
|
||||
* *************************************************
|
||||
* Standard Test Machinery
|
||||
* DO NOT modify anything below -- it's a standard
|
||||
* chunk of code whose purpose is to make user
|
||||
* interaction uniform, and thereby make it simpler
|
||||
* to read and understand someone else's test.
|
||||
* **************************************************
|
||||
*/
|
||||
class Sysout {
|
||||
private static TestDialog dialog;
|
||||
|
||||
public static void createDialogWithInstructions(String[] instructions) {
|
||||
dialog = new TestDialog(new Frame(), "Instructions");
|
||||
dialog.printInstructions(instructions);
|
||||
dialog.show();
|
||||
println("Any messages for the tester will display here.");
|
||||
}
|
||||
|
||||
public static void createDialog() {
|
||||
dialog = new TestDialog(new Frame(), "Instructions");
|
||||
String[] defInstr = {"Instructions will appear here. ", ""};
|
||||
dialog.printInstructions(defInstr);
|
||||
dialog.show();
|
||||
println("Any messages for the tester will display here.");
|
||||
}
|
||||
|
||||
|
||||
public static void printInstructions(String[] instructions) {
|
||||
dialog.printInstructions(instructions);
|
||||
}
|
||||
|
||||
|
||||
public static void println(String messageIn) {
|
||||
dialog.displayMessage(messageIn);
|
||||
}
|
||||
|
||||
}// Sysout class
|
||||
|
||||
|
||||
class TestDialog extends Dialog {
|
||||
|
||||
TextArea instructionsText;
|
||||
TextArea messageText;
|
||||
int maxStringLength = 80;
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public TestDialog(Frame frame, String name) {
|
||||
super(frame, name);
|
||||
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||
instructionsText = new TextArea("", 15, maxStringLength, scrollBoth);
|
||||
add("North", instructionsText);
|
||||
|
||||
messageText = new TextArea("", 5, maxStringLength, scrollBoth);
|
||||
add("South", messageText);
|
||||
|
||||
pack();
|
||||
|
||||
show();
|
||||
}// TestDialog()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void printInstructions(String[] instructions) {
|
||||
//Clear out any current instructions
|
||||
instructionsText.setText("");
|
||||
|
||||
//Go down array of instruction strings
|
||||
|
||||
String printStr, remainingStr;
|
||||
for (int i = 0; i < instructions.length; i++) {
|
||||
//chop up each into pieces maxSringLength long
|
||||
remainingStr = instructions[i];
|
||||
while (remainingStr.length() > 0) {
|
||||
//if longer than max then chop off first max chars to print
|
||||
if (remainingStr.length() >= maxStringLength) {
|
||||
//Try to chop on a word boundary
|
||||
int posOfSpace = remainingStr.
|
||||
lastIndexOf(' ', maxStringLength - 1);
|
||||
|
||||
if (posOfSpace <= 0) posOfSpace = maxStringLength - 1;
|
||||
|
||||
printStr = remainingStr.substring(0, posOfSpace + 1);
|
||||
remainingStr = remainingStr.substring(posOfSpace + 1);
|
||||
}
|
||||
//else just print
|
||||
else {
|
||||
printStr = remainingStr;
|
||||
remainingStr = "";
|
||||
}
|
||||
|
||||
instructionsText.append(printStr + "\n");
|
||||
|
||||
}// while
|
||||
|
||||
}// for
|
||||
|
||||
}//printInstructions()
|
||||
|
||||
//DO NOT call this directly, go through Sysout
|
||||
public void displayMessage(String messageIn) {
|
||||
messageText.append(messageIn + "\n");
|
||||
}
|
||||
|
||||
}// TestDialog class
|
||||
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Image generator for cursor and drag
|
||||
*/
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public abstract class ImageGenerator
|
||||
{
|
||||
public int width;
|
||||
public int height;
|
||||
private final BufferedImage bi;
|
||||
public ImageGenerator(int _width, int _height, Color bgColor)
|
||||
{
|
||||
width = _width;
|
||||
height = _height;
|
||||
bi = new BufferedImage(
|
||||
width,
|
||||
height,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics gr = bi.getGraphics();
|
||||
if(null==bgColor){
|
||||
bgColor = Color.WHITE;
|
||||
}
|
||||
gr.setColor(bgColor);
|
||||
gr.fillRect(0, 0, width, height);
|
||||
paint(gr);
|
||||
gr.dispose();
|
||||
}
|
||||
public Image getImage() { return bi; }
|
||||
|
||||
public abstract void paint(Graphics gr);
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* An interface provides a set of custom cursors
|
||||
*/
|
||||
|
||||
public interface MyCursor {
|
||||
public static final java.awt.Cursor NO_DROP = Toolkit.getDefaultToolkit().createCustomCursor(
|
||||
new ImageGenerator(32, 32, new Color(0xff, 0xff, 0xff, 0x00) ) {
|
||||
@Override public void paint(Graphics gr) {
|
||||
gr.setColor(Color.GREEN);
|
||||
((Graphics2D)gr).setStroke(new BasicStroke(3));
|
||||
|
||||
gr.translate(width/2, height/2);
|
||||
int R = width/4;
|
||||
gr.drawOval(-R, -R, 2*R, 2*R);
|
||||
gr.drawLine(-R, R, R, -R);
|
||||
}
|
||||
}.getImage(),
|
||||
new Point(0, 0),
|
||||
"My NoDrop Cursor"
|
||||
);
|
||||
public static final java.awt.Cursor MOVE = Toolkit.getDefaultToolkit().createCustomCursor(
|
||||
new ImageGenerator(32, 32, new Color(0xff, 0xff, 0xff, 0x00) ) {
|
||||
@Override public void paint(Graphics gr) {
|
||||
gr.setColor(Color.GREEN);
|
||||
((Graphics2D)gr).setStroke(new BasicStroke(3));
|
||||
|
||||
gr.drawLine(0, 0, width, height);
|
||||
gr.drawLine(0, 0, width/2, 0);
|
||||
gr.drawLine(0, 0, 0, height/2);
|
||||
}
|
||||
}.getImage(),
|
||||
new Point(0, 0),
|
||||
"My Move Cursor"
|
||||
);
|
||||
public static final java.awt.Cursor COPY = Toolkit.getDefaultToolkit().createCustomCursor(
|
||||
new ImageGenerator(32, 32, new Color(0xff, 0xff, 0xff, 0x00) ) {
|
||||
@Override public void paint(Graphics gr) {
|
||||
gr.setColor(Color.GREEN);
|
||||
((Graphics2D)gr).setStroke(new BasicStroke(3));
|
||||
//arrow
|
||||
gr.drawLine(0, 0, width/2, height/2);
|
||||
gr.drawLine(0, 0, width/2, 0);
|
||||
gr.drawLine(0, 0, 0, height/2);
|
||||
//plus
|
||||
gr.drawRect(width/2 - 1, height/2 -1, width/2 - 1, height/2 - 1);
|
||||
gr.drawLine(width*3/4 - 1, height/2 - 1, width*3/4 - 1, height);
|
||||
gr.drawLine(width/2 - 1, height*3/4 - 1, width, height*3/4 - 1);
|
||||
}
|
||||
}.getImage(),
|
||||
new Point(0, 0),
|
||||
"My Copy Cursor"
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user