Java SE 6 has greatly improved drag-and-drop for Swing components. These improve- ments have to do with telling a component how to determine drop locations and having Swing provide all relevant transfer information during a transfer. Let’s consider the first improvement in the context of Swing’s text components—javax.swing.JTextComponent subclasses.
Text components move the caret (text-insertion point) to the location under the mouse during a drag-and-drop operation, to visually identify where selected text will be dropped. Prior to Java SE 6, this action temporarily cleared the selection, which caused the user to lose the context of the text being dragged.
Java SE 6 remedies this situation by introducing a public final void setDropMode(DropMode dropMode)method in the JTextComponentclass, as well as a javax.swing.DropModeenumeration, whose constants identify the means by which a component tracks and indicates a drop location during drag-and-drop. Of the various constants provided by this enumeration, only DropMode.INSERTand DropMode.
USE_SELECTIONare valid for text components.
The DropMode.INSERTconstant specifies that the drop location should be tracked in terms of the position where the data will be inserted. This implies that selected text is not cleared (even temporarily). In contrast, DropMode.USE_SELECTIONspecifies that a text component’s caret will be used to track the drop location, so selected text will be tem- porarily deselected.
I have created an application that demonstrates the difference between these drop modes. This application’s source code appears in Listing 4-2.
Listing 4-2.TextDrop.java // TextDrop.java
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class TextDrop extends JFrame {
private JTextField txtField1, txtField2;
public TextDrop (String title) {
super (title);
setDefaultCloseOperation (EXIT_ON_CLOSE);
getContentPane ().setLayout (new GridLayout (3, 1));
JPanel pnl = new JPanel ();
pnl.add (new JLabel ("Text field 1"));
txtField1 = new JTextField ("Text1", 25);
txtField1.setDragEnabled (true);
pnl.add (txtField1);
getContentPane ().add (pnl);
pnl = new JPanel ();
pnl.add (new JLabel ("Text field 2"));
txtField2 = new JTextField ("Text2", 25);
txtField2.setDragEnabled (true);
pnl.add (txtField2);
getContentPane ().add (pnl);
pnl = new JPanel ();
pnl.add (new JLabel ("Drop mode"));
JComboBox cb = new JComboBox (new String [] { "USE_SELECTION",
"INSERT" });
cb.setSelectedIndex (0);
ActionListener al;
al = new ActionListener () {
public void actionPerformed (ActionEvent e) {
JComboBox cb = (JComboBox) e.getSource ();
int index = cb.getSelectedIndex ();
if (index == 0) {
txtField1.setDropMode (DropMode.USE_SELECTION);
txtField2.setDropMode (DropMode.USE_SELECTION);
} else {
txtField1.setDropMode (DropMode.INSERT);
txtField2.setDropMode (DropMode.INSERT);
} }
};
cb.addActionListener (al);
pnl.add (cb);
getContentPane ().add (pnl);
pack ();
setVisible (true);
}
public static void main (String [] args) {
Runnable r = new Runnable () {
public void run () {
new TextDrop ("Text Drop");
} };
EventQueue.invokeLater (r);
} }
When you run this application, its GUI presents three labels, two text fields, and a combo box. The idea is to select text in either text field and drag the selected text to the other text field. By choosing the drop mode from the combo box, you can verify each drop mode’s influence in terms of selected and deselected text.
Figure 4-2 shows a copy operation, where the top text field’s text has previously been selected. The text copy is being dragged to the end of the top text field, where it will be dropped. Notice that the combo box indicates the INSERT drop mode. When you switch to USE_SELECTION drop mode, you will see the text but not the selection during the drag operation. (Don’t forget to hold down the Ctrl key to drag a copy of the text.)
Figure 4-2.The TextDrop application demonstrates the DropMode.INSERT and DropMode.USE_SELECTION drop modes.
Shannon Hickey, a member of the Swing Team, has created a blog that outlines the work done to improve Swing component drag-and-drop. Rather than “reinvent the wheel” by reiterating Shannon’s blog (which includes several Web Start-based demos), I refer you to these blog entries for complete coverage:
• “Improved Drag Gesture in Swing”
(http://weblogs.java.net/blog/shan_man/archive/2005/06/improved_drag_g.html)
• “First Class Drag and Drop Support in Mustang”
(http://weblogs.java.net/blog/shan_man/archive/2006/01/first_class_dra.html)
• “Location-Sensitive Drag and Drop in Mustang”
(http://weblogs.java.net/blog/shan_man/archive/2006/01/location_sensit.html)
• “Enable Dropping into Empty JTables”
(http://weblogs.java.net/blog/shan_man/archive/2006/01/enable_dropping.html)
• “Choosing the Drop Action, and Further Changes to Swing Drag and Drop”
(http://weblogs.java.net/blog/shan_man/archive/2006/02/choosing_the_dr.html)
■ Note JTextComponentalso provides a companion public final DropMode getDropMode()method to return the current drop mode. For backward compatibility,DropMode.USE_SELECTIONis the default drop mode.