<Swing Dev> DnD fails with JTextArea and JTextField

Pavel Porvatov pavel.porvatov at oracle.com
Tue Sep 13 09:54:19 UTC 2011


Hi Sean,
> Hi Pavel ,
>
>     I'm sorry I didn't make update for this bug for a long time, and 
> here is some
> recent investigation. The scenario is as follows:
>
> Suppose we are dragging "abcde" over TextField tf, which have "hello 
> dragging" as
> its content. When we are dragging from start to end, there is a cursor 
> moving from
> "h" to "g", which means the place to insert "abcde" if we drop it.
> When we dragging "abcde" exit tf, there will be a dragExit event, the 
> tf needs to
> restore its original status after we drag out. Eg. if its cursor is 
> between "h" and
> "e" in "hello", which appears like "h|ello", when we are dragging over 
> it, it may like
> "hello dr|agging", and when drag exit, it needs to be "h|ello" again.
> So in dragExit handler, it calls 
> javax.swing.TransferHandler.cleanup(false), which
> means only to restore the original state. cleanup calls
> javax.swing.text.JTextComponent.setDropLocation to set the cursor to 
> original
> position. And setDropLocation calls DefaultCaret.setDot 
> and DefaultCaret.moveDot
> to set the state.
> The problem is moveDot doesn't know this is just to restore the 
> original state,
> it treats the invocation as an action to select something. And it 
> calls updateSystemSelection
> which will call java.awt.datatransfer.Clipboard.setContent. And the 
> selected content
> is changed from "abcde" to the original selected part of "hello 
> dragging", then
> the drop operation finds it is not the string dragged and nothing is 
> dropped.
>
> So I made a simple patch(attached) . It just check if the textField 
> owns focus
> before updateSystemSelection, if it is not focused, it does not treat 
> the moveDot as
> a selection action and does not call Clipboard.setContent.  This works 
> on Linux,
> however, DefaultCaret is shared by Linux and Windows while windows 
> doesn't have
> this problem. So I don't think this is a correct patch, but it brings 
> my question.
>
> I think it is strange for DefaultCaret to use setDot and moveDot to 
> restore
> original state, especially moveDot will cause an updateSystemSelection 
> operation,
> which makes moveDot much like an action from user instead of just 
> restoring state.
>
> I'm not sure why it works well on windows, but I don't think it is 
> right to call
> updateSystemSelection or it is not right to use setDot and moveDot to 
> restore
> the original state. Is there any reason for that ?
Thanks for the patch! I believe you are right and we shouldn't update 
system selection clipboard when the component doesn't have focus. I'd 
like to modify your fix and move checking into the 
DefaultCaret#updateSystemSelection method:
   if (this.dot != this.mark && component != null && component.hasFocus()) {

We also must write regression tests for fixes if possible, so an 
automatic test is needed as well. Could you please write a test for the fix?

 > I'm not sure why it works well on windows,
That's because Windows doesn't have system selection clipboard...

 > Is there any reason for that ?
No, that's a just bug...

Regards, Pavel
>
> 2011/6/6 Pavel Porvatov <pavel.porvatov at oracle.com 
> <mailto:pavel.porvatov at oracle.com>>
>
>     Hi Sean,
>>     Hi,
>>
>>     I reported, but the system doesn't reply me a bug number. It says
>>     "will give me email",
>>     but I haven't got one yet. Is this the right process, or I might
>>     make a problem when
>>     reporting?
>     I don't know why the system didn't report bug ID, but your bug was
>     filed successfully. You can find it here:
>     http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7049024
>
>     Regards, Pavel
>
>>
>>     2011/5/27 Pavel Porvatov <pavel.porvatov at oracle.com
>>     <mailto:pavel.porvatov at oracle.com>>
>>
>>         Hi Sean,
>>>         Hi all,
>>>
>>>             I have a testcase related to DnD failure with JTextArea
>>>         and JTextField on linux. The
>>>         testcase is as follows:
>>>
>>>         /*
>>>          * DnDTest.java
>>>          */
>>>         import java.awt.Color;
>>>         import java.awt.Component;
>>>         import java.awt.Dimension;
>>>         import java.awt.FlowLayout;
>>>         import java.awt.Frame;
>>>         import java.awt.event.WindowAdapter;
>>>         import java.awt.event.WindowEvent;
>>>
>>>         import javax.swing.JTextArea;
>>>         import javax.swing.JTextField;
>>>
>>>
>>>         public class DnDTest extends Frame {
>>>         Component c;
>>>         public DnDTest() {
>>>         super("Single Frame --- AWT Frame");
>>>         super.setBackground(Color.gray);
>>>         // set layout here.
>>>         setLayout(new FlowLayout());
>>>         c = new JTextArea("JTextArea component");
>>>         c.setPreferredSize(new Dimension(400, 100));
>>>         add(c);
>>>         c = new JTextField("JTextField component(No IM)");
>>>         c.setPreferredSize(new Dimension(400, 20));
>>>         add(c);
>>>         addWindowListener(new WindowAdapter() {
>>>         public void windowClosing(WindowEvent event) {
>>>         System.exit(0);
>>>         }
>>>         });
>>>         setSize(850, 360);
>>>         setVisible(true);
>>>         }
>>>         public static void main(String[] args) {
>>>         new DnDTest();
>>>         }
>>>         }
>>>
>>>
>>>         Reproduce steps:
>>>         1. Run the testcase with b143
>>>         2. Open a new file with gedit and input some words like "abcde"
>>>         3. Drag "abcde" into JTextField and drop it there.
>>>         4. Once more, drag "abcde" into JTextField and then move out
>>>         of the Frame (keep draging) and drag into JTextField again
>>>         and drop it.
>>>
>>>         Expectation:
>>>         The second DnD inputs another "abcde" into JTextField.
>>>
>>>         Result:
>>>         The second DnD inputs nothing into JTextField.
>>         Yes, looks like a bug. The test case works on Windows as
>>         expected.
>>
>>>
>>>         Investigation:
>>>         The JTextArea as well has this problem, and in step 4, if we
>>>         drag "abcde" over JTextField and then drop into JTextArea,
>>>         nothing
>>>         is input into JTextArea either. However, if "abcde" is drag
>>>         into JTextField or JTextArea directly or when
>>>         JTextArea/Field are
>>>         empty as in step 2, it works.
>>>
>>>
>>>         Are there any comments? And can anyone file a bug for it
>>>         please ?
>>         Anybody can file a bug, http://bugreport.sun.com/bugreport/
>>
>>         Regards, Pavel
>>
>>
>>
>>
>>     -- 
>>     Best Regards,
>>     Sean Chou
>>
>
>
>
>
> -- 
> Best Regards,
> Sean Chou
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/swing-dev/attachments/20110913/a6b537ac/attachment.html>


More information about the swing-dev mailing list