RCP Eclipse: Speichern von Spaltenbreiten

musiKk

Top Contributor
Hallo,

durch Internationalisierung und unvorhersehbare Nutzereingaben passiert es häufig, dass zunächst eingestellte Standardspaltenbreiten in Tabellen (JFace TableViewer und TreeViewer werden verwendet) zu breit oder zu schmal sind. Auch auf verschiedenen Betriebssystemen sind die Differenzen groß.

Daher habe ich mir überlegt, die Spaltenbreiten abzuspeichern und beim Erzeugen der Tabelle wieder zu laden. Gibt es dafür schon eine Möglichkeit? Ich habe bisher nichts gefunden. Wo genau gespeichert wird - ob in IMemento oder IDialogSettings - ist mir persönlich erstmal egal. Hauptsache, es geht.

Wenn es da nichts gibt, werde ich mir da wohl oder übel selbst was überlegen müssen...

Gruß
mK
 
Wenn es ein Dialog ist nimmst du IDialogSettings, wenn es eine View oder Editor ist nimmst du IMemento, du liegst also goldrichtig.
 
Ich sehe schon, die Frage war zu undeutlich. Wie gesagt: Ob ich Memento oder DialogSettings nehme, ist mir ziemlich egal. Der Fokus liegt auf: Gibt es dafür schon eine Möglichkeit? Am besten wäre ja etwas, dem ich einfach nur eine Speichermöglichkeit, eine Art Table/Tree-ID und den Table/Tree selbst hinwerfe und der Rest geht von alleine.

Ich habe schon einmal testweise einen Prototypen erstellt, der von Tree-/TableViewer abgeleitet und beim Dispose die Spalten ausliest und in DialogSettings abspeichert. Das Wiederherstellen geschieht noch mehr oder weniger manuell, wobei daran evtl. noch etwas geschraubt werden könnte. Alles in Allem etwas unschön. Viel Code wird auch dupliziert, weil Table und Tree keine gemeinsame Hierarchie haben, über die ich an die Spalten komme (selbes für die entsprechenden Viewer). Füge ich da nun noch das Memento hinzu (wofür ich eigentlich keinen Bedarf sehe... außer dem Namen ändert sich ja nicht viel...) wird das noch mehr.

Was mich am meisten stört ist natürlich, dass beim geringsten Fehler der Table/Tree nicht angezeigt wird und dass für mich relativ schwer abzuschätzen ist (wie bei jedem Framework), ob das hundertprozentig plattformübergreifend ist.
 
Hmm, irgendwie verstehe ich dein Problem nicht so richtig. Du kannst in den Dialog Settings zb doch generisch key value Paare ablegen. Du musst doch also nur die Spaltennummer als Key verwenden und die Breite als Value dazu ablegen. Beim starten lässt du dir die Spaltenbreite dann wieder geben und wendest sie auf die Columns an.
Wenn dich duplizierter Code stört kannst du ja eine Klasse schreiben die das für dich tut, oder TreeViewer und TableViewer subclassen und der abgeleiteten Klasse wahlweise ein Memento oder IDialogSettings mitgeben.
 
Ok, passt schon. Aus dem bisher gesagten entnehme ich, dass es wohl noch keine vorgefertigte Lösung gibt. Ich habe auch die eine vorgeschlagene Variante genommen: zwei Klassen, die von Tree- und TableViewer ableiten.

Mit dupliziertem Code meinte ich eigentlich folgendes: Ich habe z. B. eine Methode, die die Spaltenbreiten wiederherstellt:

Java:
public void restorePreviousWidths() {
	Table table = getTable();
	TableColumn[] columns = table.getColumns();

	if (previousWidths.length != columns.length) {
		return;
	}

	for (int i = 0; i < columns.length; i++) {
		TableColumn col = columns[i];
		int width = previousWidths[i];

		col.setWidth(width);
	}
}

Das gleiche gibts nochmal exakt so für Tree, nur dass [c](get)Table[/c] durch [c](get)Tree[/c] und [c]TableColumn[/c] durch [c]TreeColumn[/c] ersetzt wird. Tree/Table kommen halt direkt von Composite und Tree-/TableColumn von Item. Vielleicht bin ich bzgl. Duplikation auch zu mäkelig - ich meide sie wie die Pest - darum hatte ich auch nach einer vorgefertigten Lösung gesucht.
 
Ich finde es auch leidlich das solche selbstverständlichen Features mit "so" viel Aufwand programmiert werden müssen.
Deswegen habe ich mir schon vor langen eine Lösung gesucht die ich möglichst einfach modifizieren kann.
Die wird dann überall wo eine Tabelle benötigt wird hin kopiert und angepasst:
Also ich "verhackstückel" das meistens gleich mit im Labelprovider:
Java:
 public static  class CommentLabelProvider implements ITableLabelProvider 
    {
    	
    	static final String MESSAGE = "Message";
    	static final String DATE = "Date";
    	static final List<String> columns = Arrays.asList(new String[]{ DATE, MESSAGE});
     	static final Integer[] columnWidth = new Integer[]{	30,	100};
    	
    	public static void makeColumns(TableViewer tableViewer, TableColumnLayout tableColumnLayout)
    	{
    		IDialogSettings settings = MyPlugin.getDefault().getDialogSettings();
    		for(int i=0;i<columns.size();i++)
    		{
    			int width = columnWidth[i];
    			try
    			{
    				width = settings.getInt(CommentsTab.class.getSimpleName()+ "_TABLE_COLUMN_WIDTH_" + columns.get(i));
    			}catch(NumberFormatException e)
    			{}
    		    TableColumn tableColumn = new TableColumn(tableViewer.getTable(), SWT.LEFT, i);
                tableColumn.setText(columns.get(i));
                tableColumnLayout.setColumnData(tableColumn, new ColumnWeightData(width, width, true));
                tableColumn.addControlListener(new ControlAdapter()
    			{
    				@Override
    				public void controlResized(ControlEvent e)
    				{
    					TableColumn parent = (TableColumn) e.getSource();
    					IDialogSettings settings = MyPlugin.getDefault().getDialogSettings();
    					settings.put(CommentsTab.class.getSimpleName()+ "_TABLE_COLUMN_WIDTH_" + parent.getText(), parent.getWidth());
    				}
    			});
    		}
    	}
		@Override
		public String getColumnText(Object element, int columnIndex)
		{
			if(element instanceof Comment)
			{
				if(columnIndex==columns.indexOf(MESSAGE))
					return ((Comment)element).getContent();
				else if(columnIndex==columns.indexOf(DATE))
					return ((Comment)element).getDate();
			}
			return "";
			
		}
...
}
So muss ich nur die Namen der Spalten und die getText-Methode ändern.
 
Mhh Gegenfrage: Wieso nicht ;-)
Der LabelProvider muss doch sowieso wissen wie viele Spalten es gibt. Also war es für mich logisch auch die Spalten dort anzulegen.
Gibt es einen besseren Weg? Dann immer her damit!
Wie machst du das denn?
 
Der LabelProvider muss doch sowieso wissen wie viele Spalten es gibt. Also war es für mich logisch auch die Spalten dort anzulegen.
Gibt es einen besseren Weg? Dann immer her damit!
Wie machst du das denn?

Wieso muss der LabelProvider die Anzahl der Spalten wissen?

Hab mir noch keine Gedanken darüber gemacht, aber ich denke ich würde sowas eventuell im TableViewerColumn oder so machen!!!
 

Zurück
Oben