package org.limewire.ui.swing.dnd; import java.awt.AlphaComposite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JPanel; import org.jdesktop.application.Resource; import org.limewire.inject.LazySingleton; import org.limewire.ui.swing.util.GuiUtils; import com.google.inject.Inject; /** * Panel which gets installed as the glass pane of a Window. * This glass pane creates and displays semi-transparent images * over the main application. * <p> * It is the responsibility of drag listeners to update the positioning, * image and visibility of this glass pane. */ @LazySingleton public class GhostDragGlassPane extends JPanel { @Resource private Icon dragIconAccept; @Resource private Icon dragIconReject; private Icon dragIcon; private float alpha = 0.85f; private BufferedImage dragged = null; private Point location = new Point(0, 0); private Point oldLocation = new Point(0, 0); private int width; private int height; private Rectangle visibleRect = null; @Inject public GhostDragGlassPane() { setOpaque(false); GuiUtils.assignResources(this); this.dragIcon = dragIconAccept; updateDragImage(); } private void updateDragImage() { dragged = new BufferedImage(dragIcon.getIconWidth(), dragIcon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); Graphics g = dragged.getGraphics(); g.drawImage(((ImageIcon)dragIcon).getImage(), 0, 0, null); width = dragIcon.getIconWidth(); height = dragIcon.getIconHeight(); } /** * Relocates the image to this point. The image is displayed * to the right of this location and 50% above/below the * y coordinate of this location. */ public void setPoint(Point location) { this.oldLocation = this.location; this.location = location; } /** * Returns the rectangle of where changes have occurred * on the glass pane. This can greatly improve performance * by not repainting the entire glass pane. */ public Rectangle getRepaintRect() { int x = (int) (location.getX()); int y = (int) (location.getY() - (height/ 2)); int x2 = (int) (oldLocation.getX()); int y2 = (int) (oldLocation.getY() - (height/ 2)); return new Rectangle(x, y, width, height).union(new Rectangle(x2, y2, width, height)); } @Override protected void paintComponent(Graphics g) { if (dragged == null || !isVisible()) { return; } Graphics2D g2 = (Graphics2D) g.create(); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int x = (int) (location.getX()); int y = (int) (location.getY() - (height/ 2)); if (visibleRect != null) { g2.setClip(visibleRect); } g2.drawImage(dragged, x, y, width, height, null); g2.dispose(); } public void setAccept(boolean accept) { Icon oldIcon = dragIcon; dragIcon = accept ? dragIconAccept : dragIconReject; if(dragIcon != oldIcon) { updateDragImage(); repaint(); } } }