From: Erik Lumme Date: Mon, 11 Sep 2017 13:00:24 +0000 (+0300) Subject: Migrate IntegratingAnExistingGWTWidget X-Git-Tag: 8.2.0.alpha2~64^2~68 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=86b49480fdea2d193a5c62cc4644eabe0e9a5a15;p=vaadin-framework.git Migrate IntegratingAnExistingGWTWidget --- diff --git a/documentation/articles/IntegratingAnExistingGWTWidget.asciidoc b/documentation/articles/IntegratingAnExistingGWTWidget.asciidoc new file mode 100644 index 0000000000..e8917598aa --- /dev/null +++ b/documentation/articles/IntegratingAnExistingGWTWidget.asciidoc @@ -0,0 +1,179 @@ +[[integrating-an-existing-gwt-widget]] +Integrating an existing GWT widget +---------------------------------- + +Integrating an existing, third party GWT widget usually just involves +creating a regular Vaadin component with a client-side connector that +uses the third-party widget, probably using a shared state, and possibly +also with RPC - just as described in separate articles on these topics. +Usually, the only addition is the need to modify your widgetset +declaration to inherit the third-party widget's GWT module. + +In the following, we'll integrate the SimplePlot widget from the +http://code.google.com/p/gflot/[GFlot library] (which in turn is a GWT +adaptation of the pure JavaScript plotting library Flot) to create a +simple line plot component. We'll start with modifying our widgetset's +`gwt.xml` to inherit the GFlot GWT module, so if you're familiar with the +rest of the process, you can basically stop once that is done. + +But first a note on package structure: this particular example uses the +`com.example` package domain, and is set up to be a add-on project, with +the actual component in the `addon` package, and the demo that uses the +component in the `vaadingflot` package. The `addon` package contains the +`widgetset gwt.xml` definition, the server-side component (LinePlot), as +well as all the code related to the client-side in the `client.ui` +subpackage. + +Once you have a working project, go ahead and +http://code.google.com/p/gflot/downloads/list[download the GFlot jar], +and add it to `WEB-INF/lib`, then update the widgetset `gwt.xml` as follows: + +[source,xml] +.... + + + + + + +.... + +It inherits the default Vaadin widgetset as well as the GFlot GWT +module. + +Now we're ready to integrate the SimplePlot widget from the GFlot +package. Since we're familiar with the GFlot API, we know we want to add +'series' to the plot - we'll create a shared state for this purpose, and +a `DataSeries` class to represent the actual series within the state: + +[source,java] +.... +package com.example.addon.client.ui; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.client.ComponentState; + +public class LinePlotState extends AbstractComponentState { + + public List series = new ArrayList(); + + public static class DataSeries { + public String label; + public String color; + public List data; + } +} +.... + +Lets make the server-side component next: + +[source,java] +.... +package com.example.addon; + +import java.util.Arrays; + +import com.example.addon.client.ui.LinePlotState; +import com.example.addon.client.ui.LinePlotState.DataSeries; +import com.vaadin.ui.AbstractComponent; + +public class LinePlot extends AbstractComponent { + + public LinePlot() { + } + + @Override + public LinePlotState getState() { + return (LinePlotState) super.getState(); + } + + public void addSeries(String label, String color, Float[] fs) { + DataSeries ds = new DataSeries(); + ds.label = label; + ds.color = color; + ds.data = Arrays.asList(fs); + getState().series.add(ds); + } +} +.... + +We override `getState()` in order to narrow the return type to our own +`LinePlotState`, and then implement a simple `addSeries()` that creates a +`DataSeries` instance and adds it to the state. The state will be +automatically transmitted to the client when needed, so the plots will +remain intact over browser reloads for instance.The API for our +component could obviously be expanded, but lets leave it like this for +this example. + +Since the GWT widget we're going to use is already made for us (in the +GFlot library), the only thing left for us to do is implement the +client-side connector: + +[source,java] +.... +package com.example.addon.client.ui; + +import ca.nanometrics.gflot.client.DataPoint; +import ca.nanometrics.gflot.client.SeriesHandler; +import ca.nanometrics.gflot.client.SimplePlot; + +import com.example.addon.LinePlot; +import com.example.addon.client.ui.LinePlotState.DataSeries; +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.communication.StateChangeEvent; +import com.vaadin.client.ui.AbstractComponentConnector; +import com.vaadin.client.ui.Connect; + +@Connect(LinePlot.class) +public class LinePlotConnector extends AbstractComponentConnector { + + @Override + public LinePlotState getState() { + return (LinePlotState) super.getState(); + } + + @Override + public SimplePlot getWidget() { + return (SimplePlot) super.getWidget(); + } + + @Override + protected Widget createWidget() { + return GWT.create(SimplePlot.class); + } + + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); + + getWidget().getModel().clear(); + for (DataSeries ds : getState().series) { + + SeriesHandler s = getWidget().getModel().addSeries(ds.label, + ds.color); + for (int i = 0; i < ds.data.size(); i++) { + s.add(new DataPoint(i, ds.data.get(i))); + } + } + getWidget().redraw(); + } +} +.... + +We override both `getState()` and `getWidget()` to narrow the return type to +our liking, then make `createWidget()` return an instance of the GFlot +widget we're going to use, `SimplePlot`. + +Last, we override `onStateChange()` which is called whenever the shared +state has been changed. Here we make use of the `SimplePlot` API to add +the series contained in the shared state (for simplicity, we clear the +`SimplePlot` first, then add all the series in our state). + +That's it! The full source is available as an attachment to this +article. + +link:img/vaadinflot.zip[Attachment vaadinflot.zip] diff --git a/documentation/articles/contents.asciidoc b/documentation/articles/contents.asciidoc index 5c6679d05a..3c993f70da 100644 --- a/documentation/articles/contents.asciidoc +++ b/documentation/articles/contents.asciidoc @@ -39,3 +39,4 @@ are great, too. - link:UsingServerInitiatedEvents.asciidoc[Using server-initiated events] - link:ChooseInputFieldComponentsWisely.asciidoc[Choose input field components wisely] - link:CreatingASimpleComponent.asciidoc[Creating a simple component] +- link:IntegratingAnExistingGWTWidget.asciidoc[Integrating an existing GWT widget] diff --git a/documentation/articles/img/vaadingflot.zip b/documentation/articles/img/vaadingflot.zip new file mode 100644 index 0000000000..30b81f8fcc Binary files /dev/null and b/documentation/articles/img/vaadingflot.zip differ