com.sun.jna.platform.dnd.GhostedDragImage Maven / Gradle / Ivy
Show all versions of jna-platform Show documentation
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
*
* The contents of this file is dual-licensed under 2
* alternative Open Source/Free licenses: LGPL 2.1 or later and
* Apache License 2.0. (starting with JNA version 4.0.0).
*
* You can freely decide which license you want to apply to
* the project.
*
* You may obtain a copy of the LGPL License at:
*
* http://www.gnu.org/licenses/licenses.html
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "LGPL2.1".
*
* You may obtain a copy of the Apache License at:
*
* http://www.apache.org/licenses/
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "AL2.0".
*/
package com.sun.jna.platform.dnd;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.dnd.DragSource;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Area;
import javax.swing.Icon;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import com.sun.jna.platform.WindowUtils;
/** Provide a ghosted drag image for use during drags where
* {@link DragSource#isDragImageSupported} returns false.
* Its location in screen coordinates may be changed via {@link #move}.
* When the image is no longer needed, invoke {@link #dispose}, which
* hides the graphic immediately, or {@link #returnToOrigin}, which
* moves the image to its original location and then disposes it.
*/
public class GhostedDragImage {
private static final float DEFAULT_ALPHA = .5f;
private Window dragImage;
// Initial image position, relative to drag source
private Point origin;
/** Create a ghosted drag image, using the given icon.
* @param dragSource source of the drag
* @param icon image to be drawn
* @param initialScreenLoc initial screen location of the image
* @param cursorOffset offset of the cursor from the image origin
*/
public GhostedDragImage(Component dragSource, final Icon icon, Point initialScreenLoc,
final Point cursorOffset) {
Window parent = dragSource instanceof Window
? (Window)dragSource : SwingUtilities.getWindowAncestor(dragSource);
// FIXME ensure gc is compatible (X11)
GraphicsConfiguration gc = parent.getGraphicsConfiguration();
dragImage = new Window(JOptionPane.getRootFrame(), gc) {
private static final long serialVersionUID = 1L;
public void paint(Graphics g) {
icon.paintIcon(this, g, 0, 0);
}
public Dimension getPreferredSize() {
return new Dimension(icon.getIconWidth(), icon.getIconHeight());
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
public Dimension getMaximumSize() {
return getPreferredSize();
}
};
dragImage.setFocusableWindowState(false);
dragImage.setName("###overrideRedirect###");
Icon dragIcon = new Icon() {
public int getIconHeight() {
return icon.getIconHeight();
}
public int getIconWidth() {
return icon.getIconWidth();
}
public void paintIcon(Component c, Graphics g, int x, int y) {
g = g.create();
Area area = new Area(new Rectangle(x, y, getIconWidth(), getIconHeight()));
// X11 needs more of a window due to differences in event processing
area.subtract(new Area(new Rectangle(x + cursorOffset.x-1, y + cursorOffset.y-1, 3, 3)));
g.setClip(area);
icon.paintIcon(c, g, x, y);
g.dispose();
}
};
dragImage.pack();
WindowUtils.setWindowMask(dragImage, dragIcon);
WindowUtils.setWindowAlpha(dragImage, DEFAULT_ALPHA);
move(initialScreenLoc);
dragImage.setVisible(true);
}
/** Set the transparency of the ghosted image.
* @param alpha transparency level
*/
public void setAlpha(float alpha) {
WindowUtils.setWindowAlpha(dragImage, alpha);
}
/** Make all ghosted images go away. */
public void dispose() {
dragImage.dispose();
dragImage = null;
}
/** Move the ghosted image to the requested location.
* @param screenLocation Where to draw the image, in screen coordinates
*/
public void move(Point screenLocation) {
if (origin == null) {
origin = screenLocation;
}
dragImage.setLocation(screenLocation.x, screenLocation.y);
}
private static final int SLIDE_INTERVAL = 1000/30;
/** Animate the ghosted image returning to its origin. */
public void returnToOrigin() {
final Timer timer = new Timer(SLIDE_INTERVAL, null);
timer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Point location = dragImage.getLocationOnScreen();
Point dst = new Point(origin);
int dx = (dst.x - location.x)/2;
int dy = (dst.y - location.y)/2;
if (dx != 0 || dy != 0) {
location.translate(dx, dy);
move(location);
}
else {
timer.stop();
dispose();
}
}
});
timer.setInitialDelay(0);
timer.start();
}
}