original) (raw)
Hi Sean, (Hi Pavel ,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:
I'm sorry I didn't make update for this bug for a long time, and here is somerecent investigation. The scenario is as follows:
Suppose we are dragging "abcde" over TextField tf, which have "hello dragging" asits 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 torestore 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), whichmeans only to restore the original state. cleanup callsjavax.swing.text.JTextComponent.setDropLocation to set the cursor to originalposition. And setDropLocation calls DefaultCaret.setDot and DefaultCaret.moveDotto 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 updateSystemSelectionwhich will call java.awt.datatransfer.Clipboard.setContent. And the selected contentis changed from "abcde" to the original selected part of "hello dragging", thenthe 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 focusbefore updateSystemSelection, if it is not focused, it does not treat the moveDot asa selection action and does not call Clipboard.setContent. This works on Linux,however, DefaultCaret is shared by Linux and Windows while windows doesn't havethis 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 restoreoriginal 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 callupdateSystemSelection or it is not right to use setDot and moveDot to restorethe original state. Is there any reason for that ?
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@oracle.com>
Hi Sean,I don't know why the system didn't report bug ID, but your bug was filed successfully. You can find it here: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 whenreporting?
http://bugs.sun.com/bugdatabase/view\_bug.do?bug\_id=7049024
Regards, Pavel
2011/5/27 Pavel Porvatov <pavel.porvatov@oracle.com>
Hi Sean,Hi all,
I have a testcase related to DnD failure with JTextArea and JTextField on linux. Thetestcase 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(newDimension(400, 100));
add(c);
c = new
JTextField("JTextField
component(No IM)");
c.setPreferredSize(newDimension(400, 20));
add(c);
addWindowListener(newWindowAdapter() {
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