Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » Drag and Drop in a Tree
Drag and Drop in a Tree [message #450891] Sun, 20 February 2005 02:00 Go to next message
Eclipse UserFriend
Originally posted by: kent.generatescape.com

Hi-ya All,

I is having a wee bit of a problem with dnd and some pointers would be nice.

Alrighty I want to be able to move nodes around in a tree.

So my target and my source are the same.

I am using a contentprovider and label provider.

Everything seems to work until I get to the drop. The last method in the
code snippet is where my problem seems to be.

I I don't really know what to do at that point. I can go and create a new
TreeItem and put it into the tree but where exactly is it going into the
tree? And then how do I go and delete the old TreeItem from the tree?

Is there any better transfer method for TreeItems?

Here is a snippet. Thanks a billion.

// Allow data to be copied or moved to the drop target
int operations = DND.DROP_MOVE;
DropTarget target = new DropTarget(tv.getTree(), operations);

// Receive data in Text or File format
final TextTransfer textTransfer = TextTransfer.getInstance();
types = new Transfer[] { textTransfer };
target.setTransfer(types);

DragSource source = new DragSource(tv.getTree(), operations);
source.setTransfer(types);

source.addDragListener(new DragSourceAdapter()
{

public void dragSetData(DragSourceEvent event)
{
// Provide the data of the requested type.
if
(TextTransfer.getInstance().isSupportedType(event.dataType))
{
DragSource ds = (DragSource) event.widget;
Tree tree = (Tree) ds.getControl();

TreeItem[] selection = tree.getSelection();

for (int i = 0; i < selection.length; i++)
{
// right now I don't care about multiple selection
event.data = selection[i].getText();
} // end for
} // end if
}
});

target.addDropListener(new DropTargetAdapter()
{
public void dragEnter(DropTargetEvent event)
{
if (event.detail == DND.DROP_DEFAULT)
{
event.detail = (event.operations & DND.DROP_COPY) != 0 ?
DND.DROP_COPY
: DND.DROP_NONE;
}

// Allow dropping text only
for (int i = 0, n = event.dataTypes.length; i < n; i++)
{
if (TextTransfer.getInstance().isSupportedType(
event.dataTypes[i]))
{
event.currentDataType = event.dataTypes[i];
}
}
}

public void dragOver(DropTargetEvent event)
{
// Provide visual feedback
event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL;
}

public void drop(DropTargetEvent event)
{
System.out.println("drop");

if (textTransfer.isSupportedType(event.currentDataType))
{

String text = (String) event.data;
DropTarget target = (DropTarget) event.widget;

Tree tree = (Tree) target.getControl();

TreeItem ti = new TreeItem(tree, SWT.NONE);
ti.setText(text);

// this is my treelabelprovider
ftlp.toggle();
// my treeviewer
tv.refresh();

}

}
});
Re: Drag and Drop in a Tree [message #451008 is a reply to message #450891] Mon, 21 February 2005 12:22 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: kent.generatescape.com

I sort of solved the problem, but I am not too happy with my solution so if
anyone has some pointers that would be grand.

I basically tried a solution without DND, based on an example Veronika
Irvine submitted.

The problem is that I have to go and repopulate the entire tree when I move
one node around, is this really neccessary, I will be using a really large
tree, so efficiency is a requirement. Plus how would I integrate such a
solution into the labelprovider & contentprovider paradigm, where you never
even really see the treeitems?

Anyway here is my class.


import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;


public class MovingItems
{
static Tree tree;
static Shell shell;

static public void refreshTree(boolean init)
{
if (init)
{
for (int i = 0; i < 10; i++)
{
TreeItem item = new TreeItem(tree, SWT.NONE);
item.setText("item " + i);
treeItems.add(item.getText());

}
}
else
{
tree.removeAll();
for (Iterator iter = treeItems.iterator(); iter.hasNext();)
{
String element = (String) iter.next();
TreeItem item = new TreeItem(tree, SWT.NONE);
item.setText(element);
System.out.println("Setting text " + element);

}
}

}

static final ArrayList treeItems = new ArrayList();

public static void main(String[] args)
{

final Display display = new Display();
shell = new Shell(display);
shell.setLayout(new GridLayout());

tree = new Tree(shell, SWT.BORDER);
tree.setLayoutData(new GridData(GridData.FILL_BOTH));
refreshTree(true);

Listener listener = new Listener()
{
boolean drag = false;
boolean exitDrag = false;
TreeItem dragItem;

public void handleEvent(Event e)
{
Point p = new Point(e.x, e.y);
if (e.type == SWT.DragDetect)
{
p = tree.toControl(display.getCursorLocation());
}
switch (e.type)
{
case SWT.DragDetect:
{
TreeItem item = tree.getItem(p);
if (item == null)
return;
drag = true;
exitDrag = false;
dragItem = item;
System.out.println("1. dragItem " + dragItem.getText());
break;
}
case SWT.MouseEnter:
if (exitDrag)
{
exitDrag = false;
drag = e.button != 0;
}
break;
case SWT.MouseExit:
if (drag)
{
tree.setInsertMark(null, false);
exitDrag = true;
drag = false;
}
break;
case SWT.MouseUp:
{
if (!drag)
return;
tree.setInsertMark(null, false);
TreeItem item = tree.getItem(new Point(p.x, p.y));
if (item != null)
{

int toindex = treeItems.indexOf(item.getText());
System.out.println("Insertion point " +
item.getText());

int fromindex =
treeItems.indexOf(dragItem.getText());
System.out.println("Removing " + fromindex);
treeItems.remove(fromindex);
treeItems.add(toindex, dragItem.getText());
System.out.println("Adding toIndex: " + toindex + "
"
+ dragItem.getText());
refreshTree(false);

}
drag = false;
exitDrag = false;
dragItem = null;
break;
}
case SWT.MouseMove:
{
if (!drag)
return;
TreeItem item = tree.getItem(new Point(p.x, 2));
if (item == null)
{
tree.setInsertMark(null, false);
return;
}
Rectangle rect = item.getBounds();
boolean after = p.x > rect.x + rect.width / 2;
tree.setInsertMark(item, after);
break;
}
}
}
};
tree.addListener(SWT.DragDetect, listener);
tree.addListener(SWT.MouseUp, listener);
tree.addListener(SWT.MouseMove, listener);
tree.addListener(SWT.MouseExit, listener);
tree.addListener(SWT.MouseEnter, listener);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}

}

"kent" <kent@generatescape.com> wrote in message
news:cv8qs8$ac2$1@www.eclipse.org...
> Hi-ya All,
>
> I is having a wee bit of a problem with dnd and some pointers would be
> nice.
>
> Alrighty I want to be able to move nodes around in a tree.
>
> So my target and my source are the same.
>
> I am using a contentprovider and label provider.
>
> Everything seems to work until I get to the drop. The last method in the
> code snippet is where my problem seems to be.
>
> I I don't really know what to do at that point. I can go and create a new
> TreeItem and put it into the tree but where exactly is it going into the
> tree? And then how do I go and delete the old TreeItem from the tree?
>
> Is there any better transfer method for TreeItems?
>
> Here is a snippet. Thanks a billion.
>
> // Allow data to be copied or moved to the drop target
> int operations = DND.DROP_MOVE;
> DropTarget target = new DropTarget(tv.getTree(), operations);
>
> // Receive data in Text or File format
> final TextTransfer textTransfer = TextTransfer.getInstance();
> types = new Transfer[] { textTransfer };
> target.setTransfer(types);
>
> DragSource source = new DragSource(tv.getTree(), operations);
> source.setTransfer(types);
>
> source.addDragListener(new DragSourceAdapter()
> {
>
> public void dragSetData(DragSourceEvent event)
> {
> // Provide the data of the requested type.
> if
> (TextTransfer.getInstance().isSupportedType(event.dataType))
> {
> DragSource ds = (DragSource) event.widget;
> Tree tree = (Tree) ds.getControl();
>
> TreeItem[] selection = tree.getSelection();
>
> for (int i = 0; i < selection.length; i++)
> {
> // right now I don't care about multiple selection
> event.data = selection[i].getText();
> } // end for
> } // end if
> }
> });
>
> target.addDropListener(new DropTargetAdapter()
> {
> public void dragEnter(DropTargetEvent event)
> {
> if (event.detail == DND.DROP_DEFAULT)
> {
> event.detail = (event.operations & DND.DROP_COPY) != 0
> ? DND.DROP_COPY
> : DND.DROP_NONE;
> }
>
> // Allow dropping text only
> for (int i = 0, n = event.dataTypes.length; i < n; i++)
> {
> if (TextTransfer.getInstance().isSupportedType(
> event.dataTypes[i]))
> {
> event.currentDataType = event.dataTypes[i];
> }
> }
> }
>
> public void dragOver(DropTargetEvent event)
> {
> // Provide visual feedback
> event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL;
> }
>
> public void drop(DropTargetEvent event)
> {
> System.out.println("drop");
>
> if (textTransfer.isSupportedType(event.currentDataType))
> {
>
> String text = (String) event.data;
> DropTarget target = (DropTarget) event.widget;
>
> Tree tree = (Tree) target.getControl();
>
> TreeItem ti = new TreeItem(tree, SWT.NONE);
> ti.setText(text);
>
> // this is my treelabelprovider
> ftlp.toggle();
> // my treeviewer
> tv.refresh();
>
> }
>
> }
> });
>
>
Re: Drag and Drop in a Tree [message #451014 is a reply to message #451008] Mon, 21 February 2005 13:02 Go to previous message
Eclipse UserFriend
Originally posted by: kent.generatescape.com

alrighty, after doing an ever more thorough trawl of the message base I
found the perfect example once again from Veronika.

So thanks Veronika, problem solved.
"kent" <kent@generatescape.com> wrote in message
news:cvcjm5$g5$1@www.eclipse.org...
>I sort of solved the problem, but I am not too happy with my solution so if
>anyone has some pointers that would be grand.
>
> I basically tried a solution without DND, based on an example Veronika
> Irvine submitted.
>
> The problem is that I have to go and repopulate the entire tree when I
> move one node around, is this really neccessary, I will be using a really
> large tree, so efficiency is a requirement. Plus how would I integrate
> such a solution into the labelprovider & contentprovider paradigm, where
> you never even really see the treeitems?
>
> Anyway here is my class.
>
>
> import java.util.ArrayList;
> import java.util.Iterator;
> import org.eclipse.swt.SWT;
> import org.eclipse.swt.graphics.Point;
> import org.eclipse.swt.graphics.Rectangle;
> import org.eclipse.swt.layout.GridData;
> import org.eclipse.swt.layout.GridLayout;
> import org.eclipse.swt.widgets.Display;
> import org.eclipse.swt.widgets.Event;
> import org.eclipse.swt.widgets.Listener;
> import org.eclipse.swt.widgets.Shell;
> import org.eclipse.swt.widgets.Tree;
> import org.eclipse.swt.widgets.TreeItem;
>
>
> public class MovingItems
> {
> static Tree tree;
> static Shell shell;
>
> static public void refreshTree(boolean init)
> {
> if (init)
> {
> for (int i = 0; i < 10; i++)
> {
> TreeItem item = new TreeItem(tree, SWT.NONE);
> item.setText("item " + i);
> treeItems.add(item.getText());
>
> }
> }
> else
> {
> tree.removeAll();
> for (Iterator iter = treeItems.iterator(); iter.hasNext();)
> {
> String element = (String) iter.next();
> TreeItem item = new TreeItem(tree, SWT.NONE);
> item.setText(element);
> System.out.println("Setting text " + element);
>
> }
> }
>
> }
>
> static final ArrayList treeItems = new ArrayList();
>
> public static void main(String[] args)
> {
>
> final Display display = new Display();
> shell = new Shell(display);
> shell.setLayout(new GridLayout());
>
> tree = new Tree(shell, SWT.BORDER);
> tree.setLayoutData(new GridData(GridData.FILL_BOTH));
> refreshTree(true);
>
> Listener listener = new Listener()
> {
> boolean drag = false;
> boolean exitDrag = false;
> TreeItem dragItem;
>
> public void handleEvent(Event e)
> {
> Point p = new Point(e.x, e.y);
> if (e.type == SWT.DragDetect)
> {
> p = tree.toControl(display.getCursorLocation());
> }
> switch (e.type)
> {
> case SWT.DragDetect:
> {
> TreeItem item = tree.getItem(p);
> if (item == null)
> return;
> drag = true;
> exitDrag = false;
> dragItem = item;
> System.out.println("1. dragItem " +
> dragItem.getText());
> break;
> }
> case SWT.MouseEnter:
> if (exitDrag)
> {
> exitDrag = false;
> drag = e.button != 0;
> }
> break;
> case SWT.MouseExit:
> if (drag)
> {
> tree.setInsertMark(null, false);
> exitDrag = true;
> drag = false;
> }
> break;
> case SWT.MouseUp:
> {
> if (!drag)
> return;
> tree.setInsertMark(null, false);
> TreeItem item = tree.getItem(new Point(p.x, p.y));
> if (item != null)
> {
>
> int toindex = treeItems.indexOf(item.getText());
> System.out.println("Insertion point " +
> item.getText());
>
> int fromindex =
> treeItems.indexOf(dragItem.getText());
> System.out.println("Removing " + fromindex);
> treeItems.remove(fromindex);
> treeItems.add(toindex, dragItem.getText());
> System.out.println("Adding toIndex: " + toindex + "
> "
> + dragItem.getText());
> refreshTree(false);
>
> }
> drag = false;
> exitDrag = false;
> dragItem = null;
> break;
> }
> case SWT.MouseMove:
> {
> if (!drag)
> return;
> TreeItem item = tree.getItem(new Point(p.x, 2));
> if (item == null)
> {
> tree.setInsertMark(null, false);
> return;
> }
> Rectangle rect = item.getBounds();
> boolean after = p.x > rect.x + rect.width / 2;
> tree.setInsertMark(item, after);
> break;
> }
> }
> }
> };
> tree.addListener(SWT.DragDetect, listener);
> tree.addListener(SWT.MouseUp, listener);
> tree.addListener(SWT.MouseMove, listener);
> tree.addListener(SWT.MouseExit, listener);
> tree.addListener(SWT.MouseEnter, listener);
> shell.open();
> while (!shell.isDisposed())
> {
> if (!display.readAndDispatch())
> display.sleep();
> }
> display.dispose();
> }
>
> }
>
> "kent" <kent@generatescape.com> wrote in message
> news:cv8qs8$ac2$1@www.eclipse.org...
>> Hi-ya All,
>>
>> I is having a wee bit of a problem with dnd and some pointers would be
>> nice.
>>
>> Alrighty I want to be able to move nodes around in a tree.
>>
>> So my target and my source are the same.
>>
>> I am using a contentprovider and label provider.
>>
>> Everything seems to work until I get to the drop. The last method in the
>> code snippet is where my problem seems to be.
>>
>> I I don't really know what to do at that point. I can go and create a new
>> TreeItem and put it into the tree but where exactly is it going into the
>> tree? And then how do I go and delete the old TreeItem from the tree?
>>
>> Is there any better transfer method for TreeItems?
>>
>> Here is a snippet. Thanks a billion.
>>
>> // Allow data to be copied or moved to the drop target
>> int operations = DND.DROP_MOVE;
>> DropTarget target = new DropTarget(tv.getTree(), operations);
>>
>> // Receive data in Text or File format
>> final TextTransfer textTransfer = TextTransfer.getInstance();
>> types = new Transfer[] { textTransfer };
>> target.setTransfer(types);
>>
>> DragSource source = new DragSource(tv.getTree(), operations);
>> source.setTransfer(types);
>>
>> source.addDragListener(new DragSourceAdapter()
>> {
>>
>> public void dragSetData(DragSourceEvent event)
>> {
>> // Provide the data of the requested type.
>> if
>> (TextTransfer.getInstance().isSupportedType(event.dataType))
>> {
>> DragSource ds = (DragSource) event.widget;
>> Tree tree = (Tree) ds.getControl();
>>
>> TreeItem[] selection = tree.getSelection();
>>
>> for (int i = 0; i < selection.length; i++)
>> {
>> // right now I don't care about multiple selection
>> event.data = selection[i].getText();
>> } // end for
>> } // end if
>> }
>> });
>>
>> target.addDropListener(new DropTargetAdapter()
>> {
>> public void dragEnter(DropTargetEvent event)
>> {
>> if (event.detail == DND.DROP_DEFAULT)
>> {
>> event.detail = (event.operations & DND.DROP_COPY) != 0
>> ? DND.DROP_COPY
>> : DND.DROP_NONE;
>> }
>>
>> // Allow dropping text only
>> for (int i = 0, n = event.dataTypes.length; i < n; i++)
>> {
>> if (TextTransfer.getInstance().isSupportedType(
>> event.dataTypes[i]))
>> {
>> event.currentDataType = event.dataTypes[i];
>> }
>> }
>> }
>>
>> public void dragOver(DropTargetEvent event)
>> {
>> // Provide visual feedback
>> event.feedback = DND.FEEDBACK_SELECT |
>> DND.FEEDBACK_SCROLL;
>> }
>>
>> public void drop(DropTargetEvent event)
>> {
>> System.out.println("drop");
>>
>> if (textTransfer.isSupportedType(event.currentDataType))
>> {
>>
>> String text = (String) event.data;
>> DropTarget target = (DropTarget) event.widget;
>>
>> Tree tree = (Tree) target.getControl();
>>
>> TreeItem ti = new TreeItem(tree, SWT.NONE);
>> ti.setText(text);
>>
>> // this is my treelabelprovider
>> ftlp.toggle();
>> // my treeviewer
>> tv.refresh();
>>
>> }
>>
>> }
>> });
>>
>>
>
>
Previous Topic:How to rotate a low res image?...
Next Topic:How to save swt.opengl image to a PNG file
Goto Forum:
  


Current Time: Fri Apr 26 23:49:43 GMT 2024

Powered by FUDForum. Page generated in 0.03102 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top