# [SWT] Seltsames verhalten bei TableViewer mit TextCellEditor



## dzim (24. Apr 2008)

Hallo zusammen,

ich habe mich (nachdem ich die ersten Stolpersteine von RCP irgendwie in den Griff bekomm habe) mit meiner GUI weiterbeschäftigt.
Ich lasse Daten einer CSV-Datei (von dynamischen Inhalt - Zeilen- sowie Spaltenzahl sind nicht fix) in einen TableViewer einlesen.
Das klappt auch alles ganz fein, aber mit dem hinzufügen von TextCellEditoren fing mein "übel" an:
Die TextCellEditoren scheinen konkrete Platzhalter in meinem SWT-GridLayout ainzunehmen, so dass nun unter meiner Tabelle ein riesiger (eta so hoch wie die Tabelle selbst) freier Raum entstand.
Ich dachte dagegen, dass diese Editoren direkt auf die Table im TableViewer registriert werden und somit "unsichtbar" sind.
Das allein aber ist noch nicht alles:
Dieser freie Raum ist hässlich, aber wirklich eklig ist, dass das modifizieren der Zellen nicht in der Table angezeigt wird, sondern am Anfang des Composites, in dem ich mich befinde.
Ich kann es schlecht beschreiben, aber es wird quasi auf dem Hintergrund des Composites angezeigt, aber - sobald sich dieser platz mit einem Objekt, wie einem Label oder eben meines TableViewers, überschneidet - in den Hintergrund der Objekte gelegt. Klar soweit?

Siehst du Kot:

```
public void createPartControl(Composite parent) {

		GridLayout layout = new GridLayout();
		layout.numColumns = 2;

		parent.setLayout(layout);

		this.csvFile = View.getCSVFile();

		final Label header = new Label(parent, SWT.NONE);
		header.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false,
				2, 1));
		header.setAlignment(SWT.CENTER);
		header
				.setText("Edit CSV File until no further errors occur and process it");
		

		final Button checkButton = new Button(parent, SWT.NONE);
		final GridData gd_checkButton = new GridData();
		checkButton.setLayoutData(gd_checkButton);
		checkButton.setText("&Check");
		checkButton.addSelectionListener(this.getCheckButtonSelectionListener());

		final Button processButton = new Button(parent, SWT.NONE);
		final GridData gd_processButton = new GridData(SWT.RIGHT, SWT.CENTER,
				false, false);
		processButton.setLayoutData(gd_processButton);
		processButton.setText("&Process It!");

		messageText = new Text(parent, SWT.MULTI | SWT.BORDER);
		final GridData gd_messageText = new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1);
		gd_messageText.heightHint = 77;
		messageText.setLayoutData(gd_messageText);

		tableViewer = new TableViewer(parent, SWT.BORDER);
		
		tableViewer.setUseHashlookup(true);
		tableViewer.setColumnProperties(csvFile.getCSVHeader());
		
		TextCellEditor[] cellEditors = new TextCellEditor[csvFile.getCSVHeader().length];
		for (int i = 0; i < csvFile.getCSVHeader().length; i++) {
			cellEditors[i] = new TextCellEditor(parent);
			((Text) cellEditors[i].getControl()).setTextLimit(20);
		}
		tableViewer.setCellEditors(cellEditors);
		
		tableViewer.setCellModifier(new ICellModifier() {
			public boolean canModify(Object element, String property) {
				return true;
			}

			public Object getValue(Object element, String property) {
				String[] header = csvFile.getCSVHeader();
				for (int i = 0; i < header.length; i++) {
					if (header[i].equals(property))
						return ((String[])element)[i];
				}
				
				return "";
			}

			public void modify(Object element, String property, Object value) {
				TableItem tableItem = (TableItem) element;
				
				String[] header = csvFile.getCSVHeader();
				String[] data = (String[]) tableItem.getData();
				
				for (int i = 0; i < header.length; i++) {
					if (header[i].equals(property))
						data[i] = value.toString();
				}
				
				tableViewer.refresh(data);
			}
		});
		
//		tableViewer.setCellEditors(new CellEditor[] { new TextCellEditor(parent),
//				new ComboBoxCellEditor(parent, (String[])csvFile.getCSVFile().toArray()) });
		
		table = tableViewer.getTable();
		
		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
		
		for (int i = 0; i < csvFile.getCSVHeader().length; i++) {
			final TableColumn newColumnTableColumn = new TableColumn(table, SWT.NONE);

			final int index = i;

			newColumnTableColumn.setWidth(100);
			newColumnTableColumn.setText(csvFile.getCSVHeader()[i]);
			newColumnTableColumn.addListener(SWT.Selection, new Listener() {
	            @Override
	            public void handleEvent(Event event) {
	                System.err.println("Event : " + event);
	                //viewer.refresh();
	                if(table.getSortColumn() == newColumnTableColumn) {
	                    table.setSortDirection(table.getSortDirection() == SWT.UP ? SWT.DOWN : SWT.UP);
	                } else {
	                    table.setSortColumn(newColumnTableColumn);
	                    table.setSortDirection(SWT.UP);
	                }
	                
	               
	                final int direction = table.getSortDirection() == SWT.UP ? 1 : -1;
	                tableViewer.setComparator(new ViewerComparator() {
	                    @Override
	                    public int compare(Viewer viewer, Object e1, Object e2) {
	                    	System.err.println("e1: " + e1);
	                    	System.err.println("e2: " + e2);
	                        return direction * super.compare(viewer, ((String[])e1)[index], ((String[])e2)[index]);
//	                    	return 0;
	                    }
	                });
	            }
	        }); 
		}
		
		tableViewer.setContentProvider(
				new CSVTableContentProvider(tableViewer,this.csvFile));
		tableViewer.setLabelProvider(new CSVTableLabelProvider());
		tableViewer.setInput(getEditorSite());// csvFile);
	}
```

Dieses Problem beschäftigt mich seit ungefähr gestern Mittag und das finde ich über alle Maßen lästig.

Vielleicht hat einer ja DIE zündende Idee, dieses Ärgernis aus dem Weg zu Räumen...

Vielen Dank jedenfalls (für die Geduld dieses Pampflet durchzulesen) und Viele Grüße!


----------



## dzim (24. Apr 2008)

Also um das seltsame Verhalten noch etwas zu konkretisieren:
Es schein so, als würde durch die CellEditoren eine Zweite Tabelle aufgezeichnet werden, die sich sogar relativ zur originalen Tabelle verhält.
Scrolle ich in der einen, so ist der editirbare Wert auf dem Composit zu sehen, wei er hoch/runter läuft... Das ist echt "strange"


----------



## Wildcard (24. Apr 2008)

Du meinst das hier?
	
	
	
	





```
//      tableViewer.setCellEditors(new CellEditor[] { new TextCellEditor(parent),
//            new ComboBoxCellEditor(parent, (String[])csvFile.getCSVFile().toArray()) });
```
Du setzt sie doch explizit auf den Parent, was erwartest du denn  ???:L


----------



## dzim (24. Apr 2008)

Ok. Wenn, dann war das hier das Problem:


```
TextCellEditor[] cellEditors = new TextCellEditor[csvFile.getCSVHeader().length];
      for (int i = 0; i < csvFile.getCSVHeader().length; i++) {
         cellEditors[i] = new TextCellEditor(parent);
         ((Text) cellEditors[i].getControl()).setTextLimit(20);
      }
      tableViewer.setCellEditors(cellEditors);
```

Was du gerade mir gezeigt hast, erklärt es zwar, ist aber auskommentiert... wie du im nachhinein vielleicht erkennst.
Danke dennoch.

Wirklich geholfen aber hat mir nach lagem Rätzeln wieder einmal Lars Vogels Tutorial:
http://www.vogella.de/articles/EclipseJFaceTable/article.html

Neue Klasse CSVTableEditingSupport angelegt, die macht das ganze und *schwupps* schon geht's...

Danke dennoch!!!


----------



## Wildcard (24. Apr 2008)

> new TextCellEditor(parent);


Ja, das gleiche in Grün.
fremden GUI Code anzuschauen ist in der Regel kein Spaß, da vertiefe ich mich nicht zu sehr  :wink:


----------



## dzim (24. Apr 2008)

Hehe, das kann ich nur zu gut verstehen - wenn man "eiligen" Code geschrieben hat, ist es ja schon für einen selbst schwer päter noch durchzuschaun - wenn man nicht ständig mit der entsprechenden technik arbeitet...


----------

