ERLEDIGT
NEIN
NEIN
ANTWORTEN
3
3
ZUGRIFFE
551
551
EMPFEHLEN
-
07.06.11 09:13 #1
- Registriert seit
- Feb 2009
- Beiträge
- 7
Hallo allerseits,
es gibt zwar schon hunderte DND Threads aber keiner beantwortet mein folgendes Problem:
Ich habe eine GUI mit einem Graphen (Jung 2.0.1 mit Swing) auf der rechten und einem Tree (SWT) auf der linken Seite.
Der Tree enthält mehrere Items mit "Element" als Data Objekt. Die Element Objekte werden mit Hibernate aus einer Datenbank ausgelesen und haben dementsprechend (weil Tree) "parent" und "child" Attribute. Außerdem stehen sie untereinander auch noch in einer Beziehung, die ich hier mal Abhängigkeit(en) nennen möchte.
Der Graph ist vorerst leer und ich möchte per DND Elemente aus dem Tree hinein ziehen. Wenn ein Element A dem Graphen hinzugefügt wird, werden alle anderen Elemente, die mit diesem Element A in Verbingung stehen ebenfalls hinzugefügt und durch Kanten dementsprechend verbunden.
Meine aktuelle Lösung sieht in etwa wie folgt aus:
Beim Drag wird die Id bzw. die Ids der slektieren Items als String mit Semikolons getrennt übergeben (ID = Primärschlüssel). Beim Drop wird der String dann wieder gesplittet und jedes Element anhand der ID aus der Datenbank ausgelesen und dem Graphen hinzugefügt.
Frage: gibt es eine bessere / elegantere Lösung? Wie ist das mit einem eigenen TransferType bei komplexen Objekten wie meinem "Element" Objekt, welches n Kinder und n Abhängige Objekte etc. haben kann? Natürlich könnte man auch beim Drag die selektierten Elemente in ein Singleton schreiben und beim Drop dann raus holen (dann spart man sich den Datenbankzugriff), aber das ist ja auch irgendwie halbherzig.
Mir ist bewusst, dass ich keinen eigenen TransferType benötige, wenn ich Objekte nicht Anwendungsübergreifend Draggen will, aber die Lösung mit dem String kommt mir nicht sonderlich schön vor.
Wen es interessiert hier mein SourceAdapter (Tree) und DropTarget(Graph):
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
public class TreeSourceAdapter extends DragSourceAdapter { TreeItem[] dragSourceItems = null; Tree tree; public TreeSourceAdapter(Tree tree) { super(); this.tree = tree; } public void dragStart(DragSourceEvent event) { TreeItem[] selection = tree.getSelection(); if (selection.length > 0) { event.doit = true; dragSourceItems = selection; } else { event.doit = false; } } public void dragSetData(DragSourceEvent event) { String ids = ""; for (TreeItem treeItem : dragSourceItems) { Element e = (Element) treeItem.getData(); String id = String.valueOf(e.getId()); if (ids.equals("")) { ids += id; } else { ids += ";" + id; } } event.data = ids; } public void dragFinished(DragSourceEvent event) { dragSourceItems = null; } }
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
public void drop(DropTargetDropEvent dtde) { dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); String o = null; try { o = (String)dtde.getTransferable().getTransferData(DataFlavor.stringFlavor); } catch (Exception ex) { } String[] ids = o.split(";"); DaoFactory daoFactory = new DaoFactory(); ElementDao dao = daoFactory.getElementDao(); for (String idString : ids) { Long id = Long.valueOf(idString); Element e = dao.getById(id); graph.addElement(e); } }
-
07.06.11 13:53 #2
- Registriert seit
- Feb 2009
- Beiträge
- 193
Es wäre erst mal ganz nett gewesen, wenn du uns mitgeteilt hättest, dass der DragSourceAdapter den du verwendest nicht in der Standardbibliothek vorhanden ist, sondern in org.eclipse.swt.dnd, das hätte einiges schonmal um ein vielfaches einfacher gemacht.
Was die eigentliche Frage betrifft, ich würde an deiner Stelle einen eigenen DataFlavor anlegen.
Würde für deinen Fall dann so aussehen:
Code java:1
DataFlavor treeItemFlavor = new DataFlavor(TreeItem.class, "TreeItem");
Das wäre die saubere Methode denke ich.
-
07.06.11 14:12 #3
- Registriert seit
- Feb 2009
- Beiträge
- 7
Sorry, ich hatte extra dazu geschrieben, dass es ein SWT Tree ist. Ich bin davon ausgegangen, dass man dann den swt Listener nehmen muss. Ich hab das mit dem DataFlavor auch schon öfter mit JTrees etc. gemacht, wusste aber bis jetzt nichts, dass das auch mit swt widgets so funktioniert und bin ich auch nicht auf die Idee gekommen. Ich werds heute abend mal ausprobieren.
Vielen Dank!
-
15.06.11 15:59 #4
- Registriert seit
- Feb 2009
- Beiträge
- 7
Also ich komme so ehrlich gesagt nicht weiter. Ich habe mir jetzt mal ein minimal Bespiel gebastelt, mit einem SWT Tree als Quelle und einer JTextArea als Ziel. Ich poste es mal hier kommentarlos (vielleicht hilft es ja anderen bei ähnlichen Problemen):
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
import java.awt.BorderLayout; import java.awt.Frame; import java.awt.Panel; import java.awt.datatransfer.DataFlavor; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetAdapter; import java.awt.dnd.DropTargetDropEvent; import javax.swing.JTextArea; import org.eclipse.swt.SWT; import org.eclipse.swt.awt.SWT_AWT; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DragSource; import org.eclipse.swt.dnd.DragSourceAdapter; import org.eclipse.swt.dnd.DragSourceEvent; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; public class DnDTest { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); FillLayout fillLayout = new FillLayout(); shell.setLayout(fillLayout); final Tree tree = new Tree(shell, SWT.BORDER | SWT.MULTI); for (int i = 0; i < 5; i++) { TreeItem treeItem = new TreeItem(tree, SWT.NONE); treeItem.setText("Item " + (i + 1)); } Composite composite = new Composite(shell, SWT.EMBEDDED | SWT.NO_BACKGROUND); Frame frame = SWT_AWT.new_Frame(composite); Panel panel = new Panel(new BorderLayout()); frame.add(panel); final JTextArea jTxtArea = new JTextArea(); panel.add(jTxtArea, BorderLayout.CENTER); DragSource ds = new DragSource(tree, DND.DROP_DEFAULT | DND.DROP_COPY | DND.DROP_MOVE); ds.setTransfer(new Transfer[] { TextTransfer.getInstance() }); ds.addDragListener(new DragSourceAdapter() { private TreeItem[] selection = null; @Override public void dragStart(DragSourceEvent event) { selection = tree.getSelection(); } @Override public void dragSetData(DragSourceEvent event) { String s = ""; for (TreeItem item : selection) { s += (String) item.getText() + "\n"; } event.data = s; } }); DropTarget jTxtAreaDropTarget = new DropTarget(jTxtArea, new DropTargetAdapter() { @Override public void drop(DropTargetDropEvent dtde) { dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); String o = "nope"; try { o = (String) dtde.getTransferable().getTransferData(DataFlavor.stringFlavor); } catch (Exception ex) { ex.printStackTrace(); } jTxtArea.append(o); } }); jTxtArea.setDropTarget(jTxtAreaDropTarget); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }
Auch hier habe ich wieder den DragSource aus dem SWT package genommen. Hier wird auch wieder nur ein String (der Text des TreeItems) übergeben. Ich habe den Tree absichtlich mit SWT.MULTI instanziert, da das draggen mehrerer Items möglich sein soll. Mein Problem verstärkt sich zudem noch dadurch, dass ein TreeItem verschiedene Objekte enthalten kann. Damit meine ich, dass zwar klar ist welche das sein können, aber nicht in jeden TreeItem der gleiche Objekttyp drinnen ist. Daher reicht es auch nicht mehr, wie in meinem Ursprungspost beschrieben, nur IDs zu übergeben, da zwei verschiedene Objekte die gleiche ID haben können, wenn sie nicht den gleichen Typ haben.
Das Problem was ich habe ist an sich nicht, wie ich beim DropTarget ein TreeItem in empfang nehme, sondern eher wie ich es beim DragSource rein bekomme. Bei SWT muss man ja dazu org.eclipse.swt.dnd.ByteArrayTransfer erweitern und die beiden Methoden javaToNative und nativeToJava überschreiben. Bei dem Veruch habe ich schon Probleme mit einem TreeItem, welches ich nicht einfach in ein Byte Array "umwandeln" kann. An andere Stelle habe ich auch gelesen, dass man ein TreeItem nicht draggen kann und auch nicht soll, sondern nur die Elemente darin (also Tree.data).
Wenn ich nun veruche das AWT DragSource zu verwenden, funtioniert das auch nicht, da ein SWT Tree keine Component ist, wie sie java.awt.dnd.DragSource.createDefaultDragGestureRecognizer() erwartet. Ich denke dass was ich vorhabe funktioniert so einfach nicht. Ich werde, dann eben doch einfach den TextTransfer auf der Drag Seite und das DataFlavor.stringFlavor auf der Drop Seite verwenden und mit die Strings so zusammen basteln, wie ich sie brauche. Ich poste mal eine Quick & Dirty Lösung wenn ich fertig bin.
Ähnliche Themen
-
Drag 'n' Drop mit JS
Von ts230 im Forum Javascript & AjaxAntworten: 23Letzter Beitrag: 26.08.08, 10:23 -
SWT Drag&Drop
Von HuberDe im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 0Letzter Beitrag: 27.09.07, 08:15 -
Daten aus DBgrid feld per drag & drop oder doppelklick
Von epicone im Forum C/C++Antworten: 1Letzter Beitrag: 29.08.06, 14:07 -
SWT: Ghosted Drag-Image bei Drag & Drop
Von snake_plissken im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 1Letzter Beitrag: 15.04.06, 23:36 -
Ist das die Drag`n Drop Technik oder ein AS ?
Von designjunkee im Forum Flash PlattformAntworten: 2Letzter Beitrag: 05.03.04, 07:44





Zitieren
Login





