Some reader favorites:
EJB fundamentals and session beans
Create a scrollable virtual desktop in Swing
Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API
Java 2 (formerly JDK 1.2) introduced the ability to transfer data using the familiar drag and drop (D&D) metaphor. In Java
2, D&D utilizes the underlying data-transfer mechanism introduced in JDK 1.1 (java.awt.datatransfer) for use with the clipboard. Although this article discusses D&D operations in the context of GUI components, the specification
includes no restrictions that prevent direct programmatic operations.
To develop the D&D metaphor, Java 2 defines several new classes in package java.awt.dnd. Please note: The GUI components used in this article are Swing components. In actuality, any subclass of java.awt.Component may be used.
First, we'll look at how a GUI component representing the data source of a D&D operation maintains an association with a java.awt.dnd.DropSource object.
Second, we'll examine how another GUI component representing the destination of the data of a D&D operation maintains an association
with a java.awt.dnd.DropTarget object.
Finally, we'll wrap up with a java.awt.datatransfer.Transferable object that encapsulates the data transferred between the DragSource and DropTarget objects.
To download the source code in either zip or tar formats, see Resources.

When the Transferable object encapsulates data, it makes the data available to DropTarget in a variety of DataFlavors. For a local transfer within the same JVM (Java virtual machine), Transferable provides an object reference.
However, for transfers to another JVM or to the native system, this wouldn't make any sense, so a DataFlavor using a java.io.InputStream subclass usually is provided. (While a discussion of data transfer classes is beyond the scope of this article, you will
find a linked list of previous JavaWorld articles on this topic in the Resources section below.)
When invoking a drag and drop operation, you may request various drag and drop actions. The DnDConstants class defines the class variables for the supported actions:
DragSource leaves the data intact
DragSource deletes the data upon successful completion of the drop
DragSource will perform either action requested by the DropTargetFor a GUI component to act as the source of a D&D operation, it must be associated with five objects:

A common way to obtain a DragSource object is to use one instance per JVM. Class method DragSource.getDefaultDragSource will obtain a shared DragSource object that is used for the lifetime of the JVM. Another option is to provide one DragSource per instance of the Component class. With this option, however, you accept responsibility for implementation.
The user gesture or set of gestures that initiates a D&D operation will vary per component, platform, and device:
| Click left mouse button | Move |
| Control, left mouse button | Copy |
| Shift-Control, left mouse button | Link |
| Shift, BTransfer (middle button) | Move |
| Control, BTransfer | Copy |
| Shift-Control, BTransfer | Link |
A DragGestureRecognizer encapsulates these implementation details, shielding you from platform dependencies. The instance method dragSource.createDefaultDragGestureRecognizer() will obtain a recognizer and associate it with a component, action, and DragGestureListener.
This example creates a subclass of a Swing label (JLabel). In its constructor, the necessary classes and associations are made for it to act as a drag source for either a copy or move operation. We'll discuss listeners next. Here's the first step in making any draggable component:
public class DragLabel extends JLabel {
public DragLabel(String s) {
this.setText(s);
this.dragSource = DragSource.getDefaultDragSource();
this.dgListener = new DGListener();
this.dsListener = new DSListener();
// component, action, listener
this.dragSource.createDefaultDragGestureRecognizer(
this, DnDConstants.ACTION_COPY_OR_MOVE, this.dgListener );
}
private DragSource dragSource;
private DragGestureListener dgListener;
private DragSourceListener dsListener;
}
When the DragGestureRecognizer associated with the GUI component recognizes a D&D action, it messages the registered DragGestureListener. Next, the DragGestureListener sends the DragSource a startDrag message telling it to initiate the drag:
interface DragGestureListener {
public void dragGestureRecognized(DragGestureEvent e);
}
When the DragSource receives the startDrag message, it creates a DragSourceContext context object. This object tracks the state of the operation by listening to a native DragSourceContextPeer. In this situation, the DragSource may be obtained from the Event object or by an instance variable.
The particular DragSourceListener that will be informed during the progress of the D&D operation is specified as a formal parameter to dragGestureRecognized. The initial drag cursor that shows the preliminary state of the D&D operation is also specified as a parameter. If the draggable
component cannot accept drops, the initial cursor should be DragSource.DefaultCopyNoDrop.
If your platform allows it, you may specify an optional "drag image" to be displayed in addition to the cursors. Win32 platforms, however, do not support drag images.

A Transferable object encapsulates the data -- most likely associated with the Component (that is, the label's text) -- that will be transferred. Here's how to start a drag:
public void dragGestureRecognized(DragGestureEvent e) {
// check to see if action is OK ...
try {
Transferable transferable = ...
//initial cursor, transferable, dsource listener
e.startDrag(DragSource.DefaultCopyNoDrop, transferable, dsListener);
// or if dragSource is an instance variable:
// dragSource.startDrag(e, DragSource.DefaultCopyNoDrop, transferable,
dsListener);
}catch( InvalidDnDOperationException idoe ) {
System.err.println( idoe );
}
}
The java.awt.datatransfer.StringSelection class works well for transfers within the same JVM but suffers from a ClassCastException when used in inter-JVM cases. To solve this problem, you'll have to provide a custom Transferable object.
The custom Transferable object creates instances of the DataFlavors it wishes to provide. The Transferable interface directs method getTransferDataFlavors() to return an array of these flavors. To this end, we create a java.util.List representation of this array to facilitate the implementation of isDataFlavorSupported(DataFlavor).
This example provides two flavors. Since we're simply transferring text data, we can use the two predefined DataFlavor flavors. For local transfers (within the same JVM), we can use DataFlavor.stringFlavor. For nonlocal transfers, we prefer DataFlavor.plainTextFlavor, since its internal representation class is a java.io.InputStream.
Moreover, we could define our own DataFlavors to map to MIME types such as image/JPEG, or define custom-text charsets such as Latin-1; but we'll save that discussion for
a future article.
Although the Transferable doesn't necessarily have to be a ClipboardOwner for drag and drop, enabling this functionality will make it available for clipboard transfers.
Let's see the definition of a simple Transferable for text data:
public class StringTransferable implements Transferable, ClipboardOwner {
public static final DataFlavor plainTextFlavor = DataFlavor.plainTextFlavor;
public static final DataFlavor localStringFlavor = DataFlavor.stringFlavor;
public static final DataFlavor[] flavors = {
StringTransferable.plainTextFlavor,
StringTransferable.localStringFlavor
};
private static final List flavorList = Arrays.asList( flavors );
public synchronized DataFlavor[] getTransferDataFlavors() {
return flavors;
}
public boolean isDataFlavorSupported( DataFlavor flavor ) {
return (flavorList.contains(flavor));
}
The Transferable provides the data for the flavors it supports via its getTransferData method. However, if an unsupported flavor is requested, an exception will be thrown. If a local (same JVM) transfer is requested
via the StringTransferable.localStringFlavor, an object reference is returned. Note: Object references don't make sense outside of the JVM.
A subclass of java.io.InputStream should be provided for native-to-Java or inter-JVM requests.
For StringTransferable.plainTextFlavor requests, getTransferData returns a java.io.ByteArrayInputStream. Text data may have different character encodings as specified in the MIME specification. (For more on the MIME specification,
see Resources.)
Transferable interface encapsulates transferred dataFree Download - 5 Minute Product Review. When slow equals Off: Manage the complexity of Web applications - Symphoniq
![]()
Free Download - 5 Minute Product Review. Realize the benefits of real user monitoring in less than an hour. - Symphoniq