# SWT Drag&Drop / Table



## sutcha (24. Sep 2007)

Hallo,

ich versuche eine Tabelle dynamisch zu erstellen.
Wenn ich zB 4 Objekte (Buttons, Labels) habe, soll die Tabelle 4 Zeilen und 4 Reihen haben. In der 1. Zeile sollen die Objekte stehen (diese will ich auch dynamisch erzeugen). Jetzt will ich diese Objekte in der Tabelle per Drag&Drop verschieben können. Anschließend will ich die aktuelle Position auslesen (zB 2. Spalte, Reihe 3).

Wie ich einfach Labels in eine Tabelle zieh, weiß ich. Allerdings habe ich keine Erfahrung mit dynamischen Erzeugen von Objekten. Bisher scheitere ich schon an der Erzeugung der Spalten 
Kann man Opjekte nur mit Hilfe von einer Liste dynamisch erzeugen? Also immer ein Objekt instanzieren und dann der Liste hinzufügen? 
Drag&Drop bei dem die Source gleichzeitig auch das Target ist, funktioniert das? Ich habe ein bisschen rumprobiert, bin aber nicht wirklich vorangekommen.
Ich wäre sehr dankbar, wenn mir jemand helfen könnte! gegoogelt habe ich schon, aber bisher nichts brauchbares gefunden.

Vielen Dank schonmal!

Gruß

sutcha


----------



## sutcha (25. Sep 2007)

```
for (int j = 0; j < 2; j++) {
				TableColumn column = new TableColumn(table, SWT.NONE);
				column.setWidth(50);
			    
				for (int i = 0; i < 3; i++) {
					TableItem item = new TableItem(table, SWT.NONE);
					item.setText(j,"Position "+i);
				}
			}
```

So erzeuge ich meine Tabelle, die 2 Spalten und 3 Zeilen haben soll. 
Wenn ich mich nicht irre, sollte doch in der 1. Zeile Position 0 | Position 0 stehen, also in beiden Spalten das gleiche.
bei mir kommt aber:
Pos 0 |
Pos 1 |
Pos 2 |
         |   Pos 0 
         |   Pos 1
         |   Pos 2

Die rechte Spalte hat meiner Meinung nach die falschen Indices (3-5 statt 0-2)

Ich kann dem  TableItem auch den Index übergeben, also hier das "i", aber dann kommt das gleiche wie oben nur spiegelverkehrt. 
Was mache ich falsch?


----------



## sutcha (25. Sep 2007)

```
DragSource source = null;
			table = new Table(bildschirmComposite,SWT.BORDER);
			table.setLinesVisible(true);
					
			
		    for (int j = 0; j < 2; j++) {
				TableColumn column = new TableColumn(table, SWT.NONE);
				column.setWidth(50);
			    
				for (int i = 0; i < 3; i++) {
					TableItem item = new TableItem(table, SWT.NONE);
					item.setText(j,"Position "+i);
				}
			}
			
			
			source = new DragSource(table, DND.DROP_MOVE);
			Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
			source.setTransfer(types);
			
			source.addDragListener(new DragSourceAdapter() {
				public void dragSetData(DragSourceEvent event) {
					DragSource ds = (DragSource) event.widget;
					Table table = (Table)ds.getControl();
					TableItem[] selection = table.getSelection();
					
					StringBuffer buff = new StringBuffer();
					for (int i = 0, n = selection.length; i < n; i++) {
						buff.append(selection[i].getText());
					}
					
					event.data = buff.toString();
				}
			});
			
			
			
			DropTarget target = new DropTarget(table, DND.DROP_MOVE);
		    target.setTransfer(types);
		    target.addDropListener(new DropTargetAdapter() {
		      public void dragEnter(DropTargetEvent event) {
		        
		    	// 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) {
		         event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL;
		      }
		      public void drop(DropTargetEvent event) {
		        if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
		          // Get the dropped data
		          DropTarget target = (DropTarget) event.widget;
		          Table table = (Table) target.getControl();
		          String data = (String) event.data;

		          // Create a new item in the table to hold the dropped data
		          TableItem item = new TableItem(table, SWT.NONE);
		          item.setText(new String[] { data });
		          table.redraw();
		        }
		      }
		    });
```

Das ist der gesamte Code für meine Drag&Drop Table.
Ich kann nur von Spalte 1 etwas nehmen und kann es auch nur dorthin droppen. Ich möchte es aber verschieben können, momentan wird eine Kopie gedropt und es wird auch nicht an der gewünschten Stelle gedroppt sondern immer als unterstes Item der Tabellenspalte.
Kennt sich denn niemand in dem Bereich aus? 

Ich verzweifel langsam


----------



## sutcha (26. Sep 2007)

Wie finde ich heraus, welche Source wo gedroppt wurde? 
Ich habe mir sonst überlegt, eine Tabelle mit Labels zu füllen und jedem Label dann einen Listener hinzuzufügen. Das gleiche mache ich mit der Source, jede Source wird extra definiert. Die Source ist aber nichtmehr in der Tabelle, sondern als Label oben drüber oder so.
Dann sollte ich die Source in jedes Target ziehen können. Wenns erfolgreich war, wird die Source gelöscht, dh. der Text = "". Nur muss ich dann wissen, in welches Target die Source gekommen ist, damit ich eine Position im Koordinaten-System habe (Reihe, Spalte).
Funktionieren sollte es so, was meint ihr?


----------



## metaltiffy (26. Sep 2007)

Vielleicht kann man das mit einem Cursor machen


```
item1.setText(i - 1, rs.getString(i));
		Cursor cursor = new TableCursor(table, SWT.NONE);	
					cursor.addSelectionListener(new SelectionAdapter() {
						public void widgetSelected(SelectionEvent e) {
							table.setSelection(new TableItem[] {cursor.getRow()});
							TableItem row = cursor.getRow();
							String string = (row.getText(0));
							dat_id = Integer.parseInt(string);
													}
						public void widgetDefaultSelected(SelectionEvent e){
							TableItem row = cursor.getRow();
							String string = (row.getText(0));
							dat_id = Integer.parseInt(string);//id aus 1. Spalte holen
													}
					});
```

So gibts du jedem Item in der Table einen Cursor, der merkt wenn er markiert wurde...
mit String string = (row.getText(0)); holst du dir zum Beispiel den eintrag aus der 1. Spalte in der markierten Zeile...
Theoretisch könnte man mit nem index ja jeden Wert nehmen...

Vielleicht hilft dir das ja ein bisschen


----------



## sutcha (26. Sep 2007)

Mit meinem og Code hab ich momentan das Problem, das die Source nicht gelöscht wird. D.h. der Wert wird nur kopiert. Mit deinem Cursor müsste ich quasi den Wert des Feldes, den ich verschieben will, in dem Moment auf "" setzen, sobald er im Ziel-Feld eingetragen wurde. 
Ich bin gerade am überlegen, wie ich das mit dem Cursor am besten mache. 
Meine Überlegung war, eine Liste mit Labels zu machen und dann einfach die Liste durchlaufen, bis der Wert des Labels den gewünschten Wert (der des verschobenen Labels) hat. Ein Zähler läuft dabei mit und dann kann ich an Hand der Spalten-Anzahl die genaue Position errechnen. 
Zähler: 5, Spalten: 3 -> Wert befindet sich in der 2. Zeile, 2. Spalte.

Aber das Problem, das die Source nicht gelöscht wird bzw nicht "" gesetzt wird, ist noch das gleiche.

Vielen Dank für deinen Tipp, werde da mal paar Sachen versuchen


----------



## sutcha (26. Sep 2007)

```
Transfer[] types = new Transfer[] { TextTransfer.getInstance() };
	    DragSource ds = new DragSource(table, DND.DROP_MOVE);
	    ds.setTransfer(types);
	    
	    ds.addDragListener(new DragSourceAdapter() {
	      public void dragSetData(DragSourceEvent event) {
	        // Get the selected items in the drag source
	        DragSource ds = (DragSource) event.widget;
	        Table table = (Table) ds.getControl();
	        TableItem[] selection = table.getSelection();

	        StringBuffer buff = new StringBuffer();
	        for (int i = 0, n = selection.length; i < n; i++) {
	          buff.append(selection[i].getText());
	        }
	        event.data = table.getItem(table.getSelectionIndex()).getText(); 
	      }
	    });
	    
	    DropTarget dt = new DropTarget(table, DND.DROP_MOVE);
		dt.setTransfer(new Transfer[] { TextTransfer.getInstance() });
	    dt.addDropListener(new DropTargetAdapter() {
	      public void dragEnter(DropTargetEvent event) {

	        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) {
	          event.detail = DND.DROP_NONE;
	          TableItem item = (TableItem) event.item;
	          if (item == null)
	            return;
	          if (item.getText() == "") {
	              event.detail = DND.DROP_MOVE;
	            } 
	      }

	      public void drop(DropTargetEvent event) {
	        if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
	          
	          DropTarget target = (DropTarget) event.widget;
	          final Table table = (Table) target.getControl();
	          String data = (String) event.data;
	          TableItem item = (TableItem) event.item;
	          item.setText(data);
	          table.getItem(table.getSelectionIndex()).setText("");
	          table.redraw();
	        }
	      }
	      
	    });
```

So schauen momentan die Drag&Drop-Listener und Events aus. 

Problem: Ich kann die Source und das Target nur innerhalb der 1. Spalte wählen.

Ich habe als Target und als Source die gesamte Table gewählt, warum geht dann nur die 1. Spalte?
Kann mir das jemand erklären?


----------



## sutcha (27. Sep 2007)

Vielleicht liegts an der Table? 

```
for (int j = 0; j < size; j++) {
			column = new TableColumn(table, SWT.NONE);
		}
	    	
	    for (int i = 0; i < size; i++) {
	    	item = new TableItem(table, SWT.NONE);
	    		for (int k = 0; k < size; k++){
	    			if (i == 0)
	    				item.setText(k,meter.get(k));
	    			else
	    				item.setText(k,"");
	    		}
	    		table.getColumn (i).pack ();	
	    }
```

Die erste Reihe der Tabelle wird mit einem Wert aus einer Liste gefüllt, alle weiteren Reihen mit "". size ist die Größe der Liste und die Tabelle soll x-Spalten und x-Zeilen haben,wobei x=size.

Ansonsten finde ich keinen Fehler, bei der Source bzw Target-Definition...


----------



## sutcha (2. Okt 2007)

Kann mir niemand helfen?
Ich find einfach nicht, woran das liegen kann. Nur die 1. Spalte kann verwendet werden. Das ist doch nicht normal oder doch? Man muss doch die ganze Tabelle benutzen können.


----------



## java_joe (27. Okt 2008)

mhhh komisch....ja TableItem ist sehr komplex und schwierig die Source raus zu finden. wir haben auch die selbe Problemstellung


----------

