KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jmeter > visualizers > gui > AbstractVisualizer


1 // $Header: /home/cvs/jakarta-jmeter/src/core/org/apache/jmeter/visualizers/gui/AbstractVisualizer.java,v 1.23.2.1 2004/10/13 00:33:32 sebb Exp $
2
/*
3  * Copyright 2000-2004 The Apache Software Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17 */

18
19 package org.apache.jmeter.visualizers.gui;
20
21 import java.awt.Component JavaDoc;
22 import java.awt.Container JavaDoc;
23 import java.util.Arrays JavaDoc;
24 import java.util.Collection JavaDoc;
25
26 import javax.swing.JCheckBox JavaDoc;
27 import javax.swing.JPopupMenu JavaDoc;
28 import javax.swing.event.ChangeEvent JavaDoc;
29 import javax.swing.event.ChangeListener JavaDoc;
30
31 import org.apache.jmeter.gui.AbstractJMeterGuiComponent;
32 import org.apache.jmeter.gui.UnsharedComponent;
33 import org.apache.jmeter.gui.util.FilePanel;
34 import org.apache.jmeter.gui.util.MenuFactory;
35 import org.apache.jmeter.reporters.AbstractListenerElement;
36 import org.apache.jmeter.reporters.ResultCollector;
37 import org.apache.jmeter.testelement.TestElement;
38 import org.apache.jmeter.util.JMeterUtils;
39 import org.apache.jmeter.visualizers.Visualizer;
40 import org.apache.jorphan.logging.LoggingManager;
41 import org.apache.log.Logger;
42
43 /**
44  * This is the base class for JMeter GUI components which can display test
45  * results in some way. It provides the following conveniences to developers:
46  * <ul>
47  * <li>Implements the
48  * {@link org.apache.jmeter.gui.JMeterGUIComponent JMeterGUIComponent}
49  * interface that allows your Gui visualizer to "plug-in" to the JMeter
50  * GUI environment. Provides implementations for the following methods:
51  * <ul>
52  * <li>{@link org.apache.jmeter.gui.JMeterGUIComponent#configure(TestElement) configure(TestElement)}.
53  * Any additional parameters of your Visualizer need to be handled by
54  * you.</li>
55  * <li>{@link org.apache.jmeter.gui.JMeterGUIComponent#createTestElement() createTestElement()}.
56  * For most purposes, the default
57  * {@link org.apache.jmeter.reporters.ResultCollector ResultCollector}
58  * created by this method is sufficient.</li>
59  * <li>{@link org.apache.jmeter.gui.JMeterGUIComponent#getMenuCategories getMenuCategories()}.
60  * To control where in the GUI your visualizer can be added.</li>
61  * <li>{@link org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement) modifyTestElement(TestElement)}.
62  * Again, additional parameters you require have to be handled by
63  * you.</li>
64  * <li>{@link org.apache.jmeter.gui.JMeterGUIComponent#createPopupMenu() createPopupMenu()}.</li>
65  * </ul></li>
66  * <li>Provides convenience methods to help you make a JMeter-compatible GUI:
67  * <ul>
68  * <li>{@link #makeTitlePanel()}. Returns a panel that includes the name
69  * of the component, and a FilePanel that allows users to control what
70  * file samples are logged to.</li>
71  * <li>{@link #getModel()} and {@link #setModel(ResultCollector)} methods
72  * for setting and getting the model class that handles the receiving
73  * and logging of sample results.</li>
74  * </ul></li>
75  * </ul>
76  * For most developers, making a new visualizer is primarly for the purpose of
77  * either calculating new statistics on the sample results that other
78  * visualizers don't calculate, or displaying the results visually in a new and
79  * interesting way. Making a new visualizer for either of these purposes is
80  * easy - just extend this class and implement the
81  * {@link org.apache.jmeter.visualizers.Visualizer#add(SampleResult) add(SampleResult)}
82  * method and display the results as you see fit. This AbstractVisualizer and
83  * the default {@link org.apache.jmeter.reporters.ResultCollector ResultCollector}
84  * handle logging and registering to receive SampleEvents for you - all you need
85  * to do is include the JPanel created by makeTitlePanel somewhere in your gui
86  * to allow users set the log file.
87  * <p>
88  * If you are doing more than that, you may need to extend
89  * {@link org.apache.jmeter.reporters.ResultCollector ResultCollector} as well
90  * and modify the {@link #configure(TestElement)},
91  * {@link #modifyTestElement(TestElement)}, and {@link #createTestElement()}
92  * methods to create and modify your alternate ResultCollector. For an example
93  * of this, see the
94  * {@link org.apache.jmeter.visualizers.MailerVisualizer MailerVisualizer}.
95  * <p>
96  *
97  * @version $Revision: 1.23.2.1 $
98  */

99 public abstract class AbstractVisualizer
100     extends AbstractJMeterGuiComponent
101     implements Visualizer, ChangeListener JavaDoc, UnsharedComponent
102 {
103     /** Logging. */
104     private static transient Logger log =LoggingManager.getLoggerForClass();
105
106     /** A panel allowing results to be saved. */
107     private FilePanel filePanel;
108     
109     /** A checkbox choosing whether or not only errors should be logged. */
110     private JCheckBox JavaDoc errorLogging;
111     
112     protected ResultCollector collector;
113
114     public AbstractVisualizer()
115     {
116         super();
117         
118         errorLogging =
119             new JCheckBox JavaDoc(JMeterUtils.getResString("log_errors_only"));
120
121         filePanel = new FilePanel(
122                 JMeterUtils.getResString("file_visualizer_output_file"),".jtl");
123         filePanel.addChangeListener(this);
124         filePanel.add(errorLogging);
125                 
126     }
127
128     /**
129      * Gets the checkbox which selects whether or not only errors should be
130      * logged. Subclasses don't normally need to worry about this checkbox,
131      * because it is automatically added to the GUI in
132      * {@link #makeTitlePanel()}, and the behavior is handled in this base
133      * class.
134      *
135      * @return the error logging checkbox
136      */

137     protected JCheckBox JavaDoc getErrorLoggingCheckbox()
138     {
139         return errorLogging;
140     }
141
142     /**
143      * Provides access to the ResultCollector model class for extending
144      * implementations. Using this method and setModel(ResultCollector) is
145      * only necessary if your visualizer requires a differently behaving
146      * ResultCollector. Using these methods will allow maximum reuse of the
147      * methods provided by AbstractVisualizer in this event.
148      */

149     protected ResultCollector getModel()
150     {
151         return collector;
152     }
153
154    /**
155     * Gets the file panel which allows the user to save results to a file.
156     * Subclasses don't normally need to worry about this panel, because it
157     * is automatically added to the GUI in {@link #makeTitlePanel()}, and the
158     * behavior is handled in this base class.
159     *
160     * @return the file panel allowing users to save results
161     */

162     protected Component JavaDoc getFilePanel()
163     {
164         return filePanel;
165     }
166
167     /**
168      * Sets the filename which results will be saved to. This will set the
169      * filename in the FilePanel. Subclasses don't normally need to call this
170      * method, because configuration of the FilePanel is handled in this base
171      * class.
172      *
173      * @param filename the new filename
174      *
175      * @see #getFilePanel()
176      */

177     public void setFile(String JavaDoc filename)
178     {
179         // TODO: Does this method need to be public? It isn't currently
180
// called outside of this class.
181
filePanel.setFilename(filename);
182     }
183
184     /**
185      * Gets the filename which has been entered in the FilePanel. Subclasses
186      * don't normally need to call this method, because configuration of the
187      * FilePanel is handled in this base class.
188      *
189      * @return the current filename
190      *
191      * @see #getFilePanel()
192      */

193     public String JavaDoc getFile()
194     {
195         // TODO: Does this method need to be public? It isn't currently
196
// called outside of this class.
197
return filePanel.getFilename();
198     }
199     
200     
201
202     /**
203      * When a user right-clicks on the component in the test tree, or
204      * selects the edit menu when the component is selected, the
205      * component will be asked to return a JPopupMenu that provides
206      * all the options available to the user from this component.
207      * <p>
208      * This implementation returns menu items appropriate for most
209      * visualizer components.
210      *
211      * @return a JPopupMenu appropriate for the component.
212      */

213     public JPopupMenu JavaDoc createPopupMenu()
214     {
215         return MenuFactory.getDefaultVisualizerMenu();
216     }
217
218     /**
219      * Invoked when the target of the listener has changed its state. This
220      * implementation assumes that the target is the FilePanel, and will
221      * update the result collector for the new filename.
222      *
223      * @param e the event that has occurred
224      */

225     public void stateChanged(ChangeEvent JavaDoc e)
226     {
227         log.info("getting new collector");
228         collector = (ResultCollector) createTestElement();
229         try
230         {
231             collector.loadExistingFile();
232         }
233         catch (Exception JavaDoc err)
234         {
235             log.debug("Error occurred while loading file", err);
236         }
237     }
238
239     /**
240      * This is the list of menu categories this gui component will be available
241      * under. This implementation returns
242      * {@link org.apache.jmeter.gui.util.MenuFactory#LISTENERS}, which
243      * is appropriate for most visualizer components.
244      *
245      * @return a Collection of Strings, where each element is one of the
246      * constants defined in MenuFactory
247      */

248     public Collection JavaDoc getMenuCategories()
249     {
250         return Arrays.asList(new String JavaDoc[] { MenuFactory.LISTENERS });
251     }
252
253     /* Implements JMeterGUIComponent.modifyTestElement(TestElement) */
254     public TestElement createTestElement()
255     {
256         if (collector == null)
257         {
258             collector = new ResultCollector();
259         }
260         modifyTestElement(collector);
261         return (TestElement) collector.clone();
262     }
263
264     /* Implements JMeterGUIComponent.modifyTestElement(TestElement) */
265     public void modifyTestElement(TestElement c)
266     {
267         configureTestElement((AbstractListenerElement) c);
268         if (c instanceof ResultCollector)
269         {
270             ResultCollector rc = (ResultCollector) c;
271             rc.setErrorLogging(errorLogging.isSelected());
272             rc.setFilename(getFile());
273             collector = rc;
274         }
275     }
276
277     /* Overrides AbstractJMeterGuiComponent.configure(TestElement) */
278     public void configure(TestElement el)
279     {
280         super.configure(el);
281         setFile(el.getPropertyAsString(ResultCollector.FILENAME));
282         ResultCollector rc = (ResultCollector) el;
283         errorLogging.setSelected(rc.isErrorLogging());
284     }
285
286     /**
287      * This provides a convenience for extenders when they implement the
288      * {@link org.apache.jmeter.gui.JMeterGUIComponent#createTestElement()} method. This method
289      * will set the name, gui class, and test class for the created Test
290      * Element. It should be called by every extending class when creating
291      * Test Elements, as that will best assure consistent behavior.
292      *
293      * @param mc the TestElement being created.
294      */

295     protected void configureTestElement(AbstractListenerElement mc)
296     {
297         // TODO: Should the method signature of this method be changed to
298
// match the super-implementation (using a TestElement parameter
299
// instead of AbstractListenerElement)? This would require an
300
// instanceof check before adding the listener (below), but would
301
// also make the behavior a bit more obvious for sub-classes -- the
302
// Java rules dealing with this situation aren't always intuitive,
303
// and a subclass may think it is calling this version of the method
304
// when it is really calling the superclass version instead.
305
super.configureTestElement(mc);
306         mc.setListener(this);
307     }
308     
309     /**
310      * Create a standard title section for JMeter components. This includes
311      * the title for the component and the Name Panel allowing the user to
312      * change the name for the component. The AbstractVisualizer also adds
313      * the FilePanel allowing the user to save the results, and the
314      * error logging checkbox, allowing the user to choose whether or not only
315      * errors should be logged.
316      * <p>
317      * This method is typically added to the top of the component at the
318      * beginning of the component's init method.
319      *
320      * @return a panel containing the component title, name panel, file panel,
321      * and error logging checkbox
322      */

323     protected Container JavaDoc makeTitlePanel()
324     {
325         Container JavaDoc panel = super.makeTitlePanel();
326         // Note: the file panel already includes the error logging checkbox,
327
// so we don't have to add it explicitly.
328
panel.add(getFilePanel());
329         return panel;
330     }
331
332     /**
333      * Provides extending classes the opportunity to set the ResultCollector
334      * model for the Visualizer. This is useful to allow maximum reuse of the
335      * methods from AbstractVisualizer.
336      * @param collector
337      */

338     protected void setModel(ResultCollector collector)
339     {
340         this.collector = collector;
341     }
342 }
Popular Tags