changeset 4956:f46a07c11324

Refactor Pegel- and Messtelleninfo in client ui Use SmartGWT ListGrid instead of GWT Tree to display the station entires.
author Björn Ricks <bjoern.ricks@intevation.de>
date Fri, 01 Feb 2013 16:32:48 +0100
parents 4c7acc3a4ae1
children 5652aa0ad9e5
files flys-client/src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java flys-client/src/main/java/de/intevation/flys/client/client/ui/GaugeTree.java flys-client/src/main/java/de/intevation/flys/client/client/ui/InfoPanel.java flys-client/src/main/java/de/intevation/flys/client/client/ui/InfoTree.java flys-client/src/main/java/de/intevation/flys/client/client/ui/MeasurementStationPanel.java flys-client/src/main/java/de/intevation/flys/client/client/ui/MeasurementStationTree.java flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterList.java flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/GaugeListGrid.java flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/GaugePanel.java flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/GaugeRecord.java flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/InfoListGrid.java flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/InfoPanel.java flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/MeasurementStationListGrid.java flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/MeasurementStationPanel.java flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/MeasurementStationRecord.java
diffstat 15 files changed, 1217 insertions(+), 995 deletions(-) [+]
line wrap: on
line diff
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java	Thu Jan 31 20:15:41 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-package de.intevation.flys.client.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import de.intevation.flys.client.client.FLYS;
-import de.intevation.flys.client.shared.model.RiverInfo;
-
-/**
- * The GaugePanel is intended to be used within a SectionStackSection
- *
- * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
- */
-public class GaugePanel extends InfoPanel {
-
-    /**
-     * GaugePanel loads the GaugeInfo from the RiverInfoService and
-     * displays them in a tree underneath a RiverInfoPanel
-     *
-     * @param flys The FLYS object
-     */
-    public GaugePanel(FLYS flys) {
-        super(new GaugeTree(flys));
-    }
-
-    @Override
-    public String getSectionTitle() {
-        return MSG.gaugePanelTitle();
-    }
-
-    /**
-     * Loads the river info and renders it afterwards
-     */
-    public void refresh() {
-        contract();
-
-        riverInfoService.getGauges(this.river, new AsyncCallback<RiverInfo>() {
-            @Override
-            public void onFailure(Throwable e) {
-                GWT.log("Could not load the river info." + e);
-            }
-
-            @Override
-            public void onSuccess(RiverInfo riverinfo) {
-                GWT.log("Loaded river info");
-                render(riverinfo);
-                expand();
-            }
-        });
-    }
-
-}
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/GaugeTree.java	Thu Jan 31 20:15:41 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,449 +0,0 @@
-package de.intevation.flys.client.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.i18n.client.NumberFormat;
-import com.google.gwt.user.client.ui.Anchor;
-import com.google.gwt.user.client.ui.DecoratorPanel;
-import com.google.gwt.user.client.ui.Grid;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.Tree;
-import com.google.gwt.user.client.ui.TreeItem;
-
-import com.smartgwt.client.widgets.layout.HLayout;
-
-import de.intevation.flys.client.client.FLYS;
-import de.intevation.flys.client.shared.model.Data;
-import de.intevation.flys.client.shared.model.DataItem;
-import de.intevation.flys.client.shared.model.DataList;
-import de.intevation.flys.client.shared.model.GaugeInfo;
-import de.intevation.flys.client.shared.model.RiverInfo;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
- */
-public class GaugeTree extends InfoTree {
-
-    public GaugeTree(FLYS flys) {
-        this.flys = flys;
-        tree = new Tree();
-        setWidget(tree);
-    }
-
-    /**
-     * Resets the items of the tree.
-     * If the list of gauges is empty or null the tree will be empty.
-     */
-    @Override
-    public void setRiverInfo(RiverInfo riverinfo) {
-        tree.clear();
-
-        List<GaugeInfo> gauges = riverinfo.getGauges();
-
-        if (gauges != null && !gauges.isEmpty()) {
-
-            ArrayList<GaugeInfo> emptygauges = new ArrayList<GaugeInfo>();
-
-            if (!riverinfo.isKmUp()) {
-                for (GaugeInfo gauge : gauges) {
-                    addGauge(gauge, emptygauges);
-                }
-            }
-            else {
-                for (int i = gauges.size()-1; i >= 0; i--) {
-                    GaugeInfo gauge = gauges.get(i);
-                    addGauge(gauge, emptygauges);
-                }
-            }
-
-            // put empty gauges to the end
-            for (GaugeInfo gauge : emptygauges) {
-                addGauge(gauge);
-            }
-
-            open();
-        }
-    }
-
-    private void addGauge(GaugeInfo gauge, List<GaugeInfo> empty) {
-        if (gauge.getKmStart() != null && gauge.getKmEnd() != null) {
-            addGauge(gauge);
-        }
-        else {
-            empty.add(gauge);
-        }
-    }
-
-    private void addGauge(GaugeInfo gauge) {
-        GaugeInfoItem gaugeitem = new GaugeInfoItem(flys, gauge);
-        tree.addItem(gaugeitem);
-    }
-
-    void getLocations(String labelname, List<Double> locations, DataList dl) {
-        for (int j = dl.size()-1; j >= 0; --j) {
-            Data d = dl.get(j);
-            String label = d.getLabel();
-            if (label.equals(labelname)) {
-                getLocationsFromData(locations, d);
-            }
-        }
-    }
-
-    void getLocationsFromData(List<Double> locations, Data data) {
-        DataItem[] items = data.getItems();
-        for (int k = 0; k < items.length; k++) {
-            String tmp = items[k].getStringValue();
-            GWT.log("GaugeTree - getLocationsFromData " + tmp);
-            if (tmp != null) {
-                if (tmp.contains(" ")) {
-                    // string contains several values ...
-                    String[] values = tmp.split(" ");
-                    for(int i=0; i < values.length; i++) {
-                        Double value = Double.valueOf(values[i]);
-                        if (value != null) {
-                            locations.add(value);
-                        }
-                    }
-                }
-                else {
-                    Double value = Double.valueOf(tmp);
-                    if (value != null) {
-                        locations.add(value);
-                    }
-                }
-            }
-        }
-    }
-
-    public void openOnReference(Long number) {
-        GWT.log("GaugeTree - openOnReference " + number);
-        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
-            TreeItem item = it.next();
-            if (item instanceof GaugeInfoItem) {
-                GaugeInfoItem gitem = (GaugeInfoItem)item;
-                if (gitem.getReference().equals(number)) {
-                    item.setState(true);
-                }
-                else {
-                    item.setState(false);
-                }
-            }
-        }
-    }
-
-    public void openOnDistance(Double start, Double end) {
-        GWT.log("GaugeTree - openOnDistance " + start + " " + end + " " +
-                tree.getItemCount());
-
-        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
-            TreeItem item = it.next();
-            /* Strange stuff is happening here:
-             * GWT Tree.treeItemIterator returns another TreeItem for each
-             * GaugeInfoItem */
-            if (item instanceof GaugeInfoItem) {
-                boolean setstate = false;
-                GaugeInfoItem gitem = (GaugeInfoItem)item;
-                if (end == null && gitem.getStart() != null) {
-                    if (gitem.getStart() >= start) {
-                        setstate = true;
-                    }
-                }
-                else {
-                    // as getStart()/getEnd() return Double objects, they can be null and
-                    // can cause NPEs when comparing with double... strange...
-                    if (gitem.getStart() != null && gitem.getEnd() != null) {
-                        GWT.log("GaugeTree - openOnDistance gitem " + gitem.getStart() + " " + gitem.getEnd());
-                        if ((start >= gitem.getStart() && start <= gitem.getEnd()) ||
-                              (end >= gitem.getStart() &&   end <= gitem.getEnd()) ||
-                            (start <= gitem.getStart() &&   end >= gitem.getEnd())) {
-                            setstate = true;
-                        }
-                    }
-                }
-                item.setState(setstate);
-            }
-        }
-    }
-
-    /**
-     * Open Gauge entry if a location fits to the gauge
-     */
-    public void openOnLocations(List<Double> locations) {
-        GWT.log("GaugeTree - openOnLocations " + locations + " " +
-                tree.getItemCount());
-
-        if (locations == null || locations.isEmpty()) {
-            return;
-        }
-
-        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
-            TreeItem item = it.next();
-            if (item instanceof GaugeInfoItem) {
-                GaugeInfoItem gitem = (GaugeInfoItem)item;
-                boolean isset = false;
-                for (Double location: locations) {
-                    if (locations == null) {
-                        continue;
-                    }
-
-                    Double start = gitem.getStart();
-                    Double end   = gitem.getEnd();
-                    if (start == null || end == null) {
-                        // should not occur but avoid NullPointerException
-                        continue;
-                    }
-
-                    if (location >= start && location <= end) {
-                        isset = true;
-                        break;
-                    }
-                }
-                item.setState(isset);
-            }
-        }
-    }
-
-    class GaugeInfoItem extends TreeItem {
-
-        private GaugeInfo gauge;
-
-        public GaugeInfoItem(FLYS flys, GaugeInfo gauge) {
-            GaugeInfoHead gaugeinfohead = new GaugeInfoHead(flys, gauge);
-            GaugeInfoPanel gaugeinfopanel = new GaugeInfoPanel(gauge);
-            setWidget(gaugeinfohead);
-            addItem(gaugeinfopanel);
-            this.gauge = gauge;
-        }
-
-        public Double getStart() {
-            return gauge.getKmStart();
-        }
-
-        public Double getEnd() {
-            return gauge.getKmEnd();
-        }
-
-        public Long getReference() {
-            return gauge.getOfficialNumber();
-        }
-    }
-
-    class GaugeInfoHead extends HLayout {
-
-        public GaugeInfoHead(FLYS flys, GaugeInfo gauge) {
-            setStyleName("gaugeinfohead");
-            setAutoHeight();
-            setAutoWidth();
-
-            NumberFormat nf = NumberFormat.getDecimalFormat();
-
-            Label label = new Label(gauge.getName(), true);
-            addMember(label);
-
-            Double start;
-            Double end;
-
-            if (!gauge.isKmUp()) {
-                start = gauge.getKmStart();
-                end   = gauge.getKmEnd();
-            }
-            else {
-                start = gauge.getKmEnd();
-                end   = gauge.getKmStart();
-            }
-
-            String kmtext = "";
-            if (start != null) {
-                kmtext += nf.format(start);
-                kmtext += " - ";
-            }
-            if (end != null) {
-                kmtext += nf.format(end);
-            }
-            if (start != null || end != null) {
-                kmtext += " km";
-            }
-
-            label = new Label(kmtext);
-
-            addMember(label);
-
-            Double station = gauge.getStation();
-            if (station != null) {
-                String stext = nf.format(station);
-                stext += " km";
-                label = new Label(stext);
-                addMember(label);
-            }
-
-            Long number = gauge.getOfficialNumber();
-            String url = number != null ?
-                MSG.gauge_url() + number :
-                MSG.gauge_url();
-            Anchor anchor = new Anchor(MSG.gauge_info_link(), url, "_blank");
-            addMember(anchor);
-
-            addMember(new GaugeCurveAnchor(flys, gauge));
-        }
-    }
-
-    class GaugeCurveAnchor extends Anchor implements ClickHandler {
-
-        private FLYS flys;
-        private GaugeInfo gauge;
-
-        public GaugeCurveAnchor(FLYS flys, GaugeInfo gauge) {
-            super(MSG.gauge_curve_link());
-            this.flys = flys;
-            this.gauge = gauge;
-
-            addClickHandler(this);
-        }
-
-        @Override
-        public void onClick(ClickEvent ev) {
-            GWT.log("GaugeCurveAnchor - onClick " + gauge.getRiverName() +
-                    " " + gauge.getOfficialNumber());
-            flys.newGaugeDischargeCurve(gauge.getRiverName(),
-                    gauge.getOfficialNumber());
-        }
-    }
-
-    class GaugeInfoPanel extends DecoratorPanel {
-
-        public GaugeInfoPanel(GaugeInfo gauge) {
-            setStyleName("gaugeinfopanel");
-            Grid grid = new Grid(4, 2);
-
-            NumberFormat nf = NumberFormat.getDecimalFormat();
-
-            Double minw = gauge.getMinW();
-            Double maxw = gauge.getMaxW();
-            if (minw != null && maxw != null) {
-                grid.setText(0, 0, MSG.wq_value_q());
-                grid.setText(0, 1, "" + nf.format(minw) +
-                        " - " + nf.format(maxw));
-            }
-
-            Double minq = gauge.getMinQ();
-            Double maxq = gauge.getMaxQ();
-            if (minq != null && maxq != null) {
-                grid.setText(1, 0, MSG.wq_value_w());
-                grid.setText(1, 1, "" + nf.format(minq) +
-                        " - " + nf.format(maxq));
-            }
-
-            Double aeo = gauge.getAeo();
-            if (aeo != null) {
-                grid.setText(2, 0, "AEO [km²]");
-                grid.setText(2, 1, "" + nf.format(aeo));
-            }
-
-            Double datum = gauge.getDatum();
-            if (datum != null) {
-                grid.setText(3, 0, MSG.gauge_zero() + " [" +
-                        gauge.getWstUnit() + "]");
-                grid.setText(3, 1, "" + nf.format(datum));
-            }
-
-            setWidget(grid);
-        }
-    }
-
-    public void open() {
-        ArrayList<Double> locations = new ArrayList<Double>();
-
-        if (data != null && data.length > 0) {
-            for (int i = 0; i < data.length; i++) {
-                DataList dl = data[i];
-                String state = dl.getState();
-                GWT.log("GaugeTree - open " + state);
-                if (state.equals("state.winfo.location_distance")) {
-                    Double ldfrom = null;
-                    Double ldto = null;
-
-                    for (int j = dl.size()-1; j >= 0; --j) {
-                        Data d = dl.get(j);
-                        String label = d.getLabel();
-                        GWT.log("GaugeTree - setData - label " + label + " " + d.getStringValue());
-                        if (label.equals("ld_from")) {
-                            ldfrom = getDoubleValue(d);
-                        }
-                        else if (label.equals("ld_to")) {
-                            ldto = getDoubleValue(d);
-                        }
-                        else if (label.equals("ld_locations")) {
-                            getLocationsFromData(locations, d);
-                            openOnLocations(locations);
-                            return;
-                        }
-                    }
-                    if (ldfrom != null) {
-                        openOnDistance(ldfrom, ldto);
-                        return;
-                    }
-                }
-                else if(state.equals("state.winfo.distance_only") ||
-                        state.equals("state.winfo.distance")) {
-                    Double ldfrom = null;
-                    Double ldto = null;
-
-                    for (int j = dl.size()-1; j >= 0; --j) {
-                        Data d = dl.get(j);
-                        String label = d.getLabel();
-                        GWT.log("GaugeTree - setData - label " + label + " " + d.getStringValue());
-                        if (label.equals("ld_from")) {
-                            ldfrom = getDoubleValue(d);
-                        }
-                        else if (label.equals("ld_to")) {
-                            ldto = getDoubleValue(d);
-                        }
-                    }
-
-                    if (ldfrom != null) {
-                        openOnDistance(ldfrom, ldto);
-                        return;
-                    }
-                        }
-                else if (state.equals("state.winfo.location")) {
-                    getLocations("ld_locations", locations, dl);
-                    openOnLocations(locations);
-                    return;
-                }
-                else if (state.equals("state.winfo.reference.curve.input.start")) {
-                    getLocations("reference_startpoint", locations, dl);
-                }
-                else if (state.equals("state.winfo.reference.curve.input.end")) {
-                    getLocations("reference_endpoint", locations, dl);
-                }
-                else if (state.equals("state.winfo.historicalq.reference_gauge")) {
-                    for (int j = dl.size()-1; j >= 0; --j) {
-                        Data d = dl.get(j);
-                        String label = d.getLabel();
-                        if (label.equals("reference_gauge")) {
-                            String tmp = d.getStringValue();
-                            if (tmp != null) {
-                                Long gaugereference = Long.valueOf(tmp);
-                                if (gaugereference != null) {
-                                    openOnReference(gaugereference);
-                                    return;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        if (!locations.isEmpty()) {
-            openOnLocations(locations);
-        }
-        else {
-            openAll();
-        }
-    }
-}
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/InfoPanel.java	Thu Jan 31 20:15:41 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,170 +0,0 @@
-package de.intevation.flys.client.client.ui;
-
-import com.google.gwt.core.client.GWT;
-
-import com.smartgwt.client.types.Overflow;
-import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.events.ResizedEvent;
-import com.smartgwt.client.widgets.events.ResizedHandler;
-import com.smartgwt.client.widgets.layout.SectionStackSection;
-import com.smartgwt.client.widgets.layout.VLayout;
-import com.smartgwt.client.widgets.WidgetCanvas;
-
-import de.intevation.flys.client.client.FLYSConstants;
-import de.intevation.flys.client.client.services.RiverInfoService;
-import de.intevation.flys.client.client.services.RiverInfoServiceAsync;
-import de.intevation.flys.client.shared.model.DataList;
-import de.intevation.flys.client.shared.model.RiverInfo;
-
-/**
- * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
- */
-public abstract class InfoPanel extends VLayout implements ResizedHandler {
-
-    /** SectionStackSection where this InfoPanel belongs in*/
-    protected SectionStackSection section;
-
-    /** Name of the river */
-    protected String river;
-
-    /** The message class that provides i18n strings.*/
-    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
-
-    protected RiverInfoServiceAsync riverInfoService = GWT.create(RiverInfoService.class);
-
-    /** Panel to show the info about the river */
-    protected RiverInfoPanel riverinfopanel;
-    protected InfoTree tree;
-
-    /** Wrapper arround the GWT Tree (InfoTree) object */
-    protected Canvas treecanvas;
-
-    protected final static String SECTION_ID = "InfoPanelSection";
-
-    public InfoPanel(InfoTree tree) {
-        SectionStackSection section = new SectionStackSection();
-        section.setExpanded(false);
-        section.setTitle(getSectionTitle());
-        section.setName(SECTION_ID);
-        section.setID(SECTION_ID);
-
-        treecanvas = new WidgetCanvas(tree);
-
-        setOverflow(Overflow.HIDDEN);
-        setStyleName("infopanel");
-
-        section.setHidden(true);
-        section.setItems(this);
-        this.section = section;
-        this.tree = tree;
-
-        addResizedHandler(this);
-    }
-
-    /**
-     * Sets and loads the river data if river is not the current set river
-     */
-    public void setRiver(String river) {
-        if (!river.equals(this.river)) {
-            this.river = river;
-            this.refresh();
-        }
-    }
-
-    /**
-     * Sets the data and closes not corresponding folds in the gauge tree
-     */
-    public void setData(DataList[] data) {
-        tree.setData(data);
-    }
-
-    protected void render(RiverInfo riverinfo) {
-        tree.setRiverInfo(riverinfo);
-
-        if (riverinfopanel == null) {
-            removeAllMembers();
-
-            riverinfopanel = new RiverInfoPanel(riverinfo);
-
-            addMember(riverinfopanel);
-            addMember(treecanvas);
-        }
-        else {
-            riverinfopanel.setRiverInfo(riverinfo);
-        }
-    }
-
-    @Override
-        public void onResized(ResizedEvent event) {
-            /* this height calculation is only an approximation and doesn't reflect
-             * the real height of the the gaugetree. */
-            int height = getInnerContentHeight() -
-                RiverInfoPanel.getStaticHeight();
-            int width = getInnerContentWidth();
-
-            if (height < 0) {
-                height = 0;
-            }
-
-            GWT.log("InfoPanel - onResize " + height);
-
-            tree.setHeight("" + height + "px");
-            tree.setWidth("" + width + "px");
-        }
-
-    /**
-     * Hide the section stack section.
-     */
-    @Override
-        public void hide() {
-            GWT.log("InfoPanel - hide");
-            this.section.setHidden(true);
-        }
-
-    /**
-     * Show the section stack section.
-     */
-    @Override
-        public void show() {
-            GWT.log("InfoPanel - show");
-            this.section.setHidden(false);
-        }
-
-    @Override
-        public void addMember(Canvas component) {
-            super.addMember(component);
-            expand();
-        }
-
-    @Override
-        public void removeMembers(Canvas[] components) {
-            super.removeMembers(components);
-            contract();
-        }
-
-    public SectionStackSection getSection() {
-        return this.section;
-    }
-
-    protected void removeAllMembers() {
-        removeMembers(getMembers());
-    }
-
-    /**
-     * Expands the gauge section
-     */
-    public void expand() {
-        section.setExpanded(true);
-    }
-
-    /**
-     * Contracts/shrinks the expanded gauge section
-     */
-    public void contract() {
-        section.setExpanded(false);
-    }
-
-    protected abstract void refresh();
-
-    protected abstract String getSectionTitle();
-}
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/InfoTree.java	Thu Jan 31 20:15:41 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-package de.intevation.flys.client.client.ui;
-
-import java.util.Iterator;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.ui.ScrollPanel;
-import com.google.gwt.user.client.ui.Tree;
-import com.google.gwt.user.client.ui.TreeItem;
-
-import de.intevation.flys.client.client.FLYS;
-import de.intevation.flys.client.client.FLYSConstants;
-import de.intevation.flys.client.shared.model.Data;
-import de.intevation.flys.client.shared.model.DataList;
-import de.intevation.flys.client.shared.model.RiverInfo;
-
-/**
- * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
- */
-public abstract class InfoTree extends ScrollPanel  {
-
-    protected FLYS flys;
-    protected Tree tree;
-    protected DataList[] data;
-
-    /** The message class that provides i18n strings.*/
-    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
-
-    public void openAll() {
-        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
-            TreeItem item = it.next();
-            item.setState(true);
-        }
-    }
-
-    public void setData(DataList[] data) {
-        this.data = data;
-        if (tree.getItemCount() > 0) {
-            open();
-        }
-    }
-
-    protected Double getDoubleValue(Data d) {
-        String tmp = d.getStringValue();
-        if (tmp != null) {
-            return Double.valueOf(tmp);
-        }
-        return null;
-    }
-
-    public abstract void open() ;
-
-    public abstract void setRiverInfo(RiverInfo riverinfo);
-
-
-}
\ No newline at end of file
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/MeasurementStationPanel.java	Thu Jan 31 20:15:41 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-package de.intevation.flys.client.client.ui;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import de.intevation.flys.client.client.FLYS;
-import de.intevation.flys.client.shared.model.RiverInfo;
-
-/**
- * A Panel to show info about the MeasurementStations of a river
- *
- * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
- */
-public class MeasurementStationPanel extends InfoPanel {
-
-    /**
-     * MeasurementStationPanel loads the MeasurementStations from the
-     * RiverInfoService and displays them in a tree underneath a RiverInfoPanel
-     *
-     * @param flys The FLYS object
-     */
-    public MeasurementStationPanel(FLYS flys) {
-        super(new MeasurementStationTree(flys));
-    }
-
-    /**
-     * Returns the title which should be displayed in the section
-     */
-    @Override
-    public String getSectionTitle() {
-        return MSG.measurementStationPanelTitle();
-    }
-
-    /**
-     * Loads the river info and renders it afterwards
-     */
-    @Override
-    public void refresh() {
-        contract();
-
-        riverInfoService.getMeasurementStations(this.river,
-            new AsyncCallback<RiverInfo>() {
-                @Override
-                public void onFailure(Throwable e) {
-                    GWT.log("Could not load the river info." + e);
-                }
-
-                @Override
-                public void onSuccess(RiverInfo riverinfo) {
-                    GWT.log("Loaded river info");
-                    render(riverinfo);
-                    expand();
-                }
-        });
-    }
-}
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/MeasurementStationTree.java	Thu Jan 31 20:15:41 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +0,0 @@
-package de.intevation.flys.client.client.ui;
-
-import com.google.gwt.i18n.client.DateTimeFormat;
-import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
-import com.google.gwt.i18n.client.NumberFormat;
-import com.google.gwt.user.client.ui.Anchor;
-import com.google.gwt.user.client.ui.DecoratorPanel;
-import com.google.gwt.user.client.ui.Grid;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.Tree;
-import com.google.gwt.user.client.ui.TreeItem;
-
-import com.smartgwt.client.widgets.layout.HLayout;
-
-import de.intevation.flys.client.client.FLYS;
-import de.intevation.flys.client.shared.model.MeasurementStation;
-import de.intevation.flys.client.shared.model.RiverInfo;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-/**
- * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
- */
-public class MeasurementStationTree extends InfoTree {
-
-    public MeasurementStationTree(FLYS flys) {
-        this.flys = flys;
-        tree = new Tree();
-        setWidget(tree);
-    }
-
-    /**
-     * Resets the items of the tree.
-     * If the list of gauges is empty or null the tree will be empty.
-     */
-    @Override
-    public void setRiverInfo(RiverInfo riverinfo) {
-        tree.clear();
-
-        List<MeasurementStation> stations = riverinfo.getMeasurementStations();
-
-        if (stations != null && !stations.isEmpty()) {
-
-            ArrayList<MeasurementStation> emptystations =
-                new ArrayList<MeasurementStation>();
-
-            if (!riverinfo.isKmUp()) {
-                for (MeasurementStation station : stations) {
-                    addStation(station, emptystations);
-                }
-            }
-            else {
-                for (int i = stations.size()-1; i >= 0; i--) {
-                    MeasurementStation station = stations.get(i);
-                    addStation(station, emptystations);
-                }
-            }
-
-            // put empty stations to the end
-            for (MeasurementStation station : emptystations) {
-                addStation(station);
-            }
-        }
-    }
-
-    private void addStation(MeasurementStation station,
-            List<MeasurementStation> empty) {
-        if (station.getKmStart() != null && station.getKmEnd() != null) {
-            addStation(station);
-        }
-        else {
-            empty.add(station);
-        }
-    }
-
-    private void addStation(MeasurementStation station) {
-        MeasurementStationItem sitem =
-            new MeasurementStationItem(flys, station);
-        tree.addItem(sitem);
-    }
-
-    class MeasurementStationItem extends TreeItem {
-
-        private MeasurementStation station;
-
-        public MeasurementStationItem(FLYS flys, MeasurementStation station) {
-            MeasurementStationHead head =
-                new MeasurementStationHead(flys, station);
-            MeasurementStationDecoratorPanel
-                panel = new MeasurementStationDecoratorPanel(station);
-            setWidget(head);
-            addItem(panel);
-            this.station = station;
-        }
-
-        public Double getStart() {
-            return station.getKmStart();
-        }
-
-        public Double getEnd() {
-            return station.getKmEnd();
-        }
-
-        public Integer getID() {
-            return station.getID();
-        }
-    }
-
-    class MeasurementStationHead extends HLayout {
-
-        public MeasurementStationHead(FLYS flys, MeasurementStation station) {
-            setStyleName("infohead");
-            setAutoHeight();
-            setAutoWidth();
-
-            NumberFormat nf = NumberFormat.getDecimalFormat();
-
-            Label label = new Label(station.getName(), true);
-            addMember(label);
-
-            Double start;
-            Double end;
-
-            if (!station.isKmUp()) {
-                start = station.getKmStart();
-                end   = station.getKmEnd();
-            }
-            else {
-                start = station.getKmEnd();
-                end   = station.getKmStart();
-            }
-
-            String kmtext = "";
-            if (start != null) {
-                kmtext += nf.format(start);
-                kmtext += " - ";
-            }
-            if (end != null) {
-                kmtext += nf.format(end);
-            }
-            if (start != null || end != null) {
-                kmtext += " km";
-            }
-
-            label = new Label(kmtext);
-
-            addMember(label);
-
-            Double dstation = station.getStation();
-            if (dstation != null) {
-                String stext = nf.format(dstation);
-                stext += " km";
-                label = new Label(stext);
-                addMember(label);
-            }
-
-            Integer number = station.getID();
-            String url = number != null ?
-                MSG.measurement_station_url() + number :
-                MSG.measurement_station_url();
-            Anchor anchor = new Anchor(MSG.measurement_station_info_link(),
-                    url, "_blank");
-            addMember(anchor);
-        }
-    }
-
-    class MeasurementStationDecoratorPanel extends DecoratorPanel {
-
-        public MeasurementStationDecoratorPanel(MeasurementStation station) {
-            setStyleName("infopanel");
-            Grid grid = new Grid(5, 2);
-
-            String type = station.getMeasurementType();
-            if (type != null) {
-                grid.setText(0, 0, MSG.measurement_station_type());
-                grid.setText(0, 1, type);
-            }
-
-            String riverside = station.getRiverSide();
-            if (riverside != null) {
-                grid.setText(1, 0, MSG.riverside());
-                grid.setText(1, 1, riverside);
-            }
-
-            String gaugename = station.getGaugeName();
-            if (gaugename != null) {
-               grid.setText(2, 0, MSG.measurement_station_gauge_name());
-               grid.setText(2, 1, gaugename);
-            }
-
-            DateTimeFormat df = DateTimeFormat.getFormat(
-                    PredefinedFormat.DATE_MEDIUM);
-
-            Date starttime = station.getStartTime();
-            if (starttime != null) {
-               grid.setText(3, 0, MSG.measurement_station_start_time());
-               grid.setText(3, 1, df.format(starttime));
-            }
-
-            String moperator = station.getOperator();
-            if (moperator != null) {
-                grid.setText(4, 0, MSG.measurement_station_operator());
-                grid.setText(4, 1, moperator);
-            }
-
-            setWidget(grid);
-        }
-    }
-
-    @Override
-    public void open() {
-    }
-}
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterList.java	Thu Jan 31 20:15:41 2013 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterList.java	Fri Feb 01 16:32:48 2013 +0100
@@ -39,6 +39,9 @@
 import de.intevation.flys.client.client.services.ReportServiceAsync;
 import de.intevation.flys.client.client.services.StepForwardService;
 import de.intevation.flys.client.client.services.StepForwardServiceAsync;
+import de.intevation.flys.client.client.ui.stationinfo.GaugePanel;
+import de.intevation.flys.client.client.ui.stationinfo.InfoPanel;
+import de.intevation.flys.client.client.ui.stationinfo.MeasurementStationPanel;
 import de.intevation.flys.client.shared.model.Artifact;
 import de.intevation.flys.client.shared.model.ArtifactDescription;
 import de.intevation.flys.client.shared.model.Collection;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/GaugeListGrid.java	Fri Feb 01 16:32:48 2013 +0100
@@ -0,0 +1,425 @@
+package de.intevation.flys.client.client.ui.stationinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.user.client.ui.Anchor;
+import com.google.gwt.user.client.ui.DecoratorPanel;
+import com.google.gwt.user.client.ui.Grid;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.WidgetCanvas;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.layout.HLayout;
+
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataItem;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.GaugeInfo;
+import de.intevation.flys.client.shared.model.RiverInfo;
+
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class GaugeListGrid extends InfoListGrid {
+
+    public GaugeListGrid(FLYS flys) {
+        super(flys);
+        ListGridField nfield = new ListGridField("name", "Pegel");
+        ListGridField sfield = new ListGridField("kmstart", "Start [km]", 60);
+        ListGridField efield = new ListGridField("kmend", "Ende [km]", 60);
+        ListGridField stfield = new ListGridField("station", "Station [km]");
+        ListGridField lfield = new ListGridField("link", "Link");
+        lfield.setType(ListGridFieldType.LINK);
+
+        this.setFields(nfield, sfield, efield, stfield, lfield);
+    }
+
+    public void setRiverInfo(RiverInfo riverinfo) {
+        List<GaugeInfo> gauges = riverinfo.getGauges();
+
+        if (gauges != null && !gauges.isEmpty()) {
+
+            ArrayList<GaugeInfo> emptygauges = new ArrayList<GaugeInfo>();
+
+            if (!riverinfo.isKmUp()) {
+                for (GaugeInfo gauge : gauges) {
+                    addGauge(gauge, emptygauges);
+                }
+            }
+            else {
+                for (int i = gauges.size()-1; i >= 0; i--) {
+                    GaugeInfo gauge = gauges.get(i);
+                    addGauge(gauge, emptygauges);
+                }
+            }
+
+            // put empty gauges to the end
+            for (GaugeInfo gauge : emptygauges) {
+                addGauge(gauge);
+            }
+        }
+    }
+
+    private void addGauge(GaugeInfo gauge, List<GaugeInfo> empty) {
+        if (gauge.getKmStart() != null && gauge.getKmEnd() != null) {
+            addGauge(gauge);
+        }
+        else {
+            empty.add(gauge);
+        }
+    }
+
+    private void addGauge(GaugeInfo gauge) {
+        this.addData(new GaugeRecord(gauge));
+    }
+
+
+    class GaugeInfoHead extends HLayout {
+
+        public GaugeInfoHead(FLYS flys, GaugeInfo gauge) {
+            setStyleName("gaugeinfohead");
+            setAutoHeight();
+            setAutoWidth();
+
+            NumberFormat nf = NumberFormat.getDecimalFormat();
+
+            Label label = new Label(gauge.getName());
+            addMember(label);
+
+            Double start;
+            Double end;
+
+            if (!gauge.isKmUp()) {
+                start = gauge.getKmStart();
+                end   = gauge.getKmEnd();
+            }
+            else {
+                start = gauge.getKmEnd();
+                end   = gauge.getKmStart();
+            }
+
+            String kmtext = "";
+            if (start != null) {
+                kmtext += nf.format(start);
+                kmtext += " - ";
+            }
+            if (end != null) {
+                kmtext += nf.format(end);
+            }
+            if (start != null || end != null) {
+                kmtext += " km";
+            }
+
+            label = new Label(kmtext);
+
+            addMember(label);
+
+            Double station = gauge.getStation();
+            if (station != null) {
+                String stext = nf.format(station);
+                stext += " km";
+                label = new Label(stext);
+                addMember(label);
+            }
+
+            Long number = gauge.getOfficialNumber();
+            String url = number != null ?
+                MSG.gauge_url() + number :
+                MSG.gauge_url();
+            Anchor anchor = new Anchor(MSG.gauge_info_link(), url, "_blank");
+            addMember(anchor);
+
+            addMember(new GaugeCurveAnchor(flys, gauge));
+        }
+    }
+
+    class GaugeCurveAnchor extends Anchor implements ClickHandler {
+
+        private FLYS flys;
+        private GaugeInfo gauge;
+
+        public GaugeCurveAnchor(FLYS flys, GaugeInfo gauge) {
+            super(MSG.gauge_curve_link());
+            this.flys = flys;
+            this.gauge = gauge;
+
+            addClickHandler(this);
+        }
+
+        @Override
+        public void onClick(ClickEvent ev) {
+            GWT.log("GaugeCurveAnchor - onClick " + gauge.getRiverName() +
+                    " " + gauge.getOfficialNumber());
+            flys.newGaugeDischargeCurve(gauge.getRiverName(),
+                    gauge.getOfficialNumber());
+        }
+    }
+
+    class GaugeInfoPanel extends DecoratorPanel {
+
+        public GaugeInfoPanel(GaugeInfo gauge) {
+            setStyleName("gaugeinfopanel");
+            Grid grid = new Grid(4, 2);
+
+            NumberFormat nf = NumberFormat.getDecimalFormat();
+
+            Double minw = gauge.getMinW();
+            Double maxw = gauge.getMaxW();
+            if (minw != null && maxw != null) {
+                grid.setText(0, 0, MSG.wq_value_q());
+                grid.setText(0, 1, nf.format(minw) +
+                        " - " + nf.format(maxw));
+            }
+
+            Double minq = gauge.getMinQ();
+            Double maxq = gauge.getMaxQ();
+            if (minq != null && maxq != null) {
+                grid.setText(1, 0, MSG.wq_value_w());
+                grid.setText(1, 1, nf.format(minq) +
+                        " - " + nf.format(maxq));
+            }
+
+            Double aeo = gauge.getAeo();
+            if (aeo != null) {
+                grid.setText(2, 0, "AEO [km²]");
+                grid.setText(2, 1, nf.format(aeo));
+            }
+
+            Double datum = gauge.getDatum();
+            if (datum != null) {
+                grid.setText(3, 0, MSG.gauge_zero() + " [" +
+                        gauge.getWstUnit() + "]");
+                grid.setText(3, 1, nf.format(datum));
+            }
+
+            setWidget(grid);
+        }
+    }
+
+    public void open() {
+        ArrayList<Double> locations = new ArrayList<Double>();
+
+        if (data != null && data.length > 0) {
+            for (int i = 0; i < data.length; i++) {
+                DataList dl = data[i];
+                String state = dl.getState();
+                GWT.log("GaugeListGrid - open " + state);
+                if (state.equals("state.winfo.location_distance")) {
+                    Double ldfrom = null;
+                    Double ldto = null;
+
+                    for (int j = dl.size()-1; j >= 0; --j) {
+                        Data d = dl.get(j);
+                        String label = d.getLabel();
+                        GWT.log("GaugeListGrid - setData - label " + label + " " + d.getStringValue());
+                        if (label.equals("ld_from")) {
+                            ldfrom = getDoubleValue(d);
+                        }
+                        else if (label.equals("ld_to")) {
+                            ldto = getDoubleValue(d);
+                        }
+                        else if (label.equals("ld_locations")) {
+                            getLocationsFromData(locations, d);
+                            openOnLocations(locations);
+                            return;
+                        }
+                    }
+                    if (ldfrom != null) {
+                        openOnDistance(ldfrom, ldto);
+                        return;
+                    }
+                }
+                else if(state.equals("state.winfo.distance_only") ||
+                        state.equals("state.winfo.distance")) {
+                    Double ldfrom = null;
+                    Double ldto = null;
+
+                    for (int j = dl.size()-1; j >= 0; --j) {
+                        Data d = dl.get(j);
+                        String label = d.getLabel();
+                        GWT.log("GaugeListGrid - setData - label " + label + " " + d.getStringValue());
+                        if (label.equals("ld_from")) {
+                            ldfrom = getDoubleValue(d);
+                        }
+                        else if (label.equals("ld_to")) {
+                            ldto = getDoubleValue(d);
+                        }
+                    }
+
+                    if (ldfrom != null) {
+                        openOnDistance(ldfrom, ldto);
+                        return;
+                    }
+                }
+                else if (state.equals("state.winfo.location")) {
+                    getLocations("ld_locations", locations, dl);
+                    openOnLocations(locations);
+                    return;
+                }
+                else if (state.equals("state.winfo.reference.curve.input.start")) {
+                    getLocations("reference_startpoint", locations, dl);
+                }
+                else if (state.equals("state.winfo.reference.curve.input.end")) {
+                    getLocations("reference_endpoint", locations, dl);
+                }
+                else if (state.equals("state.winfo.historicalq.reference_gauge")) {
+                    for (int j = dl.size()-1; j >= 0; --j) {
+                        Data d = dl.get(j);
+                        String label = d.getLabel();
+                        if (label.equals("reference_gauge")) {
+                            String tmp = d.getStringValue();
+                            if (tmp != null) {
+                                Long gaugereference = Long.valueOf(tmp);
+                                if (gaugereference != null) {
+                                    openOnReference(gaugereference);
+                                    return;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (!locations.isEmpty()) {
+            openOnLocations(locations);
+        }
+        else {
+            openAll();
+        }
+    }
+
+    void getLocations(String labelname, List<Double> locations, DataList dl) {
+        for (int j = dl.size()-1; j >= 0; --j) {
+            Data d = dl.get(j);
+            String label = d.getLabel();
+            if (label.equals(labelname)) {
+                getLocationsFromData(locations, d);
+            }
+        }
+    }
+
+    void getLocationsFromData(List<Double> locations, Data data) {
+        DataItem[] items = data.getItems();
+        for (int k = 0; k < items.length; k++) {
+            String tmp = items[k].getStringValue();
+            GWT.log("GaugeListGrid - getLocationsFromData " + tmp);
+            if (tmp != null) {
+                if (tmp.contains(" ")) {
+                    // string contains several values ...
+                    String[] values = tmp.split(" ");
+                    for(int i=0; i < values.length; i++) {
+                        Double value = Double.valueOf(values[i]);
+                        if (value != null) {
+                            locations.add(value);
+                        }
+                    }
+                }
+                else {
+                    Double value = Double.valueOf(tmp);
+                    if (value != null) {
+                        locations.add(value);
+                    }
+                }
+            }
+        }
+    }
+
+    public void openOnReference(Long number) {
+        GWT.log("GaugeListGrid - openOnReference " + number);
+        for (ListGridRecord record: this.getRecords()) {
+            GaugeRecord item = (GaugeRecord)record;
+            if (item.getOfficialNumber().equals(number)) {
+                expandRecord(item);
+            }
+            else {
+                collapseRecord(item);
+            }
+        }
+    }
+
+    public void openOnDistance(Double start, Double end) {
+        GWT.log("GaugeListGrid - openOnDistance " + start + " " + end);
+
+        for (ListGridRecord record: this.getRecords()) {
+            GaugeRecord item = (GaugeRecord)record;
+            if (end == null && item.getKmStart() != null) {
+                if (item.getKmStart() >= start) {
+                    expandRecord(item);
+                }
+                else {
+                    collapseRecord(item);
+                }
+            }
+            else if (item.getKmStart() != null && item.getKmEnd() != null) {
+                // as getStart()/getEnd() return Double objects, they can be null and
+                // can cause NPEs when comparing with double... strange...
+                GWT.log("GaugeListGrid - openOnDistance item " + item.getKmStart() + " " + item.getKmEnd());
+                if ((start >= item.getKmStart() && start <= item.getKmEnd()) ||
+                      (end >= item.getKmStart() &&   end <= item.getKmEnd()) ||
+                    (start <= item.getKmStart() &&   end >= item.getKmEnd())) {
+                    expandRecord(item);
+                }
+                else {
+                    collapseRecord(item);
+                }
+            }
+            else {
+                collapseRecord(item);
+            }
+        }
+    }
+
+    /**
+     * Open Gauge entry if a location fits to the gauge
+     */
+    public void openOnLocations(List<Double> locations) {
+        GWT.log("GaugeListGrid - openOnLocations " + locations);
+
+        if (locations == null || locations.isEmpty()) {
+            return;
+        }
+
+        for (ListGridRecord record: this.getRecords()) {
+            GaugeRecord item = (GaugeRecord)record;
+            boolean isset = false;
+            for (Double location: locations) {
+                if (locations == null) {
+                    continue;
+                }
+
+                Double start = item.getKmStart();
+                Double end   = item.getKmEnd();
+                if (start == null || end == null) {
+                    // should not occur but avoid NullPointerException
+                    continue;
+                }
+
+                if (location >= start && location <= end) {
+                    isset = true;
+                    break;
+                }
+            }
+            if (isset) {
+                expandRecord(item);
+            }
+            else {
+                collapseRecord(item);
+            }
+        }
+    }
+
+    @Override
+    protected Canvas getExpandPanel(ListGridRecord record) {
+        GaugeRecord item = (GaugeRecord)record;
+        return new WidgetCanvas(new GaugeInfoPanel(item));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/GaugePanel.java	Fri Feb 01 16:32:48 2013 +0100
@@ -0,0 +1,52 @@
+package de.intevation.flys.client.client.ui.stationinfo;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.shared.model.RiverInfo;
+
+/**
+ * The GaugePanel is intended to be used within a SectionStackSection
+ *
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class GaugePanel extends InfoPanel {
+
+    /**
+     * GaugePanel loads the GaugeInfo from the RiverInfoService and
+     * displays them in a tree underneath a RiverInfoPanel
+     *
+     * @param flys The FLYS object
+     */
+    public GaugePanel(FLYS flys) {
+        super(new GaugeListGrid(flys));
+    }
+
+
+    @Override
+    public String getSectionTitle() {
+        return MSG.gaugePanelTitle();
+    }
+
+    /**
+     * Loads the river info and renders it afterwards
+     */
+    public void refresh() {
+        contract();
+
+        riverInfoService.getGauges(this.river, new AsyncCallback<RiverInfo>() {
+            @Override
+            public void onFailure(Throwable e) {
+                GWT.log("Could not load the river info." + e);
+            }
+
+            @Override
+            public void onSuccess(RiverInfo riverinfo) {
+                GWT.log("Loaded river info");
+                render(riverinfo);
+                expand();
+            }
+        });
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/GaugeRecord.java	Fri Feb 01 16:32:48 2013 +0100
@@ -0,0 +1,160 @@
+package de.intevation.flys.client.client.ui.stationinfo;
+
+import com.google.gwt.core.client.GWT;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.shared.model.GaugeInfo;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class GaugeRecord extends ListGridRecord implements GaugeInfo {
+
+    /** The message class that provides i18n strings.*/
+    private FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+    public GaugeRecord(GaugeInfo gauge) {
+        setCanExpand(true);
+        Long number = gauge.getOfficialNumber();
+        String url = number != null ?
+                MSG.gauge_url() + number :
+                MSG.gauge_url();
+        setLink(url);
+        setLinkText(MSG.gauge_info_link());
+        setName(gauge.getName());
+        setKmStart(gauge.getKmStart());
+        setKmEnd(gauge.getKmEnd());
+        setMinQ(gauge.getMinQ());
+        setMaxQ(gauge.getMaxQ());
+        setMinW(gauge.getMinW());
+        setMaxW(gauge.getMaxW());
+        setAeo(gauge.getAeo());
+        setDatum(gauge.getDatum());
+        setKmUp(gauge.isKmUp());
+        setOfficialNumber(gauge.getOfficialNumber());
+        setRiverName(gauge.getRiverName());
+        setStation(gauge.getStation());
+        setWstUnit(gauge.getWstUnit());
+    }
+
+    private void setLink(String url) {
+        this.setAttribute("link", url);
+    }
+
+    public String getLink() {
+        return this.getAttributeAsString("link");
+    }
+
+    public String getName() {
+        return this.getAttributeAsString("name");
+    }
+
+    private void setName(String value) {
+        this.setAttribute("name", value);
+    }
+
+    public Double getKmStart() {
+        return this.getAttributeAsDouble("kmstart");
+    }
+
+    private void setKmStart(Double value) {
+        this.setAttribute("kmstart", value);
+    }
+
+    public Double getKmEnd() {
+        return this.getAttributeAsDouble("kmend");
+    }
+
+    private void setKmEnd(Double value) {
+        this.setAttribute("kmend", value);
+    }
+
+    public Double getMinQ() {
+        return this.getAttributeAsDouble("minq");
+    }
+
+    private void setMinQ(Double value) {
+        this.setAttribute("minq", value);
+    }
+
+    public Double getMaxQ() {
+        return this.getAttributeAsDouble("maxq");
+    }
+
+    private void setMaxQ(Double value) {
+        this.setAttribute("maxq", value);
+    }
+
+    public Double getMinW() {
+        return this.getAttributeAsDouble("minw");
+    }
+
+    private void setMinW(Double value) {
+        this.setAttribute("minw", value);
+    }
+
+    public Double getMaxW() {
+        return this.getAttributeAsDouble("maxw");
+    }
+
+    private void setMaxW(Double value) {
+        this.setAttribute("maxw", value);
+    }
+
+    public Double getDatum() {
+        return this.getAttributeAsDouble("datum");
+    }
+
+    private void setDatum(Double value) {
+        this.setAttribute("datum", value);
+    }
+
+    public Double getAeo() {
+        return this.getAttributeAsDouble("aeo");
+    }
+
+    private void setAeo(Double value) {
+        this.setAttribute("aeo", value);
+    }
+
+    public boolean isKmUp() {
+        return this.getAttributeAsBoolean("kmup");
+    }
+
+    private void setKmUp(boolean value) {
+        this.setAttribute("kmup", value);
+    }
+
+    public Double getStation() {
+        return this.getAttributeAsDouble("station");
+    }
+
+    private void setStation(Double value) {
+        this.setAttribute("station", value);
+    }
+
+    public String getWstUnit() {
+        return this.getAttributeAsString("wstunit");
+    }
+
+    private void setWstUnit(String value) {
+        this.setAttribute("wstunit", value);
+    }
+
+    public Long getOfficialNumber() {
+        return this.getAttributeAsLong("officialnumber");
+    }
+
+    private void setOfficialNumber(Long number) {
+        this.setAttribute("officialnumber", number);
+    }
+
+    public String getRiverName() {
+        return this.getAttributeAsString("rivername");
+    }
+
+    private void setRiverName(String rivername) {
+        this.setAttribute("rivername", rivername);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/InfoListGrid.java	Fri Feb 01 16:32:48 2013 +0100
@@ -0,0 +1,67 @@
+package de.intevation.flys.client.client.ui.stationinfo;
+
+import com.google.gwt.core.client.GWT;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.shared.model.Data;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.RiverInfo;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public abstract class InfoListGrid extends ListGrid {
+
+    protected FLYS flys;
+    protected DataList[] data;
+
+    public InfoListGrid(FLYS flys) {
+        super();
+        this.flys = flys;
+        this.setCanExpandRecords(true);
+        this.setCanExpandMultipleRecords(true);
+    }
+
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+    public void openAll() {
+        GWT.log("InfoListGrid - openAll");
+        for (ListGridRecord record: this.getRecords()) {
+            expandRecord(record);
+        }
+    }
+
+    public void setData(DataList[] data) {
+        GWT.log("InfoListGrid - setData");
+        this.data = data;
+        this.open();
+    }
+
+    protected Double getDoubleValue(Data d) {
+        String tmp = d.getStringValue();
+        if (tmp != null) {
+            return Double.valueOf(tmp);
+        }
+        return null;
+    }
+
+    @Override
+    protected Canvas getExpansionComponent(ListGridRecord record) {
+        VLayout layout = new VLayout();
+        layout.setPadding(5);
+        layout.addMember(this.getExpandPanel(record));
+        return layout;
+    }
+
+    public abstract void open();
+
+    public abstract void setRiverInfo(RiverInfo riverinfo);
+
+    protected abstract Canvas getExpandPanel(ListGridRecord record);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/InfoPanel.java	Fri Feb 01 16:32:48 2013 +0100
@@ -0,0 +1,140 @@
+package de.intevation.flys.client.client.ui.stationinfo;
+
+import com.google.gwt.core.client.GWT;
+
+import com.smartgwt.client.types.Overflow;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.layout.SectionStackSection;
+import com.smartgwt.client.widgets.layout.VLayout;
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.client.services.RiverInfoService;
+import de.intevation.flys.client.client.services.RiverInfoServiceAsync;
+import de.intevation.flys.client.client.ui.RiverInfoPanel;
+import de.intevation.flys.client.shared.model.DataList;
+import de.intevation.flys.client.shared.model.RiverInfo;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public abstract class InfoPanel extends VLayout {
+
+    /** SectionStackSection where this InfoPanel belongs in*/
+    protected SectionStackSection section;
+
+    /** Name of the river */
+    protected String river;
+
+    /** The message class that provides i18n strings.*/
+    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+    protected RiverInfoServiceAsync riverInfoService = GWT.create(RiverInfoService.class);
+
+    /** Panel to show the info about the river */
+    protected RiverInfoPanel riverinfopanel;
+
+    protected InfoListGrid listgrid;
+
+    public final static String SECTION_ID = "InfoPanelSection";
+
+    public InfoPanel(InfoListGrid listgrid) {
+        SectionStackSection section = new SectionStackSection();
+        section.setExpanded(false);
+        section.setTitle(getSectionTitle());
+        section.setName(SECTION_ID);
+        section.setID(SECTION_ID);
+
+        setOverflow(Overflow.HIDDEN);
+        setStyleName("infopanel");
+
+        section.setHidden(true);
+        section.setItems(this);
+        this.section = section;
+        this.listgrid = listgrid;
+        this.addMember(listgrid);
+    }
+
+    /**
+     * Sets and loads the river data if river is not the current set river
+     */
+    public void setRiver(String river) {
+        if (!river.equals(this.river)) {
+            this.river = river;
+            this.refresh();
+        }
+    }
+
+    /**
+     * Sets the data and closes not corresponding folds in the gauge tree
+     */
+    public void setData(DataList[] data) {
+        this.listgrid.setData(data);
+    }
+
+    protected void render(RiverInfo riverinfo) {
+        if (this.riverinfopanel == null) {
+            this.riverinfopanel = new RiverInfoPanel(riverinfo);
+
+            this.addMember(this.riverinfopanel, 0);
+        }
+        else {
+            riverinfopanel.setRiverInfo(riverinfo);
+        }
+        this.listgrid.setRiverInfo(riverinfo);
+    }
+
+    /**
+     * Hide the section stack section.
+     */
+    @Override
+    public void hide() {
+        GWT.log("InfoPanel - hide");
+        this.section.setHidden(true);
+    }
+
+    /**
+     * Show the section stack section.
+     */
+    @Override
+    public void show() {
+        GWT.log("InfoPanel - show");
+        this.section.setHidden(false);
+    }
+
+    @Override
+    public void addMember(Canvas component) {
+        super.addMember(component);
+        expand();
+    }
+
+    @Override
+    public void removeMembers(Canvas[] components) {
+        super.removeMembers(components);
+        contract();
+    }
+
+    public SectionStackSection getSection() {
+        return this.section;
+    }
+
+    protected void removeAllMembers() {
+        removeMembers(getMembers());
+    }
+
+    /**
+     * Expands the gauge section
+     */
+    public void expand() {
+        section.setExpanded(true);
+    }
+
+    /**
+     * Contracts/shrinks the expanded gauge section
+     */
+    public void contract() {
+        section.setExpanded(false);
+    }
+
+    protected abstract void refresh();
+
+    protected abstract String getSectionTitle();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/MeasurementStationListGrid.java	Fri Feb 01 16:32:48 2013 +0100
@@ -0,0 +1,139 @@
+package de.intevation.flys.client.client.ui.stationinfo;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
+import com.google.gwt.user.client.ui.DecoratorPanel;
+import com.google.gwt.user.client.ui.Grid;
+
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.WidgetCanvas;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.shared.model.MeasurementStation;
+import de.intevation.flys.client.shared.model.RiverInfo;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class MeasurementStationListGrid extends InfoListGrid {
+
+    public MeasurementStationListGrid(FLYS flys) {
+        super(flys);
+        ListGridField nfield = new ListGridField("name", "Messtelle");
+        ListGridField sfield = new ListGridField("kmstart", "Start [km]", 60);
+        ListGridField efield = new ListGridField("kmend", "Ende [km]", 60);
+        ListGridField stfield = new ListGridField("station", "Station [km]");
+        ListGridField lfield = new ListGridField("link", "Link");
+        lfield.setType(ListGridFieldType.LINK);
+        this.setFields(nfield, sfield, efield, stfield, lfield);
+    }
+
+    /**
+     * Resets the items of the tree.
+     * If the list of gauges is empty or null the tree will be empty.
+     */
+    @Override
+    public void setRiverInfo(RiverInfo riverinfo) {
+        List<MeasurementStation> stations = riverinfo.getMeasurementStations();
+        GWT.log("MeasurmentStationListGrid - setRiverInfo " + stations);
+
+        if (stations != null && !stations.isEmpty()) {
+
+            ArrayList<MeasurementStation> emptystations =
+                new ArrayList<MeasurementStation>();
+
+            if (!riverinfo.isKmUp()) {
+                for (MeasurementStation station : stations) {
+                    addStation(station, emptystations);
+                }
+            }
+            else {
+                for (int i = stations.size()-1; i >= 0; i--) {
+                    MeasurementStation station = stations.get(i);
+                    addStation(station, emptystations);
+                }
+            }
+
+            // put empty stations to the end
+            for (MeasurementStation station : emptystations) {
+                addStation(station);
+            }
+        }
+    }
+
+    private void addStation(MeasurementStation station,
+            List<MeasurementStation> empty) {
+        if (station.getKmStart() != null && station.getKmEnd() != null) {
+            addStation(station);
+        }
+        else {
+            empty.add(station);
+        }
+    }
+
+    private void addStation(MeasurementStation station) {
+        ListGridRecord record = new MeasurementStationRecord(station);
+        this.addData(record);
+    }
+
+    class MeasurementStationDecoratorPanel extends DecoratorPanel {
+
+        public MeasurementStationDecoratorPanel(MeasurementStation station) {
+            setStyleName("infopanel");
+            Grid grid = new Grid(5, 2);
+
+            String type = station.getMeasurementType();
+            if (type != null) {
+                grid.setText(0, 0, MSG.measurement_station_type());
+                grid.setText(0, 1, type);
+            }
+
+            String riverside = station.getRiverSide();
+            if (riverside != null) {
+                grid.setText(1, 0, MSG.riverside());
+                grid.setText(1, 1, riverside);
+            }
+
+            String gaugename = station.getGaugeName();
+            if (gaugename != null) {
+               grid.setText(2, 0, MSG.measurement_station_gauge_name());
+               grid.setText(2, 1, gaugename);
+            }
+
+            DateTimeFormat df = DateTimeFormat.getFormat(
+                    PredefinedFormat.DATE_MEDIUM);
+
+            Date starttime = station.getStartTime();
+            if (starttime != null) {
+               grid.setText(3, 0, MSG.measurement_station_start_time());
+               grid.setText(3, 1, df.format(starttime));
+            }
+
+            String moperator = station.getOperator();
+            if (moperator != null) {
+                grid.setText(4, 0, MSG.measurement_station_operator());
+                grid.setText(4, 1, moperator);
+            }
+
+            setWidget(grid);
+        }
+    }
+
+    @Override
+    public void open() {
+    }
+
+    @Override
+    protected Canvas getExpandPanel(ListGridRecord record) {
+        MeasurementStationRecord station = (MeasurementStationRecord)record;
+        return new WidgetCanvas(new MeasurementStationDecoratorPanel(station));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/MeasurementStationPanel.java	Fri Feb 01 16:32:48 2013 +0100
@@ -0,0 +1,56 @@
+package de.intevation.flys.client.client.ui.stationinfo;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.shared.model.RiverInfo;
+
+/**
+ * A Panel to show info about the MeasurementStations of a river
+ *
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class MeasurementStationPanel extends InfoPanel {
+
+    /**
+     * MeasurementStationPanel loads the MeasurementStations from the
+     * RiverInfoService and displays them in a tree underneath a RiverInfoPanel
+     *
+     * @param flys The FLYS object
+     */
+    public MeasurementStationPanel(FLYS flys) {
+        super(new MeasurementStationListGrid(flys));
+    }
+
+    /**
+     * Returns the title which should be displayed in the section
+     */
+    @Override
+    public String getSectionTitle() {
+        return MSG.measurementStationPanelTitle();
+    }
+
+    /**
+     * Loads the river info and renders it afterwards
+     */
+    @Override
+    public void refresh() {
+        GWT.log("MeasurementStationPanel - refresh");
+        contract();
+
+        riverInfoService.getMeasurementStations(this.river,
+            new AsyncCallback<RiverInfo>() {
+                @Override
+                public void onFailure(Throwable e) {
+                    GWT.log("Could not load the river info." + e);
+                }
+
+                @Override
+                public void onSuccess(RiverInfo riverinfo) {
+                    GWT.log("MeasurementStationPanel - Loaded river info");
+                    render(riverinfo);
+                    expand();
+                }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/stationinfo/MeasurementStationRecord.java	Fri Feb 01 16:32:48 2013 +0100
@@ -0,0 +1,175 @@
+package de.intevation.flys.client.client.ui.stationinfo;
+
+import java.util.Date;
+
+import com.google.gwt.core.client.GWT;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+import de.intevation.flys.client.client.FLYSConstants;
+import de.intevation.flys.client.shared.model.MeasurementStation;
+
+/**
+ * @author <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
+ */
+public class MeasurementStationRecord
+extends ListGridRecord
+implements MeasurementStation {
+
+    /** The message class that provides i18n strings.*/
+    private FLYSConstants MSG = GWT.create(FLYSConstants.class);
+
+    public MeasurementStationRecord(MeasurementStation station) {
+        this.setCanExpand(true);
+
+        Integer number = station.getID();
+        String link = number != null ?
+            MSG.measurement_station_url() + number :
+            MSG.measurement_station_url();
+        this.setLink(link);
+        this.setLinkText(MSG.measurement_station_info_link());
+        this.setID(number);
+        this.setName(station.getName());
+        if (station.isKmUp()) {
+            this.setKmEnd(station.getKmStart());
+            this.setKmStart(station.getKmEnd());
+        }
+        else {
+            this.setKmEnd(station.getKmEnd());
+            this.setKmStart(station.getKmStart());
+        }
+        this.setKmUp(station.isKmUp());
+        this.setRiverName(station.getRiverName());
+        this.setStation(station.getStation());
+        this.setGaugeName(station.getGaugeName());
+        this.setMeasurementType(station.getMeasurementType());
+        this.setOperator(station.getOperator());
+        this.setRiverSide(station.getRiverSide());
+        this.setStartTime(station.getStartTime());
+        this.setStopTime(station.getStopTime());
+    }
+
+    @Override
+    public Integer getID() {
+        return this.getAttributeAsInt("stationid");
+    }
+
+    private void setID(Integer value) {
+        this.setAttribute("stationid", value);
+    }
+
+    @Override
+    public String getName() {
+        return this.getAttributeAsString("name");
+    }
+
+    private void setName(String value) {
+        this.setAttribute("name", value);
+    }
+
+    @Override
+    public Double getKmStart() {
+        return this.getAttributeAsDouble("kmstart");
+    }
+
+    private void setKmStart(Double value) {
+        this.setAttribute("kmstart", value);
+    }
+
+    @Override
+    public Double getKmEnd() {
+        return this.getAttributeAsDouble("kmend");
+    }
+
+    private void setKmEnd(Double value) {
+        this.setAttribute("kmend", value);
+    }
+
+    @Override
+    public boolean isKmUp() {
+        return this.getAttributeAsBoolean("kmup");
+    }
+
+    private void setKmUp(boolean value) {
+        this.setAttribute("kmup", value);
+    }
+
+    @Override
+    public Double getStation() {
+        return this.getAttributeAsDouble("station");
+    }
+
+    private void setStation(Double station) {
+        this.setAttribute("station", station);
+    }
+
+    @Override
+    public String getRiverName() {
+        return this.getAttributeAsString("rivername");
+    }
+
+    private void setRiverName(String rivername) {
+        this.setAttribute("rivername", rivername);
+    }
+
+    @Override
+    public String getRiverSide() {
+        return this.getAttributeAsString("riverside");
+    }
+
+    private void setRiverSide(String riverside) {
+        this.setAttribute("riverside", riverside);
+    }
+
+    @Override
+    public String getMeasurementType() {
+        return this.getAttributeAsString("measurementtype");
+    }
+
+    private void setMeasurementType(String value) {
+        this.setAttribute("measurementtype", value);
+    }
+
+    @Override
+    public String getOperator() {
+        return this.getAttributeAsString("operator");
+    }
+
+    private void setOperator(String value) {
+        this.setAttribute("operator", value);
+    }
+ 
+    @Override
+    public Date getStartTime() {
+        return this.getAttributeAsDate("starttime");
+    }
+
+    private void setStartTime(Date value) {
+        this.setAttribute("starttime", value);
+    }
+
+    @Override
+    public Date getStopTime() {
+        return this.getAttributeAsDate("stoptime");
+    }
+
+    private void setStopTime(Date value) {
+        this.setAttribute("stoptime", value);
+    }
+
+    @Override
+    public String getGaugeName() {
+        return this.getAttributeAsString("gaugename");
+    }
+
+    private void setGaugeName(String value) {
+        this.setAttribute("gaugename", value);
+    }
+
+    public String getLink() {
+        return this.getAttributeAsString("link");
+    }
+    
+    public void setLink(String link) {
+        this.setAttribute("link", link);
+    }
+}

http://dive4elements.wald.intevation.org