[ Team LiB ] Previous Section Next Section

14.1 Simple Swing Data Transfer

We begin with an examination of the built-in data transfer capabilities of Swing components and how to perform simple customizations. As a general rule, Swing components that display text and allow it to be selected (JList and JTable, for example, but not JLabel) support Copy and Drag operations. Components that display editable text typically support Cut, Paste, and Drop operations as well. JPasswordField is a special case: it supports Paste and Drop, but because of the sensitivity of password data, does not allow its masked text to be dragged, cut, or copied to the clipboard. Finally, JColorChooser allows colors to be dragged, and JFileChooser allows files to be dragged.

Swing components that support dragging do not enable it by default. To enable drags in a component that supports it, pass true to setDragEnabled( ). Components that do not support dragging at all do not define this setDragEnabled( ) method.

Swing data transfer is enabled by a TransferHandler object. Components that support data transfer by default have a default TransferHandler installed. The TransferHandler( ) constructor method takes a JavaBeans property name as its sole argument. A TransferHandler created in this way is responsible for transferring the value of the named property. In a Cut, Copy, or Drag operation, it reads the value of the named property and makes it available for transfer. In a Paste or Drop operation, it reads the transferred data and then attempts to set the named property to the specified value. If the named property is read-only, the TransferHandler will enable only Copy and Drag operations, not Cut, Paste, or Drop operations. If the data to be transferred is not available through a property, or if you want to support pastes and drops of more than one type of data, you can subclass TransferHandler to add these capabilities.

Example 14-1 illustrates two simple customizations of the default Swing data transfer behavior. First, it registers custom TransferHandler objects to support Drag and Drop of colors. Second, it enables Drag operations from a JLabel component by registering a MouseMotionListener to detect drag gestures and initiate the drag through the TransferHandler. When you run the program, it allows you to drag the foreground color of the first JLabel and drop it on the second JLabel, which will use the dropped color as its background. This example is more interesting if you also display a JColorChooser component at the same time, using the ShowBean program of Chapter 11. To enable drags from the JColorChooser, you must set its dragEnabled property:

java je3.gui.ShowBean javax.swing.JColorChooser dragEnabled=true

Note that the JColorChooser component does not allow drags from the tiny color swatches in the main part of the window. Instead, you must select a color and then drag it from the sample swatch at the bottom of the window.

Example 14-1. ColorDrag.java
package je3.datatransfer;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/** 
 * Simple Drag-and-Drop customization: drag the foreground color from the first
 * label and drop it as the background color into the second one.  Try it also
 * using the ShowBean program to display a JColorChooser component with
 * dragEnabled=true.
 */
public class ColorDrag {
    public static void main(String args[  ]) {
        // Create two JLabel objects
        final JLabel label1 = new JLabel("Drag here"); 
        JLabel label2 = new JLabel("Drop here");

        // Register TransferHandler objects on them: label1 transfers its 
        // foreground color and label2 transfers its background color.
        label1.setTransferHandler(new TransferHandler("foreground"));
        label2.setTransferHandler(new TransferHandler("background"));

        // Give label1 a foreground color other than the default
        // Make label2 opaque so it displays its background color
        label1.setForeground(new Color(100, 100, 200));
        label2.setOpaque(true);

        // Now look for drag gestures over label1.  When one occurs, 
        // tell the TransferHandler to begin a drag.
        // Exercise: modify this gesture recognition so that the drag doesn't
        // begin until the mouse has moved 4 pixels.  This helps to keep
        // drags distinct from sloppy clicks.  To do this, you'll need both
        // a MouseListener and a MouseMotionListener.
        label1.addMouseMotionListener(new MouseMotionAdapter( ) {
                public void mouseDragged(MouseEvent e) {
                    TransferHandler handler = label1.getTransferHandler( );
                    handler.exportAsDrag(label1, e, TransferHandler.COPY);
                }
            });

        // Create a window, add the labels, and make it all visible.
        JFrame f = new JFrame("ColorDrag");
        f.getContentPane( ).setLayout(new FlowLayout( ));
        f.getContentPane( ).add(label1);
        f.getContentPane( ).add(label2);
        f.pack( );
        f.setVisible(true);
    }
}
    [ Team LiB ] Previous Section Next Section