SWT - TableViewer (Viele Tabellen in der Gui, wie sinnvoll auslagern)

M

Marcus W

Ich hab eine etwas umfangreichere Gui Anwendung, die zig unterschiedliche Tabellen beinhaltet.

Da ich nicht gerne code zig fach kopier, würde mich interessieren ob es einen Sinnvollen ansatz (oop) gibt, der mir erlaubt die Tabellen mithilfe einer eigenen klasse zu erzeugen.

Momentan habe ich für jede Tabelle einen Konstrukt in der Art (Siehe Code). Mir gefällt es aber eigentlich überhaupt nicht, ziemlich den selben code, zig mal zu kopieren und zu ändern.

Alternativ könnte ich mir einen initTable() vorstellen, der die LableProvider usw, dynamisch zusammenbaut anhand eines Objects in dem ich die Tabelleneigenschaften speicher, somit wäre das ganze zumindestens nicht jedesmal komplett zu kopieren. Aber so richtig oop ist das ja eher nicht.

Ich hätte gerne etwas wie:

TableViewerLog logs = new TableViewerLogs();

public TableViewerLogs implements TableViewerInterface{
// hier die Eigenschaften meiner Speziellen log Tabelle
}

public interface TableViewerInterface extends TableViewer{
// hier die Allgemeinen Dinge, wie implementierung der Sortierfunktion usw.
}

Geht das irgendwie / bzw geht es besser als mein möglicher Ansatz einen initTable(TableEigenschaften eigenschaften){} mit meinen gewünschten Tabellen Eigenschaften zu füttern udn die Tabelle dan da dynamisch zusammenzubauen!?

Danke

Aktueller Code:
Code:
		TableViewer tableViewer_1 = new TableViewer(composite_3, SWT.BORDER
				| SWT.FULL_SELECTION);

		tableViewer_1.getTable().setBounds(10, 10, 445, 262);

		initLogTable(tableViewer_1);

	private void initLogTable(TableViewer tableViewer) {
		Table table = tableViewer.getTable();

		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		tableViewer.setContentProvider(ArrayContentProvider.getInstance());


		TableViewerColumn viewerNameColumn = new TableViewerColumn(tableViewer,
				SWT.NONE);
		viewerNameColumn.getColumn().setText("Datum");
		viewerNameColumn.getColumn().setWidth(120);
		viewerNameColumn.setLabelProvider(new CellLabelProvider() {
			@Override
			public void update(ViewerCell cell) {
				DateFormat formatter = new SimpleDateFormat(
						"dd.MM.yy - hh:mm:ss");
				cell.setText(formatter.format(((Log) cell.getElement())
						.getDate()));
			}
		});

		TableViewerColumn viewerNameColumn2 = new TableViewerColumn(
				tableViewer, SWT.NONE);
		viewerNameColumn2.getColumn().setText("User");
		viewerNameColumn2.getColumn().setWidth(65);
		viewerNameColumn2.setLabelProvider(new CellLabelProvider() {
			@Override
			public void update(ViewerCell cell) {
				cell.setText(((Log) cell.getElement()).getUser());
			}
		});

		TableViewerColumn viewerNameColumn3 = new TableViewerColumn(
				tableViewer, SWT.NONE);
		viewerNameColumn3.getColumn().setText("Action");
		viewerNameColumn3.getColumn().setWidth(230);
		viewerNameColumn3.setLabelProvider(new CellLabelProvider() {
			@Override
			public void update(ViewerCell cell) {
				cell.setText(((Log) cell.getElement()).getAction());
			}
		});

		ArrayList<Log> logs = new ArrayList<Log>();
		logs.add(new Log("Test Aktion 1", "Marcus"));
		logs.add(new Log("Test Aktion 2", "Marcus"));
		logs.add(new Log("Test Aktion 3", "Marcus"));
		logs.add(new Log("Test Aktion 4", "Marcus"));
		logs.add(new Log("Test Aktion 5", "Marcus"));
		logs.add(new Log("Test Aktion 1", "Daniel"));
		logs.add(new Log("Test Aktion 2", "Daniel"));
		logs.add(new Log("Test Aktion 3", "Daniel"));
		logs.add(new Log("Test Aktion 4", "Daniel"));

		tableViewer.setInput(logs);
	}
 
Ich hab meine code ein wenig weiter verfeinert, nun sieht es wie folgt aus.

Der interessante Teil ist in createLogTable(TableViewer tableViewer), diesen würde ich gerne noch weiter verkürzen, wie gesagt es handelt sich um 50+ Tables und das ist doch schon ziemlich aufgebläht wenn ich jedesmal für jede spalte rund 20 Zeilen Code brauche, macht 5000+ Zeilen Code oO

Also falls wer nen schöneren Ansatz hat immer her damit :)

Und vielleicht kann mir wer sagen ob ich den comperator noch "automatisieren" kann. Da es sich ja eigentlich immer um das "Feld" handelt das in cell.setText() definiert wurde, welches per comperator verglichen werden soll.

Danke

Code:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

/**
 * Creats the Tables used in the Gui
 *
 */
public final class TableHelper {
	/**
	 * Fills the provided tableViewer with our Table.
	 * This is for the logTable.
	 * 
	 * @param tableViewer
	 */
	public void createLogTable(TableViewer tableViewer){
		initTable(tableViewer);

		// Column 1
		TableViewerColumn column1 = createColumn(tableViewer, "Time", 130);
		column1.setLabelProvider(new CellLabelProvider() {
			@Override
			public void update(ViewerCell cell) {
				DateFormat formatter = new SimpleDateFormat(
						"dd.MM.yy - hh:mm:ss");
				cell.setText(formatter.format(((Log) cell.getElement())
						.getDate()));
			}
		});
		
		// Comparator for Column 1
		new ColumnViewerSorter(tableViewer, column1) {
			@Override
			protected int doCompare(Viewer viewer, Object e1, Object e2) {
				return ((Log) e1).getDate().compareTo(
						((Log) e2).getDate());
			}
		};

		// Column 2
		TableViewerColumn column2 = createColumn(tableViewer, "User", 65);
		column2.setLabelProvider(new CellLabelProvider() {
			@Override
			public void update(ViewerCell cell) {
				cell.setText(((Log) cell.getElement()).getUser());
			}
		});
		// Comparator for Column 2
		new ColumnViewerSorter(tableViewer, column2) {
			@Override
			protected int doCompare(Viewer viewer, Object e1, Object e2) {
				return ((Log) e1).getUser().compareTo(
						((Log) e2).getUser());
			}
		};

		// Column 3
		createColumn(tableViewer, "Action", 230).setLabelProvider(new CellLabelProvider() {
			@Override
			public void update(ViewerCell cell) {
				cell.setText(((Log) cell.getElement()).getAction());
			}
		});
	}

	/**
	 * creates an column and returns it
	 * @param tableViewer
	 * @param title
	 * @param width
	 * @return column
	 */
	private TableViewerColumn createColumn(TableViewer tableViewer, String title, int width) {
		// Create an TableViewerColumn for each Column
		TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
		viewerColumn.getColumn().setText(title);
		viewerColumn.getColumn().setWidth(width);
		
		return viewerColumn;
	}

	/**
	 * Initialize the table, clears, disposes and sets the contentProvider
	 * @param tableViewer
	 */
	private void initTable(TableViewer tableViewer) {
		// get the table
		Table table = tableViewer.getTable();
		
		// clear the table
		// just for the case it is used for other data / columns, too
		table.removeAll();

		// dispose the columns
		for (TableColumn t : table.getColumns()) {
			t.dispose();
		}

		// set header and lines to true, can be overwritten in the createTableX() if needed
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		
		// sets the content provider
		tableViewer.setContentProvider(ArrayContentProvider.getInstance());
	}
	
	/**
	 * Sorter class which provides the ASC / DESC sorting for columns
	 *
	 */
	private abstract class ColumnViewerSorter extends ViewerComparator {
		public int ASC = 1;
		public int NONE = 0;
		public int DESC = -1;
		private int direction = 0;
		private TableViewerColumn column;
		private ColumnViewer viewer;

		public ColumnViewerSorter(ColumnViewer viewer, TableViewerColumn column) {
			this.column = column;
			this.viewer = viewer;
			this.column.getColumn().addSelectionListener(
					new SelectionAdapter() {

						public void widgetSelected(SelectionEvent e) {
							if (ColumnViewerSorter.this.viewer.getComparator() != null) {
								if (ColumnViewerSorter.this.viewer
										.getComparator() == ColumnViewerSorter.this) {
									int tdirection = ColumnViewerSorter.this.direction;

									if (tdirection == ASC) {
										setSorter(ColumnViewerSorter.this, DESC);
									} else if (tdirection == DESC) {
										setSorter(ColumnViewerSorter.this, NONE);
									}
								} else {
									setSorter(ColumnViewerSorter.this, ASC);
								}
							} else {
								setSorter(ColumnViewerSorter.this, ASC);
							}
						}
					});
		}

		public void setSorter(ColumnViewerSorter sorter, int direction) {
			if (direction == NONE) {
				column.getColumn().getParent().setSortColumn(null);
				column.getColumn().getParent().setSortDirection(SWT.NONE);
				viewer.setComparator(null);
			} else {
				column.getColumn().getParent()
						.setSortColumn(column.getColumn());
				sorter.direction = direction;

				if (direction == ASC) {
					column.getColumn().getParent().setSortDirection(SWT.DOWN);
				} else {
					column.getColumn().getParent().setSortDirection(SWT.UP);
				}

				if (viewer.getComparator() == sorter) {
					viewer.refresh();
				} else {
					viewer.setComparator(sorter);
				}
			}
		}

		public int compare(Viewer viewer, Object e1, Object e2) {
			return direction * doCompare(viewer, e1, e2);
		}

		protected abstract int doCompare(Viewer viewer, Object e1, Object e2);
	}
}
 
Nachdem mir wohl keiner mit dem eigentlichen Thema meines Threads weiterhelfen kann / will.

Hätt ich noch eine andere Frage zum selben Thema.

Ich benutze ein und den selben TableViewer zur Darstellung unterschiedlicher Datensätze, wenn ich nun in der einen Tabelle die Daten sortiert habe (auf die Headerzeile geklickt habe), und die Ansicht auf andere Daten wechsel, bekomm ich eine Cast exception, wenn der sorter hingegen nicht ausgewählt wurde, funktioniert alles so wies soll.

Ich muss also wohl irgendwo den Sorter jedesmal beim initialisieren zurücksetzen, nur wie da es sich um eine Anonyme Klasse handelt komm ich aus meiner init Methode nicht an die besagte Variable (direction) um diese auf direction = 0; zu setzen.

Kann mir jemand sagen an welcher stelle ich die sorter zurücksetze damit ich mich der exception entledigen kann?

Oder ist durch mein Konzept (mehrere Daten in dem selben Viewer abzulegen) schlichtweg Müll ?

Danke
 
Zurück