提交 64adfbf6 编写于 作者: U uta

4874070: invoking DragSource's startDrag with an Image renders no image on drag

Reviewed-by: art, denis, alexp
上级 fcba311b
......@@ -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
......
此差异已折叠。
/*
* 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);
......
/*
* 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)
......
/*
* 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) {
......
/*
* 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
/*
* 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_ */
/*
* 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
);
}
/*
* 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
/*
* 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;
}
......
/*
* 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 */
/*
* 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
......
/*
* 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
*/
......
/*
* 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.
......
/*
* 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
/*
* 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
<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>
/*
* 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
/*
* 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);
}
}
/*
* 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;
}
}
}
/*
* 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();
}
}
<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>
/*
* 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
/*
* 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);
}
/*
* 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"
);
}
/*
* 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;
}
}
}
/*
* 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();
}
}
<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>
/*
* 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
/*
* 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);
}
/*
* 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"
);
}
/*
* 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;
}
}
}
/*
* 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();
}
}
<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>
/*
* 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
/*
* 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);
}
/*
* 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"
);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册