SWT Table sortieren

I dont use Jtable

Hi again,

I only use the normal Table from eclipse SWT sorry but i can't do nothing with this example :-(
 
Original geschrieben von Thomas Darimont
Hallo!



Das verstehe ich nicht. Was für ein Problem hast du denn mit dem Eclipse Snippet?

Gruß Tom

Also ich hab das Snippet benutzt:
http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/platform-swt-home/snippits/snippet2.html

Ich habe eine Tabelle mit 4 Spalten und 10 Zeilen.
Spalten: ID, Name, Description, Article Number

Wenn ich jetzt den Listener mit dem CodeSnippet auf meine Spalte Setzte! Von mir aus Name, dann muss ich ca. 4- 5 mal auf die Spalte klicken, damit die Liste danach sortiert ist!
 
Ich hab jetzt auch nochmal das Snippet allein ausprobiert. Sobald ich mehr als 5 Einträge im Table habe, dann kommt eine org.eclipse.swt.SWTException: Widget is disposed Exception

Kann mir da jemand weiterhelfen? Was mache ich nur falsch!
 
Hallo!

Versuchs mal hiermit:

Code:
import java.util.Arrays;
import java.util.Random;

import org.eclipse.swt.SWT;
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.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

/*
 * Created on 02.06.2004
 */

/**
 * @author Administrator
 *
 */
public class SWTTableTest {

	public static void main(String[] args) {
		new SWTTableTest().doIt();
	}

	private void doIt() {

		Display display = new Display();
		Shell shell = new Shell(display);

		Random rnd = new Random();

		final Table table =
			new Table(shell, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION);
		table.setSize(320, 240);
		table.setLinesVisible(true);
		table.setHeaderVisible(true);

		//Tabellenspaltenbeschriftungen festlegen
		String[] clmHeader = new String[] { "A", "B", "C", "D" };
		//Tabelle mit zufälligen Buchstabenfüllen
		for (int i = 0; i < clmHeader.length; i++) {
			TableColumn column = new TableColumn(table, SWT.NONE);
			column.setText(clmHeader[i]);
			column.setWidth(50);
		}
		//Tabelle mit zufälligen Buchstaben füllen
		for (int i = 0; i < 10; i++) {
			TableItem tableItem = new TableItem(table, SWT.NONE);
			tableItem.setText(
				new String[] {
					"" + (char) (65 + rnd.nextInt(26)),
					"" + (char) (65 + rnd.nextInt(26)),
					"" + (char) (65 + rnd.nextInt(26)),
					"" + (char) (65 + rnd.nextInt(26)),
					});
		}

		TableColumn[] columns = table.getColumns();

		//Auf jede Tabellenspalte einen Listener legen
		for (int i = 0; i < columns.length; i++) {
			final int _i = i;
			columns[i].addListener(SWT.Selection, new Listener() {
				private int colPos = -1;
				private boolean sortFlag;
				{
					colPos = _i;
				}
				public void handleEvent(Event event) {
					System.out.println("Mouse Clicked on " + colPos);
					sortFlag = !sortFlag;
					//Sort
					System.out.println(sortFlag);
					TableItem[] tableItems = table.getItems();
					sortTable(table, tableItems, colPos, sortFlag);
				}

			});
		}

		shell.setSize(320, 240);
		shell.setText("TableTest");
		shell.open();

		while (!shell.isDisposed())
			if (!display.readAndDispatch())
				display.sleep();

		display.dispose();
	}

	/**
	 * Hier werden die Daten der Spalten des "original" TableItem[] in einen MyComperatorArray
	 * umkopiert und darauf hin wird dieser mittels der Array.sort(Object[] o) Methode sortiert.
	 * Da sich der MyComperator die ursprüngliche Position in der Tabelle gemerkt hat, kann
	 * man nun ganz einfach die entsprechenden Werte im Original Array tauschen und schon ist man fertig.  
	 * @param tableItems
	 */
	protected void sortTable(
		Table table,
		TableItem[] tableItems,
		int colPos,
		boolean sortFlag) {

		int clmCnt = table.getColumnCount();
		MyComparator[] comparators = new MyComparator[tableItems.length];
		String[] textBuffer = null;

		for (int i = 0; i < tableItems.length; i++) {
			textBuffer = new String[clmCnt];

			for (int j = 0; j < textBuffer.length; j++)
				textBuffer[j] = tableItems[i].getText(j);
			comparators[i] = new MyComparator(textBuffer, i, sortFlag, colPos);
		}

		Arrays.sort(comparators);

		String[] tmp;
		textBuffer = new String[clmCnt];
		for (int i = 0; i < comparators.length; i++) {
			int rowNum = comparators[i]._oldRowNum;

			tmp = comparators[i]._textBuffer;
			tableItems[rowNum].setText(comparators[rowNum]._textBuffer);
			tableItems[i].setText(tmp);
		}
		
	}

	/**
	 * 
	 * @author Administrator
	 * Eigener Comperator der das Vergleichen der einzelnen Tabellenzeilen vornimmt... 
	 */

	class MyComparator implements Comparable {

		private String[] _textBuffer;
		private int _oldRowNum;
		private boolean _sortFlag;
		private int _colPos;

		/**
		 * Konstruktor ...
		 * @param textBuffer : Der Text der Zeile 
		 * @param rowNum : Die Zeilennr der Tabellenzeile 
		 * @param sortFlag : Aufsteigend false, Absteigend true
		 * @param colPos : Die Spalte nach der Sortiert werden soll
		 */

		public MyComparator(
			String[] textBuffer,
			int rowNum,
			boolean sortFlag,
			int colPos) {
			_textBuffer = textBuffer;
			_oldRowNum = rowNum;
			_sortFlag = sortFlag;
			_colPos = colPos;
		}

		public int compareTo(Object arg0) {
			int ret =
				_textBuffer[_colPos].compareTo(
					((MyComparator) arg0)._textBuffer[_colPos]);
			if (_sortFlag)
				ret *= -1;
			return ret;
		}

	}

}

Btw. bei mir funktioniert das Eclipse Snippet einwandfrei.... ;-)

Gruß Tom
 
Zuletzt bearbeitet:
Super geil ein riesen dankeschön!

Aber noch eine Frage: Könnte man die MyComperator Klasse so erweitern, dass es nicht auf case Sensitiv reagiert? Dein Beispiel füllt die Tabelle mit Großbuchstaben. Wenn ich jetzt aber zum Beispiel ein kleines a hinzufüge und dann auf sortieren klicke, dann schiebt der alg das kleine "a" bis ans ende bzw. bei absteigend ganz an den Anfang.

Danke im vorraus!
 
Hallo!

Wie wärs denn dann mit :

Code:
		public int compareTo(Object arg0) {
			int ret =
				_textBuffer[_colPos].toUpperCase().compareTo(
					((MyComparator) arg0)._textBuffer[_colPos].toUpperCase());
			if (_sortFlag)
				ret *= -1;
			return ret;
		}

Ps.: an der ganzen Sache sollte man noch etwas feilen .... glaube nicht, dass dier Performance von diesem Beispiel für "reale" Anwendungen ausreicht...

Gruß Tom
 
Ich habs mal mit 100.000 Einträgen getestet .. Es sind respektable 17 sekunden!
Angesichts der menge an daten ist dies durchaus ok!
Könnte man jetzt die compareTo Methode so anpassen, dass auch zahlen richtig sortiert werden?

Sorry aber ich hab keine Ahnung von Sortieralgorithmen..
 

Neue Beiträge

Zurück