Class PaletteDragSupport
Purpose
Every palette panel that lets the user drag items onto a canvas needs the
same Swing DnD boilerplate: create a DragSource gesture recogniser,
start the drag with an optional drag image, and clean up the selection when
the drag ends. PaletteDragSupport encapsulates that ceremony so that
palette panels only have to supply two things:
- A
PaletteDragSupport.PaletteDragSourcecallback that decides, for a given drag origin point, whatTransferableto carry — ornullto cancel the drag. - Optionally, a
PaletteDragSupport.DragImageProvidercallback that builds aBufferedImageto display under the cursor during the drag.
Usage
// In a palette panel constructor:
new PaletteDragSupport(myTable, origin -> {
int row = myTable.rowAtPoint(origin);
int col = myTable.columnAtPoint(origin);
if (row < 0 || col < 1) return null; // cancel drag
MyDescriptor d = buildDescriptor(row, col);
return d != null ? new MyTransferable(d) : null;
});
To supply a drag image in addition to the transferable:
new PaletteDragSupport(myTable,
origin -> buildTransferable(origin),
origin -> buildDragImage(origin),
32); // drag image size in pixels
Cleanup callback
PaletteDragSupport calls PaletteDragSupport.PaletteDragSource.onDragEnd() on the
EDT after every drag attempt — regardless of whether the drop succeeded or
was cancelled, and regardless of whether the drag was even started (i.e. the
callback returned null). Palette panels use this to clear their
selection highlight.
Thread safety
All Swing DnD callbacks arrive on the EDT. PaletteDragSupport does
not introduce any additional threading.
Design notes
Only the drag side of DnD is abstracted here. Drop targets are domain-specific: a map canvas and a network-layout canvas need completely different logic to unpack a payload and create the right item type. Keeping drop-target logic in the canvas implementations avoids forcing unrelated domains into a shared type hierarchy.
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfaceOptionally supplies aBufferedImageto display under the cursor during a drag.static interfaceSupplies the drag payload and receives end-of-drag notification. -
Constructor Summary
ConstructorsConstructorDescriptionPaletteDragSupport(JComponent source, PaletteDragSupport.PaletteDragSource dragSource) Install drag support onsourcewith no drag image.PaletteDragSupport(JComponent source, PaletteDragSupport.PaletteDragSource dragSource, PaletteDragSupport.DragImageProvider imageProvider) Install drag support onsourcewith a custom drag image. -
Method Summary
Modifier and TypeMethodDescriptionstatic BufferedImagescaleToDragImage(Image source, int sidePixels) Scale aImageinto a new squareBufferedImagesuitable for use as a drag image.
-
Constructor Details
-
PaletteDragSupport
Install drag support onsourcewith no drag image.The drag cursor will be the platform default (typically a small arrow with a copy badge). Use
PaletteDragSupport(JComponent, PaletteDragSource, DragImageProvider)to supply a custom drag image.- Parameters:
source- the Swing component to install the gesture recogniser on; must not benulldragSource- callback that creates the payload and handles cleanup; must not benull- Throws:
IllegalArgumentException- if either argument isnull
-
PaletteDragSupport
public PaletteDragSupport(JComponent source, PaletteDragSupport.PaletteDragSource dragSource, PaletteDragSupport.DragImageProvider imageProvider) Install drag support onsourcewith a custom drag image.The image is only used when
DragSource.isDragImageSupported()returnstrue. On platforms that do not support drag images theimageProvideris never called and the drag falls back to the default cursor.The size of the drag image is entirely the responsibility of the
PaletteDragSupport.DragImageProvider— it returns a fully-renderedBufferedImageof whatever dimensions are appropriate for the palette's content.scaleToDragImage(java.awt.Image, int)is provided as a convenience for the common case of scaling an existing icon image.- Parameters:
source- the Swing component to install the gesture recogniser on; must not benulldragSource- callback that creates the payload and handles cleanup; must not benullimageProvider- callback that builds the drag image, ornullfor no custom image- Throws:
IllegalArgumentException- ifsourceordragSourceisnull
-
-
Method Details
-
scaleToDragImage
Scale aImageinto a new squareBufferedImagesuitable for use as a drag image.This is provided as a convenience for
PaletteDragSupport.DragImageProviderimplementations that already have a loaded image and only need to scale it. Rendering hints are set for bilinear interpolation, quality rendering, and anti-aliasing.- Parameters:
source- the source image to scale; must not benullsidePixels- the side length in pixels of the output square image; must be positive- Returns:
- a new
BufferedImageof sizesidePixels × sidePixels - Throws:
IllegalArgumentException- ifsourceisnullorsidePixelsis not positive
-