-
Enhancement
-
Resolution: Duplicate
-
P4
-
None
-
5.0
-
x86
-
windows_xp
Name: js151677 Date: 07/07/2004
A DESCRIPTION OF THE REQUEST :
I have a table that is essential a file browser similar to windows explorer. With both awt DnD and swing DnD implementaions, I get notified that the dragEvent is a move unless the ctrl key is down. This is not how windows explorer works. In Windows explorer, dragging from one drive to another is a copy gesture, while dragging and dropping whithin a drive is a move. My users are complaining that my UI does not behave the same way as windows explorer and I have no way to work around the problem. I assume that the reason I am always told this action is a move is because java has no way of knowing where the file will be dropped.
I would like some way to accept a drag of a file object in my dropTarget with an optional arguement to let the dragSource know where the file will be dropped.
Can you please add a new method to accept file objects with an arguement of directory that the file will be dropped in?
JUSTIFICATION :
To provide a consistent look and feel with windows.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would like drag and drop of files to behave the same as windows explorer in that some drops are copy actions even though there are no modifier keys down.
ACTUAL -
Currently dropping a file object is always a move unless there are modifier keys.
---------- BEGIN SOURCE ----------
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.awt.*;
public class TestTableDnD extends JFrame implements DropTargetListener, DragGestureListener, DragSourceListener
{
private JFrame fFrame;
private JTable fTable;
public TestTableDnD()
{
fFrame = new JFrame("Test DnD in Table");
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() { return 10; }
public int getRowCount() { return 10;}
public Object getValueAt(int row, int col) { return new Integer(row*col); }
};
fTable = new JTable(dataModel);
JScrollPane scrollpane = new JScrollPane(fTable);
fFrame.getContentPane().add(scrollpane);
fTable.setDragEnabled(true);
fTable.setDropTarget(new DropTarget(this, // component
DnDConstants.ACTION_COPY_OR_MOVE, // actions
this)); // DropTargetListener
fTable.setTransferHandler(new FBDefaultTransferHandler());
fFrame.setSize(300,300);
fFrame.setVisible(true);
}
public static void main(String[] args)
{
new TestTableDnD();
}
// DragGestureListener implementation begins -------------------------
public void dragGestureRecognized(DragGestureEvent dge)
{
/* this doesn't matter for test */
}
// DragSourceListener implementation begins --------------------------
// These methods are also part of DragSourceListener.
// They are invoked at interesting points during the drag, and can be
// used to perform "drag over" effects, such as changing the drag cursor
// or drag image.
public void dragEnter(DragSourceDragEvent dsde)
{
Cursor newCursor = null;
Cursor currentCursor = dsde.getDragSourceContext().getCursor();
switch (dsde.getUserAction())
{
case DnDConstants.ACTION_COPY:
if (!currentCursor.equals(DragSource.DefaultCopyDrop))
{
newCursor = DragSource.DefaultCopyDrop;
}
break;
case DnDConstants.ACTION_MOVE:
if (!currentCursor.equals(DragSource.DefaultMoveDrop))
{
newCursor = DragSource.DefaultMoveDrop;
}
break;
default:
newCursor = DragSource.DefaultCopyDrop;
break;
}
if (newCursor != null)
dsde.getDragSourceContext().setCursor(newCursor);
}
public void dragExit(DragSourceEvent dsde)
{
dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyNoDrop);
}
public void dragOver(DragSourceDragEvent dsde)
{
Cursor newCursor = null;
Cursor currentCursor = dsde.getDragSourceContext().getCursor();
switch (dsde.getUserAction())
{
case DnDConstants.ACTION_COPY:
if (!currentCursor.equals(DragSource.DefaultCopyDrop))
{
newCursor = DragSource.DefaultCopyDrop;
}
break;
case DnDConstants.ACTION_MOVE:
if (!currentCursor.equals(DragSource.DefaultMoveDrop))
{
newCursor = DragSource.DefaultMoveDrop;
}
break;
default:
newCursor = DragSource.DefaultCopyDrop;
break;
}
if (newCursor != null)
dsde.getDragSourceContext().setCursor(newCursor);
}
public void dropActionChanged(DragSourceDragEvent dsde)
{
}
/**
* dragDropEnd() is invoked when the drag & drop is completed.
**/
public void dragDropEnd(DragSourceDropEvent e)
{
/* this doesn't matter for test */
}
// DragSourceListener implementation ends ----------------------------
// DropTargetListener implementation begins --------------------------
public void dragEnter(DropTargetDragEvent dtde)
{
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
{
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
}
else
{
dtde.rejectDrag();
}
}
public void dragExit(DropTargetEvent dte)
{
}
public void dragOver(DropTargetDragEvent dtde)
{
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
{
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
return; //get out.
}
//if not a file flavor, reject.
dtde.rejectDrag();
}
public void drop(DropTargetDropEvent dtde)
{
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
{
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
if (dtde.getDropAction() == DnDConstants.ACTION_MOVE)
System.out.println("drop - MOVE");
else
System.out.println("drop - COPY");
//do stuff to drop. not relevant to test.
dtde.dropComplete(true);
return;
}
//If there was not a transferable object we are interested in then
//reject the drop.
dtde.rejectDrop();
}
public void dropActionChanged(DropTargetDragEvent dtde)
{
}
class FBDefaultTransferHandler extends TransferHandler
{
public void exportToClipboard(JComponent comp, Clipboard clipboard,
int action)
{
// Not important for test example
}
public void exportDone(JComponent source,
Transferable data,
int action)
{
cleanup(source, action == MOVE);
}
//If the remove argument is true, the drop has been
//successful and it's time to remove the selected items
//from the list. If the remove argument is false, it
//was a Copy operation and the original list is left
//intact.
protected void cleanup(JComponent c, boolean remove) {
}
/**
* This is called to paste. Gets data off the clipboard.
* @param comp
* @param t
* @return successful import
*/
public boolean importData(JComponent comp, Transferable t)
{
// Not important for test example
return false;
}
private DataFlavor getFlavor(DataFlavor[] flavors)
{
if (flavors != null)
{
for (int counter = 0; counter < flavors.length; counter++)
{
if (flavors[counter].equals(DataFlavor.javaFileListFlavor))
{
return flavors[counter];
}
}
}
return null;
}
/**
* Does the flavor list have a file flavor?
*/
protected boolean hasFileFlavor(DataFlavor[] flavors) {
for (int i = 0; i < flavors.length; i++) {
if (DataFlavor.javaFileListFlavor.equals(flavors[i])) {
return true;
}
}
return false;
}
/**
* Overridden to include a check for a file flavor.
*/
public boolean canImport(JComponent c, DataFlavor[] flavors) {
return hasFileFlavor(flavors);
}
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
protected Transferable createTransferable(JComponent c) {
// Not important for test example
Transferable trans = new StringSelection("");
return trans;
}
}
}
---------- END SOURCE ----------
(Incident Review ID: 284965)
======================================================================
A DESCRIPTION OF THE REQUEST :
I have a table that is essential a file browser similar to windows explorer. With both awt DnD and swing DnD implementaions, I get notified that the dragEvent is a move unless the ctrl key is down. This is not how windows explorer works. In Windows explorer, dragging from one drive to another is a copy gesture, while dragging and dropping whithin a drive is a move. My users are complaining that my UI does not behave the same way as windows explorer and I have no way to work around the problem. I assume that the reason I am always told this action is a move is because java has no way of knowing where the file will be dropped.
I would like some way to accept a drag of a file object in my dropTarget with an optional arguement to let the dragSource know where the file will be dropped.
Can you please add a new method to accept file objects with an arguement of directory that the file will be dropped in?
JUSTIFICATION :
To provide a consistent look and feel with windows.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would like drag and drop of files to behave the same as windows explorer in that some drops are copy actions even though there are no modifier keys down.
ACTUAL -
Currently dropping a file object is always a move unless there are modifier keys.
---------- BEGIN SOURCE ----------
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.awt.*;
public class TestTableDnD extends JFrame implements DropTargetListener, DragGestureListener, DragSourceListener
{
private JFrame fFrame;
private JTable fTable;
public TestTableDnD()
{
fFrame = new JFrame("Test DnD in Table");
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() { return 10; }
public int getRowCount() { return 10;}
public Object getValueAt(int row, int col) { return new Integer(row*col); }
};
fTable = new JTable(dataModel);
JScrollPane scrollpane = new JScrollPane(fTable);
fFrame.getContentPane().add(scrollpane);
fTable.setDragEnabled(true);
fTable.setDropTarget(new DropTarget(this, // component
DnDConstants.ACTION_COPY_OR_MOVE, // actions
this)); // DropTargetListener
fTable.setTransferHandler(new FBDefaultTransferHandler());
fFrame.setSize(300,300);
fFrame.setVisible(true);
}
public static void main(String[] args)
{
new TestTableDnD();
}
// DragGestureListener implementation begins -------------------------
public void dragGestureRecognized(DragGestureEvent dge)
{
/* this doesn't matter for test */
}
// DragSourceListener implementation begins --------------------------
// These methods are also part of DragSourceListener.
// They are invoked at interesting points during the drag, and can be
// used to perform "drag over" effects, such as changing the drag cursor
// or drag image.
public void dragEnter(DragSourceDragEvent dsde)
{
Cursor newCursor = null;
Cursor currentCursor = dsde.getDragSourceContext().getCursor();
switch (dsde.getUserAction())
{
case DnDConstants.ACTION_COPY:
if (!currentCursor.equals(DragSource.DefaultCopyDrop))
{
newCursor = DragSource.DefaultCopyDrop;
}
break;
case DnDConstants.ACTION_MOVE:
if (!currentCursor.equals(DragSource.DefaultMoveDrop))
{
newCursor = DragSource.DefaultMoveDrop;
}
break;
default:
newCursor = DragSource.DefaultCopyDrop;
break;
}
if (newCursor != null)
dsde.getDragSourceContext().setCursor(newCursor);
}
public void dragExit(DragSourceEvent dsde)
{
dsde.getDragSourceContext().setCursor(DragSource.DefaultCopyNoDrop);
}
public void dragOver(DragSourceDragEvent dsde)
{
Cursor newCursor = null;
Cursor currentCursor = dsde.getDragSourceContext().getCursor();
switch (dsde.getUserAction())
{
case DnDConstants.ACTION_COPY:
if (!currentCursor.equals(DragSource.DefaultCopyDrop))
{
newCursor = DragSource.DefaultCopyDrop;
}
break;
case DnDConstants.ACTION_MOVE:
if (!currentCursor.equals(DragSource.DefaultMoveDrop))
{
newCursor = DragSource.DefaultMoveDrop;
}
break;
default:
newCursor = DragSource.DefaultCopyDrop;
break;
}
if (newCursor != null)
dsde.getDragSourceContext().setCursor(newCursor);
}
public void dropActionChanged(DragSourceDragEvent dsde)
{
}
/**
* dragDropEnd() is invoked when the drag & drop is completed.
**/
public void dragDropEnd(DragSourceDropEvent e)
{
/* this doesn't matter for test */
}
// DragSourceListener implementation ends ----------------------------
// DropTargetListener implementation begins --------------------------
public void dragEnter(DropTargetDragEvent dtde)
{
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
{
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
}
else
{
dtde.rejectDrag();
}
}
public void dragExit(DropTargetEvent dte)
{
}
public void dragOver(DropTargetDragEvent dtde)
{
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
{
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
return; //get out.
}
//if not a file flavor, reject.
dtde.rejectDrag();
}
public void drop(DropTargetDropEvent dtde)
{
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
{
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
if (dtde.getDropAction() == DnDConstants.ACTION_MOVE)
System.out.println("drop - MOVE");
else
System.out.println("drop - COPY");
//do stuff to drop. not relevant to test.
dtde.dropComplete(true);
return;
}
//If there was not a transferable object we are interested in then
//reject the drop.
dtde.rejectDrop();
}
public void dropActionChanged(DropTargetDragEvent dtde)
{
}
class FBDefaultTransferHandler extends TransferHandler
{
public void exportToClipboard(JComponent comp, Clipboard clipboard,
int action)
{
// Not important for test example
}
public void exportDone(JComponent source,
Transferable data,
int action)
{
cleanup(source, action == MOVE);
}
//If the remove argument is true, the drop has been
//successful and it's time to remove the selected items
//from the list. If the remove argument is false, it
//was a Copy operation and the original list is left
//intact.
protected void cleanup(JComponent c, boolean remove) {
}
/**
* This is called to paste. Gets data off the clipboard.
* @param comp
* @param t
* @return successful import
*/
public boolean importData(JComponent comp, Transferable t)
{
// Not important for test example
return false;
}
private DataFlavor getFlavor(DataFlavor[] flavors)
{
if (flavors != null)
{
for (int counter = 0; counter < flavors.length; counter++)
{
if (flavors[counter].equals(DataFlavor.javaFileListFlavor))
{
return flavors[counter];
}
}
}
return null;
}
/**
* Does the flavor list have a file flavor?
*/
protected boolean hasFileFlavor(DataFlavor[] flavors) {
for (int i = 0; i < flavors.length; i++) {
if (DataFlavor.javaFileListFlavor.equals(flavors[i])) {
return true;
}
}
return false;
}
/**
* Overridden to include a check for a file flavor.
*/
public boolean canImport(JComponent c, DataFlavor[] flavors) {
return hasFileFlavor(flavors);
}
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
protected Transferable createTransferable(JComponent c) {
// Not important for test example
Transferable trans = new StringSelection("");
return trans;
}
}
}
---------- END SOURCE ----------
(Incident Review ID: 284965)
======================================================================
- duplicates
-
JDK-4869264 drag & drop action negotiation does not honor the targets supported actions
- Resolved