package ika.gui;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
/**
* BorderedDropTarget adds a border to a JComponent when the user drags some
* data over it. This serves as visual feedback for dragging operations. The
* border should be drawn when the data can be accepted by the JComponent.
* Derived classes should overwrite isDataFlavorSupported to customize the
* appearance of the border.
*/
public class BorderedDropTarget implements DropTargetListener {
/** The component for which a border will be created. */
protected JComponent targetComponent;
/** The width of the border that is temporarily displayed. */
private int borderWidth = 3;
public BorderedDropTarget(JComponent targetComponent) {
this.targetComponent = targetComponent;
// set up drop target: attach this drop target to the passed component.
new DropTarget(this.targetComponent, this);
}
/**
* Shows a border. A standard higlighting color is used to draw a LineBorder.
*/
private void showBorder() {
Color color = UIManager.getColor("Table.selectionBackground");
Border newBorder = BorderFactory.createLineBorder(color, this.borderWidth);
Border oldBorder = this.targetComponent.getBorder();
Border compoundBorder = BorderFactory.createCompoundBorder(newBorder, oldBorder);
this.targetComponent.setBorder(compoundBorder);
}
/**
* Hides the border. The currently visible border is replaced by the
* previous one.
*/
private void hideBorder() {
Border border = this.targetComponent.getBorder();
if (border instanceof CompoundBorder) {
CompoundBorder compoundBorder = (CompoundBorder)border;
this.targetComponent.setBorder(compoundBorder.getInsideBorder());
} else {
this.targetComponent.setBorder(null);
}
}
/**
* The mouse entered the component. Show the border if the dragged data
* can be accepted.
*/
public void dragEnter(DropTargetDragEvent dtde) {
// there is a bug / limitation in Java DnD:
// Transferable does not return the transfer data on dragEnter events.
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4378091
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4248542
// It is therefore impossible to test in dragEnter whether the data can be
// accepted.
showBorder();
}
/**
* The mouse left the component. Hide the border again.
*/
public void dragExit(DropTargetEvent dte) {
hideBorder();
}
public void dragOver(DropTargetDragEvent dtde) {
}
/**
* The dragged data is dropped over the component. Hide the border.
* Derived classes should overwrite drop and hide the border by
* calling super.drop(dtde);
*/
public void drop(DropTargetDropEvent dtde) {
hideBorder();
}
public void dropActionChanged(DropTargetDragEvent dtde) {
}
/** Getter for the width of the border. */
public int getBorderWidth() {
return borderWidth;
}
/* Setter for the width of the border. */
public void setBorderWidth(int borderWidth) {
this.borderWidth = borderWidth;
}
}