blob: bb1798681059237b6519ae67bba4da418709b3c3 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<!-- -*- xhtml -*- -->
<title>NetBeans Platform Gesture Collection Infrastructure for NetBeans Platform 7.0</title>
<meta name="AUDIENCE" content="NBUSER"/>
<meta name="TYPE" content="ARTICLE"/>
<meta name="EXPIRES" content="N"/>
<meta name="developer" content="geertjan.wielenga@sun.com"/>
<meta name="indexed" content="y"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="description"
content="A guide describing how to collect gestures in NetBeans Platform applications."/>
<link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"/>
</head>
<!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -->
<!-- Use is subject to license terms.-->
<body>
<h1><a name="top"></a>NetBeans Platform Gesture Collection Infrastructure Tutorial</h1>
<p>Do you know what your users are doing with your NetBeans Platform application?
Which windows are they opening? Which actions are they commonly invoking? When
are they clicking the "Help" button on a dialog? Knowing the answers to these questions
is crucial in determining where you should be assigning development resources. Knowing
that the "Help" button is being pressed a lot for a particular feature might indicate that
there is a problem with the UI that you could consider modifying in some way.</p>
<p>Also, the priority of bugs can be determined, at least partially, by how frequently something
is actually being used. When someone files a P1 bug and writes e-mails demanding you
fix something, wouldn't it be helpful to find out that the buggy feature in question is
only being used by 2% of your user base?</p>
<p>The usefulness of knowing what users are doing with your application is limitless. Time to
add a user interface gesture collector to your application. NetBeans IDE has such a collector and, since your
application is built on the same infrastructure (i.e., the NetBeans Platform), you can make
use of that same gesture collecting infrastructure.</p>
<p>In this tutorial, you are introduced to setting up
the NetBeans Platform gesture collection infrastructure and to using
it in a NetBeans Platform application. You will analyze how heavily the
"brush size change" feature in the NetBeans Paint Application is used:</p>
<p><img style="border:1px solid black" alt="brand gesture" src="../../images/tutorials/gesture/70/uigestureserver-5.png"/></p>
<p>By the end of this tutorial, you should have a general understanding of how
the gesture collection infrastructure fits together and have a basic idea
of how to create your own statistics and where to go for further information.</p>
<p><b>Contents</b></p>
<p><img src="../../images/articles/70/netbeans-stamp.gif" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 6.9" title="Content on this page applies to NetBeans IDE 6.9"/></p>
<ul class="toc">
<li><a href="#setup">Setting Up the Gesture Collecting Infrastructure</a></li>
<li><a href="#log">Logging UI Gestures</a></li>
<li><a href="#submit">Submitting UI Gestures</a></li>
<li><a href="#accept">Accepting UI Gestures</a></li>
<li><a href="#visualize">Visualizing UI Gestures</a></li>
<li><a href="#reading">Further Reading</a></li>
</ul>
<p><b>To follow this tutorial, you need the software and resources listed in the following
table.</b></p>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td>
<td class="tbltd1">version 7.0 or above</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">Java Developer Kit (JDK)</a></td>
<td class="tbltd1">version 6 or above</td>
</tr>
</tbody>
</table>
<!-- ===================================================================================== -->
<h2 class="tutorial"><a name="setup"></a>Setting Up the Gesture Collecting Infrastructure</h2>
<p>When setting up the gesture collecting infrastructure, you need
to enable certain modules that are disabled by
default in your NetBeans Platform application.</p>
<p class="tips">If you want to try out these instructions on an actual
application prior to trying them out on your own
sources, you can use the NetBeans Platform Paint
Application, which you can get from the Samples
category in the New Project wizard (Ctrl-Shift-N). That is the
example application that will be referred to throughout this
tutorial.</p>
<div class="indent">
<ol>
<li>In the Projects window, right-click your application and choose Properties.
In the Project Properties dialog, click "Libraries".</li>
<li><p>Check the "nb" checkbox, then check the following three checkboxes
to add the related modules
to the application:</p>
<ul>
<li>UI Gestures Collector Infrastructure</li>
<li>UI Handler Library</li>
</ul>
<p>You should now see the following:</p>
<p><img alt="enable harness" src="../../images/tutorials/gesture/70/enable-infrastructure.png"/></p>
</li>
</ol>
</div>
<!-- ======================================================================================== -->
<h2><a name="log"></a>Logging UI Gestures</h2>
<p>A UI collecting gesture, that is, an event that will be identified as a UI gesture,
is considered to be everything that is logged into the "org.netbeans.ui" logger. In this section
you are shown how to use this logger.</p>
<div class="indent">
<ol>
<li>In the <tt>PaintTopComponent</tt>, change the <tt>stateChanged</tt> method so that
a new gesture log is created whenever the brush size changes:
<pre class="examplecode">@Override
public void stateChanged(ChangeEvent e) {
int brushSize = brushSizeSlider.getValue();
canvas.setBrushDiameter(brushSize);
String UI_LOGGER_NAME = "org.netbeans.ui.brushsize";
LogRecord record = new LogRecord(Level.INFO, "BRUSH_SIZE_CHANGED");
record.setParameters(new Object[]{brushSize});
record.setLoggerName(UI_LOGGER_NAME);
Logger.getLogger(UI_LOGGER_NAME).log(record);
}</pre>
<p class="tips">Read more about <a href="http://download.oracle.com/javase/6/docs/api/java/util/logging/LogRecord.html"><tt>java.util.logging.LogRecord</tt></a>. </p>
</li>
<li><p>Run the application. Make the gesture a few times, that is, change the brush
size a few times, using the "Brush Size" slider, shown below:</p>
<p><img style="border: 1px solid black" alt="enable harness" src="../../images/tutorials/gesture/70/brush-change.png"/></p></li>
<li><p>Close the application and notice that the following file exists in the "build/testuserdir/var/log"
folder, which is visible if the Files window (Ctrl-2) is open in the IDE:</p>
<p><img alt="enable harness" src="../../images/tutorials/gesture/70/gesture-collected.png"/></p>
<p>Whenever the brush size changes, a new entry such as the following is added to the "uigestures"
file:</p>
<pre class="examplecode">&lt;record&gt;
&lt;date&gt;2011-05-12T16:42:30&lt;/date&gt;
&lt;millis&gt;1305211350828&lt;/millis&gt;
&lt;sequence&gt;102&lt;/sequence&gt;
&lt;level&gt;INFO&lt;/level&gt;
&lt;thread&gt;12&lt;/thread&gt;
&lt;message&gt;BRUSH_SIZE_CHANGED&lt;/message&gt;
&lt;param&gt;24&lt;/param&gt;
&lt;/record&gt;</pre>
</li>
</ol>
</div>
<p>You have now learned how to collect UI gestures. Let's now learn how to
submit them to the server.</p>
<!-- ======================================================================================== -->
<h2><a name="submit"></a>Submitting UI Gestures</h2>
<p>In this section, you learn how to submit gestures to the server. By default, gestures are automatically submitted
once there are 1000 gestures in the "uigestures" folder. In addition to that, in this example we are going to
let the user specify when the gestures are to be sent, interactively, via a button in the toolbar.</p>
<ol>
<li><p>Follow <a href="http://netbeans.dzone.com/news/including-nbm-files-netbeans">these instructions</a> to incorporate
this plugin into your application: <a href="http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastStableBuild/artifact/nbbuild/nbms/extra/org-netbeans-modules-uihandler-interactive.nbm">org-netbeans-modules-uihandler-interactive.nbm</a></p>
<p class="tips">Add this target to your application's "build.xml" file and then the
NBM you have downloaded above will always be copied into the right folder whenever
you build the application, assuming the NBM file is in the same folder as the
"build.xml" file:</p>
<pre class="examplecode">&lt;target name="build" depends="suite.build"&gt;
&lt;copy todir="build/cluster/update/download" &gt;
&lt;fileset file="org-netbeans-modules-uihandler-interactive.nbm"/&gt;
&lt;/copy&gt;
&lt;echo message="copied the interactive ui handler into cluster/update/download" /&gt;
&lt;/target&gt;</pre>
</li>
<li><p>Run the application and notice that you now have a new button in the toolbar,
which can be used for submitting gestures to the server:</p>
<p><img style="border:1px black solid" alt="brand gesture" src="../../images/tutorials/gesture/70/uigesture-submit.png"/></p>
</li>
<li><p>Click the button and you see this dialog:</p>
<p><img alt="brand gesture" src="../../images/tutorials/gesture/70/welcome-uigesture.png"/></p>
</li>
<li><p>Click "View Data" and you see this dialog, showing the data that is ready to be submitted:</p>
<p><img alt="brand gesture" src="../../images/tutorials/gesture/70/data-dialog.png"/></p>
</li>
<li><p>Now we will change the location for submitting the gestures. By default, gestures are submitted here:</p>
<pre class="examplecode"><a href="https://netbeans.org/nonav/uigestures/index3.html">http://netbeans.org/nonav/uigestures/index3.html</a></pre>
<p>Look in the source of that location and you will see this:</p>
<pre class="examplecode">&lt;!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;&lt;/meta&gt;
&lt;title&gt;Welcome to UI Gestures Collector&lt;/title&gt;
&lt;link rel="stylesheet" type="text/css" href="https://netbeans.org/nonav/uigestures/index.css"&gt;&lt;/link&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;
You can now submit data about the UI actions you did in the IDE and
help us make NetBeans better. &lt;a href="https://netbeans.org/nonav/uigestures/info2.html"&gt;
Read more...&lt;/a&gt;
&lt;/p&gt;
&lt;!--
&lt;form action="https://netbeans.org/uigestures/post2.html" method="post"&gt;
--&gt;
<b>&lt;form action="http://statistics.netbeans.org/analytics/upload.jsp" method="post"&gt;</b>
&lt;input type="hidden" name="submit" value="&amp;Submit Data"&gt;&lt;/input&gt;
&lt;input type="hidden" name="auto-submit" value="&amp;Automatic Submit"&gt;&lt;/input&gt;
&lt;input type="hidden" name="view-data" value="&amp;View Data" align="left" alt="&amp;Hide Data"&gt;&lt;/input&gt;
&lt;input type="hidden" name="exit" value="&amp;Cancel"&gt;&lt;/input&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Gestures for NetBeans IDE
are visualized at <a href="http://statistics.netbeans.org/analytics/">http://statistics.netbeans.org/analytics/</a>.</li>
<li><p>You need to create an XHTML page similar to the above, but pointing to your own location
for receiving gestures. For example:</p>
<pre class="examplecode">&lt;h2&gt;UI Gestures Collector&lt;/h2&gt;
&lt;p&gt;Welcome to UI Gestures Collector&lt;/p&gt;
&lt;p&gt;You can now submit data about the UI actions you performed.&lt;/p&gt;
&lt;form action="http://localhost:8888/analytics/upload.jsp" method="post"&gt;
&lt;input name="submit" value="&amp;Submit Data" type="hidden"&gt;
&lt;input name="exit" value="&amp;Cancel" type="hidden"&gt;
&lt;/form&gt;</pre>
<p class="tips">Later in this tutorial you will learn how to use the "upload.jsp"
referred to above.</p></li>
<li><p>Now that we have a site that will handle our gestures, we need to customize the
gesture collecting infrastructure to use that site rather than the default.
The site used for this purpose is specified by the WELCOME_URL key
in a bundle in the "uihandler" module. You now need to brand the value of the WELCOME_URL key
to point to where your site for handling gestures is found. Right-click on the Paint Application and choose "Branding". In the Branding editor, use
the Resource Bundles tab to look for "uigestures". You will find several values returned,
as shown below, including "WELCOME_URL":</p>
<p><img alt="brand gesture" src="../../images/tutorials/gesture/70/brand-ui-gesture.png"/></p>
<p>Right-click on the WELCOME_URL item above and choose "Add To Branding". Then replace the
above with the location of your own UI gesture handling location.</p></li>
</ol>
<p>By means of the indirection provided by the gesture collection XHTML page shown above,
you can easily switch to different servers or change the buttons shown in the page or
even shutdown the service completely, simply by editing the XHTML page.</p>
<!-- ======================================================================================== -->
<h2><a name="accept"></a>Accepting UI Gestures</h2>
<p>In this section, you learn how to accept gestures.</p>
<ol>
<li><p>Install Mercurial and run this command:</p>
<pre class="examplecode">hg clone http://hg.netbeans.org/main/misc</pre>
<p>You should see something like the following:</p>
<pre class="examplecode">C:\Documents and Settings\gwielenga\uigesture>hg clone http://hg.netbeans.org/main/misc
destination directory: misc
requesting all changes
adding changesets
adding manifests
adding file changes
added 5854 changesets with 22833 changes to 7178 files
updating to branch default
4995 files updated, 0 files merged, 0 files removed, 0 files unresolved</pre></li>
<li><p>In the Files window, browse to the location where you did your clone and you should
be able to open "misc/logger/uihandlerserver" as a NetBeans project, as shown below:</p>
<p><img alt="brand gesture" src="../../images/tutorials/gesture/70/uigestureserver-1.png"/></p>
</li>
<li>On the command line, go to the location above, that is, go to "misc/logger/uihandlerserver" and
then run:
<pre class="examplecode">ant</pre>
<p>The above command will download many required JARs and compile the application. The application should now look as follows in the IDE:</p>
<p><img alt="brand gesture" src="../../images/tutorials/gesture/70/uigestureserver-2.png"/></p>
<li><p>Run the application and go to this site:</p>
<pre class="examplecode"><a href="http://localhost:8888/">http://localhost:8888/</a></pre>
<p>The analytics application should start and you should see a default analytics
page in your browser.</p></li>
<li><p>Now we're going to set up our NetBeans Platform application to use the redirect
page that is in the deployed application, at "misc/logger/uihandlerserver/redirect.xhtml". Do this
by opening the application's <tt>project.properties</tt> file and then adding this line, changing
it where necessary to match your own file location:
<pre class="examplecode">run.args.extra=-J-Dorg.netbeans.modules.uihandler.LoadURI=file:///"C:/Documents and Settings/gwielenga/uigesture/misc/logger/uihandlerserver/redirect.xhtml"</pre>
</li>
<li><p>When the application starts up, click the UI Gesture button, then click "Submit Data" a few times, refresh
the page in the browser, and you should see something like this, taking
note of the top right corner, where the data is incremented:</p>
<p><img style="border:1px solid black" alt="brand gesture" src="../../images/tutorials/gesture/70/uigestureserver-3.png"/></p>
</li>
<li><p>Look in the "uihandlerserver/build/logs" folder and you'll see a new file added each time
data is submitted to the server:</p>
<p><img alt="brand gesture" src="../../images/tutorials/gesture/70/uigestureserver-4.png"/></p>
</li>
</ol>
<p>You have now learned about the Analytics application and how to use it to accept gestures from the user.</p>
<!-- ======================================================================================== -->
<h2><a name="visualize"></a>Visualizing UI Gestures</h2>
<p>In this section, you learn how to visualize gestures. You will do so by working
with three files in the Analytics application. You will create a Statistic class:</p>
<p><img alt="brand gesture" src="../../images/tutorials/gesture/70/sample-1.png"/></p>
<p>You will also create a JSP file:</p>
<p><img alt="brand gesture" src="../../images/tutorials/gesture/70/sample-2.png"/></p>
<p>Finally, you will tweak an existing file, which defines the sidebar of the application:</p>
<p><img alt="brand gesture" src="../../images/tutorials/gesture/70/sample-3.png"/></p>
<p class="tips">To learn about the different ways of visualizing gestures, you are advised to
examine the existing statistic classes and JSP files in the application. These are
used by the <a href="http://statistics.netbeans.org/analytics/">NetBeans statistics community</a> and can serve as examples for your
own statistics.</p>
<ol>
<li><p>Let's first create a statistic:</p>
<pre class="examplecode">package org.netbeans.server.uihandler.statistics;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.LogRecord;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import javax.servlet.jsp.PageContext;
import org.netbeans.server.uihandler.Statistics;
import org.netbeans.server.uihandler.statistics.BrushSizeChangeStatistic.DataBean;
import org.openide.util.lookup.ServiceProvider;
@ServiceProvider(service = Statistics.class)
public class BrushSizeChangeStatistic extends Statistics<DataBean> {
private static final DataBean EMPTY = new DataBean(0, 0, 0);
public static final String STATISTIC_NAME = "BrushSizeChangeStatistic";
public BrushSizeChangeStatistic() {
super(STATISTIC_NAME);
}
@Override
protected DataBean newData() {
return EMPTY;
}
@Override
protected DataBean process(LogRecord rec) {
if ("BRUSH_SIZE_CHANGED".equals(rec.getMessage())) {
return new DataBean(1, 0, 0);
} else {
return EMPTY;
}
}
@Override
protected DataBean finishSessionUpload(String userId, int sessionNumber, boolean initialParse, DataBean d) {
int nonNullSessions = 0;
if (d.getActionsCount() > 0) {
nonNullSessions = 1;
}
return new DataBean(d.getActionsCount(), 1, nonNullSessions);
}
@Override
protected DataBean join(DataBean one, DataBean two) {
return new DataBean(one.getActionsCount() + two.getActionsCount(),
one.getNumberOfSessions() + two.getNumberOfSessions(),
one.getNumberOfNonNullSessions() + two.getNumberOfNonNullSessions());
}
@Override
protected void write(Preferences pref, DataBean d) throws BackingStoreException {
pref.putInt("all", d.getActionsCount());
pref.putInt("sessions", d.getNumberOfSessions());
pref.putInt("non_null_sessions", d.getNumberOfNonNullSessions());
}
@Override
protected DataBean read(Preferences pref) throws BackingStoreException {
return new DataBean(pref.getInt("all", 0), pref.getInt("sessions", 0), pref.getInt("non_null_sessions", 0));
}
@Override
protected void registerPageContext(PageContext page, String name, DataBean data) {
page.setAttribute(name + "Usages", data.getUsages());
}
public static final class DataBean {
private final int actionsCount;
private final int numberOfSessions;
private final int numberOfNonNullSessions;
public DataBean(int actionsCount, int numberOfSessions, int numberOfNonNullSessions) {
this.actionsCount = actionsCount;
this.numberOfSessions = numberOfSessions;
this.numberOfNonNullSessions = numberOfNonNullSessions;
}
public int getActionsCount() {
return actionsCount;
}
public int getNumberOfSessions() {
return numberOfSessions;
}
public int getNumberOfNonNullSessions() {
return numberOfNonNullSessions;
}
public Map<String, Integer> getUsages() {
Map<String, Integer> usages = new HashMap<String, Integer>();
usages.put("brush changed", numberOfNonNullSessions);
usages.put("brush not changed", numberOfSessions - numberOfNonNullSessions);
return usages;
}
}
}</pre>
</li>
<li><p>Next, we need to display our statistic in some way:</p>
<pre class="examplecode">&lt;%@page contentType="text/html"%&gt;
&lt;%@page pageEncoding="UTF-8"%&gt;
&lt;%@ taglib uri="/WEB-INF/statistics.tld" prefix="ui" %&gt;
&lt;c:set var="path" value='/ &lt;a href="../index.jsp"&gt;Analytics&lt;/a&gt; / Graph / Brush Size'/&gt;
&lt;%@include file="/WEB-INF/jspf/header.jspf" %&gt;
&lt;ui:useStatistic name="BrushSizeChangeStatistic"/&gt;
&lt;h2&gt;Brush Size Change Analysis&lt;/h2&gt;
&lt;ui:pie
collection="globalBrushSizeChangeStatisticUsages"
category="key"
value="value"
title="In how many logs was there a brush size change?"
resolution="600x200"
/&gt;
&lt;%@include file="/WEB-INF/jspf/footer.jspf" %&gt;</pre>
<p class="tips">It is important to understand how the JSP page above is linked
to the statistic class that we created earlier:</p>
<ul>
<li><b>Tag Library.</b> We use a tag library that
provides the "useStatistic" tag, in line 6 above.
The "useStatistic" tag injects the statistics data
into the JSP page. To create characters we
use the statistic tag library, together with, in this case,
its pie tag. The "useStatistic" tag injects the data that your statistic
has created into the JSP page. In our case we don't need
to preprocess the data first because the pie chart tag
accepts a collection and it doesn't need to know nothing
about our <tt>DataBean</tt>.
<li><b>Collection Name.</b> The name of the collection specified above, in line 11,
is "globalBrushSizeChangeStatisticUsages".
The prefix, "global", specifies that we want to see the
overall statistics, rather than "user" and "last". The "last"
prefix contains only data counted for the last submitted log,
while the "user" prefix contains all the data from the submitter.
The middle part of the name is "BrushSizeChangeStatistic", which
is the name of the statistic that has calculated the data, while
the suffix "Usages" was added in the statistic's "registerPageContext"
method so that different charts can be distinguished.
</ul>
</li>
<li><p>Run the Analytics application and also run the Paint application.
Submit a few logs and then go to this location:</p>
<pre class="examplecode"><a href="http://localhost:8888/analytics/graph/brushsize.jsp">http://localhost:8888/analytics/graph/brushsize.jsp</a></pre></a>
<p>Below, you can see that 7 logs have been submitted and that the majority of them
indicate that the brush size change feature is not used a lot:</p>
<p><img style="border:1px solid black" alt="brand gesture" src="../../images/tutorials/gesture/70/uigestureserver-5.png"/></p>
<li><p>Now, let's add a bar chart, together with the pie chart used above:</p>
<pre class="examplecode">&lt;%@page contentType="text/html"%&gt;
&lt;%@page pageEncoding="UTF-8"%&gt;
&lt;%@ taglib uri="/WEB-INF/statistics.tld" prefix="ui" %&gt;
&lt;c:set var="path" value='/ &lt;a href="../index.jsp"&gt;Analytics&lt;/a&gt; / Graph / Brush Size'/&gt;
&lt;%@include file="/WEB-INF/jspf/header.jspf" %&gt;
&lt;ui:useStatistic name="BrushSizeChangeStatistic"/&gt;
&lt;h2&gt;Brush Size Change Analysis&lt;/h2&gt;
&lt;ui:pie
collection="globalBrushSizeChangeStatisticUsages"
category="key"
value="value"
title="Number of logs with a brush size change"
resolution="600x200"
/&gt;
&lt;ui:bar
collection="globalBrushSizeChangeStatisticAvg"
category="name"
value="value"
serie="name"
stacked="true"
title="Average count of brush size changes"
resolution="300x400"
/&gt;
&lt;%@include file="/WEB-INF/jspf/footer.jspf" %&gt;</pre>
<p>This is what we'd like to see, that is, a bar chart
showing averages, together with our pie chart:</p>
<p><img style="border:1px solid black" alt="brand gesture" src="../../images/tutorials/gesture/70/uigestureserver-6.png"/></p>
<p>Therefore, we need to add a new calculation to our BrushSizeChangeStatistic.
</li>
<li><p>In the <tt>BrushSizeChangeStatistic</tt> class, add the following
to the <tt>DataBean</tt>: </p>
<pre class="examplecode">private Collection&lt;ViewBean&gt; getAvgData() {
List&lt;ViewBean&gt; vb = new ArrayList&lt;ViewBean&gt;();
vb.add(new ViewBean("AVG for all logs", actionsCount / numberOfSessions));
vb.add(new ViewBean("AVG for users of brush change", actionsCount / numberOfNonNullSessions));
return vb;
}
public static final class ViewBean {
private final String name;
private final Integer value;
public ViewBean(String name, Integer value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public Integer getValue() {
return value;
}
}</pre>
<p>Then expose the above via the line
in bold below in the <tt>registerPageContext</tt>:</p>
<pre class="examplecode">@Override
protected void registerPageContext(PageContext page, String name, DataBean data) {
page.setAttribute(name + "Usages", data.getUsages());
<b>page.setAttribute(name + "Avg", data.getAvgData());</b>
}</pre>
</li>
</ol>
<p>Now you know how to visualize gestures received from the user. Refer to the files
shown earlier and treat them as examples for your own statistics. In the "statistics"
package, explore the available statistics:</p>
<p><img alt="brand gesture" src="../../images/tutorials/gesture/70/sample-1.png"/></p>
<p>Then learn how to render them, by looking at the JSPs in the "graph" folder:
<p><img alt="brand gesture" src="../../images/tutorials/gesture/70/sample-2.png"/></p>
<!-- ======================================================================================== -->
<h2><a name="reading"></a>Further Reading</h2>
<p>This concludes the NetBeans Platform Gesture Collector Tutorial.
This document has described
how to collect user interface gestures from the users of a NetBeans Platform application.
For more information about gesture collecting on the NetBeans Platform,
see the following resources:</p>
<ul>
<li><a href="http://statistics.netbeans.org/analytics/">NetBeans Analytics Community</a></li>
<li><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-uihandler/overview-summary.html">UI Gestures Collector Infrastructure</a></li>
<li><a href="http://wiki.netbeans.org/UIGesturesCollector">UIGesturesCollector</a></li>
<li><a href="http://wiki.netbeans.org/HowToUseUIGesturesCollectorInYourApp">HowToUseUIGesturesCollectorInYourApp</a></li>
<li><a href="http://blogs.oracle.com/geertjan/entry/collecting_data_on_users_of">Collecting Data on Users of a NetBeans Platform Application</a></li>
<li><a href="http://weblogs.java.net/blog/fvo/archive/2010/11/22/slowness-detection-netbeans-rcp-applications">Slowness Detection in NetBeans RCP Applications</a></li>
<li><a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/doc-files/logging.html">Logging in NetBeans</a></li>
</ul>
<!-- ======================================================================================== -->
</body>
</html>