package de.tudresden.slr.questionnaire;

import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;

public abstract class ObservableCombo<E> {

	protected Combo combo;
	protected List<String> labels = new LinkedList<>();
	protected List<E> elements = new LinkedList<>();

	private List<Consumer<E>> observers = new LinkedList<>();

	public ObservableCombo(Composite parent, GridData gridData) {
		combo = new Combo(parent, SWT.READ_ONLY);
		combo.setLayoutData(gridData);
		combo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				notifyObservers();
			}
		});
	}

	/** should update {@link #labels} and {@link #elements} */
	protected abstract void updateLabelsAndElements();

	public E getSelected() {
		if (elements.size() == 0)
			return null;
		int index = combo.getSelectionIndex();
		if (index < 0 || index >= elements.size())
			throw new IllegalStateException();
		return elements.get(index);
	}

	public void updateOptionsDisplay() {
		labels.clear();
		elements.clear();
		updateLabelsAndElements();
		combo.removeAll();
		if (labels.size() != elements.size())
			throw new IllegalStateException("unequal sizes of labels/elements");
		labels.forEach(combo::add);

		// TODO Instead of selecting first, try to select the previous element (if it
		// still exists)
		selectFirst();
	}

	public void selectFirst() {
		combo.select(0);
		notifyObservers();
	}

	private void notifyObservers() {
		E selection = getSelected();
		observers.forEach(o -> o.accept(selection));
	}

	public void addObserver(Consumer<E> observer) {
		observers.add(observer);
	}

}
@@ -151,16 +151,102 @@
 wt.SWT;%0A
+import org.eclipse.swt.events.MouseAdapter;%0Aimport org.eclipse.swt.events.MouseEvent;%0A
 import o
@@ -371,16 +371,97 @@
 idData;%0A
+import org.eclipse.swt.layout.GridLayout;%0Aimport org.eclipse.swt.widgets.Button;%0A
 import o
@@ -824,24 +824,142 @@
 gridData) %7B%0A
+%09    Composite container = new Composite(parent, SWT.NONE);%0A%09    container.setLayout(new GridLayout(2, false));%0A%09    %0A
 %09%09combo = ne
@@ -966,22 +966,25 @@
 w Combo(
-parent
+container
 , SWT.RE
@@ -1177,16 +1177,254 @@
 %7D%0A%09%09%7D);%0A
+%09%09Button refresh = new Button(container, SWT.PUSH);%0A%09%09refresh.setText(%22Refresh%22);%0A%09%09refresh.addMouseListener(new MouseAdapter() %7B%0A%09%09    @Override%0A%09%09    public void mouseDown(MouseEvent e) %7B%0A%09%09        updateOptionsDisplay();%0A%09%09    %7D%0A%09%09%7D);%0A
 %09%7D%0A%0A%09/**
@@ -1558,18 +1558,24 @@
 ted() %7B%0A
-%09%09
+        
 if (elem
@@ -1592,19 +1592,28 @@
 ) == 0)%0A
-%09%09%09
+            
 return n
@@ -1617,18 +1617,24 @@
 n null;%0A
-%09%09
+        
 int inde
@@ -1660,26 +1660,32 @@
 ionIndex();%0A
-%09%09
+        
 if (index %3C 
@@ -1707,35 +1707,44 @@
 lements.size())%0A
-%09%09%09
+            
 throw new Illega
@@ -1766,24 +1766,308 @@
 ();%0A
-%09%09return element
+        return elements.get(index);%0A    %7D%0A%09%0A%09public String getSelectedLabel() %7B%0A        if (labels.size() == 0)%0A            return null;%0A        int index = combo.getSelectionIndex();%0A        if (index %3C 0 %7C%7C index %3E= labels.size())%0A            throw new IllegalStateException();%0A        return label
 s.ge
@@ -2076,17 +2076,20 @@
 index);%0A
-%09
+    
 %7D%0A%0A%09publ
@@ -2121,16 +2121,70 @@
 lay() %7B%0A
+%09    String previousLabel = getSelectedLabel();%0A%09    %0A
 %09%09labels
@@ -2412,104 +2412,50 @@
 %0A%0A%09%09
-// TODO Instead of selecting first, try to select the previous element (if it%0A%09%09// still exists)
+int index = labels.indexOf(previousLabel);
 %0A%09%09s
@@ -2459,22 +2459,22 @@
 %09%09select
-First(
+(index
 );%0A%09%7D%0A%0A%09
@@ -2470,29 +2470,30 @@
 dex);%0A%09%7D%0A%0A%09p
-ublic
+rivate
  void select
@@ -2496,20 +2496,46 @@
 lect
-First() %7B%0A%09%09
+(int n) %7B%0A%09    if (n %3C 0) n = 0;%0A%09    
 comb
@@ -2547,14 +2547,17 @@
 ect(
-0
+n
 );%0A%09
-%09
+    
 noti

maintain selection on refresh, added refresh button