Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4468566
Votes 28
Synopsis Swing DnD should not use selection to show drop location
Category java:classes_swing
Reported Against rc , 1.4 , b06 , 1.4.0_00 , mantis-beta , merlin-beta , tiger-beta2
Release Fixed mustang(b42)
State 10-Fix Delivered, request for enhancement
Priority: 4-Low
Related Bugs 6277499 , 6297778 , 6310757 , 6315298 , 6331837 , 6342398 , 4459289 , 6459915 , 5077753 , 6184817 , 6184866 , 4760426 , 4942851
Submit Date 12-JUN-2001
Description
In Swing, the selection is used to show the point where a drop operation would occur. With text components, this is the caret. In JList, JTable, JTree, the selection is used.

This causes many complications. With text, playing with the caret causes the selection to be temporary lost as described in the report below. With the other components, using the selection makes it difficult to specify a drop above or below the current selection.

A new mechanism should be designed such that a drop location can be displayed without using the selection.

-----------------------------------
Original bug report:




java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b65)
Java HotSpot(TM) Client VM (build 1.4.0-beta-b65, mixed mode)

Dragging selected text from a text component deselects the original text. The
original text is deselected as soon as the drag starts. I expect the original
text to remain selected until the text is dropped on a target.
Set setDragEnabled on a JTextField, JTextArea, JTextPane, JFormattedTextField
or JEditorPane to true to select default drag operation. After selecting some
text and starting to drag, the text becomes unselected.
The example code shows a frame with each of the text components in it. The
components have had their default drag operation enabled so that drag and drop
of text can by played with. Select some text in any component and drag it. As
soon as the selected text is dragged the original text becomes unselected.

/*
 * Test.java
 *
 * Created on 6 June 2001, 16:08
 */


/**
 *
 * @author  daz
 * @version 1.0
 */
public class Test extends javax.swing.JFrame {

    /** Creates new form Test */
    public Test() {
        initComponents ();
        jFormattedTextField1 = new javax.swing.JFormattedTextField();
        jFormattedTextField1.setText("jFormattedTextField1");
        getContentPane().add(jFormattedTextField1);
        jTextArea1.setDragEnabled(true);
        jTextField1.setDragEnabled(true);
        jTextPane1.setDragEnabled(true);
        jEditorPane1.setDragEnabled(true);
        jFormattedTextField1.setDragEnabled(true);
        pack ();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the FormEditor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
      jTextArea1 = new javax.swing.JTextArea();
      jTextField1 = new javax.swing.JTextField();
      jTextPane1 = new javax.swing.JTextPane();
      jEditorPane1 = new javax.swing.JEditorPane();
      
      getContentPane().setLayout(new java.awt.GridLayout(0, 1));
      
      addWindowListener(new java.awt.event.WindowAdapter() {
        public void windowClosing(java.awt.event.WindowEvent evt) {
          exitForm(evt);
        }
      });
      
      jTextArea1.setText("jTextArea1");
      getContentPane().add(jTextArea1);
      
      jTextField1.setText("jTextField1");
      getContentPane().add(jTextField1);
      
      jTextPane1.setText("jTextPanel1");
      getContentPane().add(jTextPane1);
      
      jEditorPane1.setText("jEditorPane1");
      getContentPane().add(jEditorPane1);
      
    }//GEN-END:initComponents

    /** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-
FIRST:event_exitForm
        System.exit (0);
    }//GEN-LAST:event_exitForm

    /**
    * @param args the command line arguments
    */
    public static void main (String args[]) {
        new Test ().show ();
    }


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextPane jTextPane1;
    private javax.swing.JEditorPane jEditorPane1;
    // End of variables declaration//GEN-END:variables
    private javax.swing.JFormattedTextField jFormattedTextField1;
}
(Review ID: 126245) 
======================================================================
Work Around


Nome
======================================================================
Evaluation


Pure AWT text components are based on the native window objects:
XmText and XmTextField widgets on X11, EDIT controls on Win32. All of
them clear the current selection on left mouse button press. When the
left mouse button is pressed we cannot predict whether the drag
gesture will be eventually recognized or not, so we have to follow the
default behavior and clear the current selection.

The desired behavior can be implemented for Swing text components with
enabled drag operation.

======================================================================

The reason that this occurs in Swing is that we use the caret to show the insert location. Ideally, we should not use the caret and use another means to show this location. By doing this we can avoid changing the selection. A similar change should be made for other components that use selection to show the insert location. I am changing the description and synopsis to reflect the source of the problem.
  xxxxx@xxxxx   2001-11-13

See also 5077753. The behavior we decide on should likely be customized to act like the associated native platform for each L&F.
  xxxxx@xxxxx   2004-07-23

A fix for this bug has been made! JTextComponent, JList, JTable and JTree now all have a new setDropMode(DropMode) method. This method controls how the components track and indicate their drop location. The new drop modes and the components that support them are:

USE_SELECTION     - JTextComponent, JList, JTable, JTree
ON                - JList, JTable, JTree
INSERT            - JTextComponent, JList, JTable, JTree
INSERT_ROWS       - JTable
INSERT_COLS       - JTable
ON_OR_INSERT      - JList, JTable, JTree
ON_OR_INSERT_ROWS - JTable
ON_OR_INSERT_COLS - JTable

The default drop mode for all components will be USE_SELECTION (which uses the selection to track the drop location), for backward compatibility. However, the new drop modes offer better options for tracking and indicating the drop location, without affecting the component's selection.

Each of these components will also have a new getDropLocation() method which will return a subclass of TransferHandler.DropLocation, customized to indicate the drop location as it makes sense for that component type. This getDropLocation() method is intended for use by UI code that renders the drop location. Additionally, the DropLocation will be passed to canImport, shouldIndicateAnyway, and importData of TransferHandler so that the behavior can be customized based on drop location.
  xxxxx@xxxxx   2005-06-01 17:30:40 GMT
Comments
  
  Include a link with my name & email   

Submitted On 15-JUN-2001
krbennett
This has been a bug in 1.3, and possibly 1.2 also.  The 
problem is that the text is deselected on the mouseDown 
instead of the mouseUp.  This is clearer when you compare 
the behavior of Swing/AWT with that of a program such as 
WordPad or Word.


Submitted On 22-OCT-2003
dfried
In Swing JList and JTable, the selection is still used to define 
the point where a drop operation should occur.  This makes it 
impossible to drop the first row into an empty such 
component with no model entries.  [JDK version 1.4.1-02]


Submitted On 19-NOV-2003
starry_chloe
Also would like a way to find the Point at which the drop 
occured, ideally in TransferHandler.importData(). When 
dropping objects onto a panel or canvas, it makes it 
extremely difficult to find exactly where to insert the object.


Submitted On 08-JAN-2004
kumar_parveen
There should also be provision or callback 
corresponding to dragOver(), along with the mouse 
position, so that within a component one can 
dynamically decide where drop is allowed and where 
not. At present, only during dragEnter, one can decide 
and then no extensibility support is left for dragOver.


Submitted On 29-APR-2004
rroy1
Please add the ability to distinguish between a drag 
with left-mouse-button-down and right-mouse-button-
down from within importData. With the right mouse 
button you would probably display a popup menu.

Also, one might want to use Ctrl, Shft, etc. while 
dragging and then check in importData for the key 
modifier.


Submitted On 25-MAY-2004
hute37
I tried to write a custom tree TransferHandler acting as a dispatcher for a set of installable DnD and Clibpoard actionMap, using an extended Action interface. 
I give up basically  for  insufficient  event support (Point ?) and canImport() caching policy in BasicUI. 
Why TransferHandler isn't  an Interface, with AbstractTransferHandler abstract base 
and a default  PropertyTransferHandler implementation?

But worse the main problem lies in the private approach:

setDropTarget(new TransferHandler.SwingDropTarget(this));

in JComponent.setTransferHandler()

that should be  "open" instead:
 
setDropTarget(
newHandler.getDropTargetForComponent(this));



Submitted On 11-AUG-2004
Ashfire
TransferHandler.canImport() can decide the drop action is allowed or not, meanwhile it also affects the mouse shape. But in canImport() I don't know how to obtain current mouse position and I can't know which component(Treenode of JTree) is dragEnter or dragOver. I don't want to provide a DropTargetListener for the JTree. What shall I do?


Submitted On 12-AUG-2004
shan-man
Ashfire, note that bug 4942851 is tracking the issue of canImport() not providing enough information. For one, we'd like to pass the Transferable as an additional parameter. Additionally, we want to pass more information, such as the current location in the component.



PLEASE NOTE: JDK6 is formerly known as Project Mustang