jmeter-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Jmeter Wiki] Update of "DeveloperManual/VisualizerTutorial" by JerryAndrews
Date Wed, 29 Jan 2014 21:20:24 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Jmeter Wiki" for change notification.

The "DeveloperManual/VisualizerTutorial" page has been changed by JerryAndrews:
https://wiki.apache.org/jmeter/DeveloperManual/VisualizerTutorial?action=diff&rev1=2&rev2=3

  
  In some cases, you may not want to display the menu for the file textbox. In that case,
you can override the “init()” method. Here is the implementation for DistributionGraphVisualizer.
  
+  {{{
-  {{{1    /**
+ 1    /**
  2     * Initialize the GUI.
  3     */
  4     private void init()
@@ -54, +55 @@

  
  The second thing the init method does is create a border. If you want to increase or decrease
the border, change the four integer values. Each integer value represents pixels. If you want
your visualizer to have no border, skip lines 9 and 11. Line 15 calls “createGraphPanel,”
which is responsible for configuring and adding the DistributionGraph to the visualizer.
  
+  {{{
-  {{{1    private Component createGraphPanel()
+ 1    private Component createGraphPanel()
  2    {
  3        graphPanel = new JPanel();
  4        graphPanel.setBorder(BorderFactory.createBevelBorder(
@@ -67, +69 @@

  
  At line 6, the graph component is added to the graph panel. The constructor is where a new
instance of DistributionGraph is created.
  
+  {{{
-  {{{public DistributionGraphVisualizer()
+ public DistributionGraphVisualizer()
  {
      model = new SamplingStatCalculator("Distribution");
      graph = new DistributionGraph(model);
@@ -78, +81 @@

  
  The constructor of DistributionGraphVisualizer is responsible for creating the model and
the graph. Every time a new result is complete, the engine passes the result to all the listeners
by calling add(SampleResult res). The visualizer passes the new SampleResult to the model.
  
+  {{{
-  {{{1    public synchronized void add(SampleResult res)
+ 1    public synchronized void add(SampleResult res)
  2    {
  3        model.addSample(res);
  4        updateGui(model.getCurrentSample());
@@ -87, +91 @@

  
  In the case of the DistributionGraphVisualizer, the “add” method doesn't acutally update
the graph. Instead, it calls “updateGui” in line four.
  
+  {{{
-  {{{public synchronized void updateGui(Sample s)
+ public synchronized void updateGui(Sample s)
  {
      // We have received one more sample
      if (delay == counter) {
@@ -101, +106 @@

  
  Unlike GraphVisualizer, the distribution graph attempts to show how the results clump; therefore
the DistributionGraphVisualizer delays the update. The default delay is 10 sampleresults.
  
+  {{{
-  {{{1    public synchronized void updateGui()
+ 1    public synchronized void updateGui()
  2    {
  3        if (graph.getWidth() < 10){
  4            graph.setPreferredSize(new Dimension(getWidth() - 40, getHeight() - 160));
@@ -113, +119 @@

  
  Lines 3 to 4 are suppose to resize the graph, if the user resizes the window or drags the
divider. Line 6 updates the panel containing the graph. Line 7 triggers the update of the
DistributionGraph. Before we cover writing graphcs, there are couple of important methods
visualizer must implement.
  
+  {{{
-  {{{public String getLabelResource()
+ public String getLabelResource()
  {
      return "distribution_graph_title";
  }
@@ -121, +128 @@

  
  The label resource retrieves the name of the visualizer from the properties file. The file
is located in “core/org/apache/jmeter/resources”. It's best not to hardcode the name of
the visualizer. Message.properties file is organized alphabetically, so adding a new entry
is easy.
   
+  {{{
-  {{{public synchronized void clear()
+ public synchronized void clear()
  {
      this.graph.clear();
      model.clear();
@@ -131, +139 @@

  
  Every component in Jmeter should implement logic for “clear()” method. If this isn't
done, the component will not clear the UI or model when the user tries to clear the last results
and run a new test. If clear is not implemented, it can result in a memory leak.
  
+  {{{
-  {{{public JComponent getPrintableComponent() 
+ public JComponent getPrintableComponent() 
  {
      return this.graphPanel;
  }
@@ -143, +152 @@

  
  Visualizers should implement GraphListener. This is done to make it simpler to add new Sample
instances to listeners. As a general rule, if the a custom graph does not plot every single
sample, it does not need to implement the interface.
  
+  {{{
-  {{{public interface GraphListener
+ public interface GraphListener
  {
      public void updateGui(Sample s);
      public void updateGui();
@@ -160, +170 @@

  
  For those new to Swing and haven't written custom Jcomponents yet, I would suggest getting
a book on Swing and get a good feel for how Swing widgets work. This tutorial will not attempt
to explain basic Swing concepts and assumes the reader is already familiar with the Swing
API and MVC (Model View Controller) design pattern. From the constructor of DistributionGraphVisualizer,
we see a new instance of DistributionGraph is created with an instance of the model.
  
+  {{{
-  {{{public DistributionGraph(SamplingStatCalculator model)
+ public DistributionGraph(SamplingStatCalculator model)
  {
      this();
      setModel(model);
@@ -169, +180 @@

  
  The implementation of “setModel” method is straight forward.
  
+  {{{
-  {{{private void setModel(Object model)
+ private void setModel(Object model)
  {
      this.model = (SamplingStatCalculator) model;
      repaint();
@@ -178, +190 @@

  
  Notice the method calls “repaint” after it sets the model. If “repaint” isn't called,
it can cause the GUI to not draw the graph. Once the test starts, the graph would redraw,
so calling “repaint” isn't critical.
  
+  {{{
-  {{{public void paintComponent(Graphics g)
+ public void paintComponent(Graphics g)
  {
      super.paintComponent(g);
      final SamplingStatCalculator m = this.model;
@@ -191, +204 @@

  
  The other important aspect of updating the widget is placing the call to drawSample within
a synchronized block. If drawSample wasn't synchronized, Jmeter would throw a ConcurrentModificationException
at runtime. Depending on the test plan, there may be a dozen or more threads adding results
to the model. The synchronized block does not affect the accuracy of each individual request
and time measurement, but it does affect Jmeter's ability to generate large loads. As the
number of threads in a test plan increases, the likelihood a thread will have to wait until
the graph is done redrawing before starting a new request increases. Here is the implementation
of drawSample.
  
+  {{{
-  {{{private void drawSample(SamplingStatCalculator model, Graphics g)
+ private void drawSample(SamplingStatCalculator model, Graphics g)
  {
      width = getWidth();
      double height = (double)getHeight() - 1.0;

Mime
View raw message