001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.visualizers;
020:
021: import java.awt.BorderLayout;
022: import java.awt.Color;
023: import java.awt.Component;
024: import java.awt.Dimension;
025: import java.awt.Image;
026:
027: import javax.swing.BorderFactory;
028: import javax.swing.Box;
029: import javax.swing.JComponent;
030: import javax.swing.JLabel;
031: import javax.swing.JPanel;
032: import javax.swing.JTextField;
033: import javax.swing.border.BevelBorder;
034: import javax.swing.border.Border;
035: import javax.swing.border.EmptyBorder;
036:
037: import org.apache.jmeter.samplers.Clearable;
038: import org.apache.jmeter.samplers.SampleResult;
039: import org.apache.jmeter.util.JMeterUtils;
040: import org.apache.jmeter.visualizers.gui.AbstractVisualizer;
041:
042: /**
043: * This class implements the visualizer for displaying the distribution graph.
044: * Distribution graphs are useful for standard benchmarks and viewing the
045: * distribution of data points. Results tend to clump together.
046: *
047: * Created May 25, 2004
048: */
049: public class DistributionGraphVisualizer extends AbstractVisualizer
050: implements ImageVisualizer, GraphListener, Clearable {
051: SamplingStatCalculator model;
052:
053: private JPanel graphPanel = null;
054:
055: private DistributionGraph graph;
056:
057: private JTextField noteField;
058:
059: private int delay = 10;
060:
061: private int counter = 0;
062:
063: /**
064: * Constructor for the GraphVisualizer object.
065: */
066: public DistributionGraphVisualizer() {
067: model = new SamplingStatCalculator("Distribution");
068: graph = new DistributionGraph(model);
069: graph.setBackground(Color.white);
070: init();
071: }
072:
073: /**
074: * Gets the Image attribute of the GraphVisualizer object.
075: *
076: * @return the Image value
077: */
078: public Image getImage() {
079: Image result = graph.createImage(graph.getWidth(), graph
080: .getHeight());
081:
082: graph.paintComponent(result.getGraphics());
083:
084: return result;
085: }
086:
087: public synchronized void updateGui() {
088: if (graph.getWidth() < 10) {
089: graph.setPreferredSize(new Dimension(getWidth() - 40,
090: getHeight() - 160));
091: }
092: graphPanel.updateUI();
093: graph.repaint();
094: }
095:
096: public synchronized void updateGui(Sample s) {
097: // We have received one more sample
098: if (delay == counter) {
099: updateGui();
100: counter = 0;
101: } else {
102: counter++;
103: }
104: }
105:
106: public synchronized void add(SampleResult res) {
107: model.addSample(res);
108: updateGui(model.getCurrentSample());
109: }
110:
111: public String getLabelResource() {
112: return "distribution_graph_title"; // $NON-NLS-1$
113: }
114:
115: public synchronized void clearData() {
116: this .graph.clearData();
117: model.clear();
118: repaint();
119: }
120:
121: public String toString() {
122: return "Show the samples in a distribution graph";
123: }
124:
125: /**
126: * Initialize the GUI.
127: */
128: private void init() {
129: this .setLayout(new BorderLayout());
130:
131: // MAIN PANEL
132: Border margin = new EmptyBorder(10, 10, 5, 10);
133:
134: this .setBorder(margin);
135:
136: // Set up the graph with header, footer, Y axis and graph display
137: JPanel lgraphPanel = new JPanel(new BorderLayout());
138: lgraphPanel.add(createGraphPanel(), BorderLayout.CENTER);
139: lgraphPanel.add(createGraphInfoPanel(), BorderLayout.SOUTH);
140:
141: // Add the main panel and the graph
142: this .add(makeTitlePanel(), BorderLayout.NORTH);
143: this .add(lgraphPanel, BorderLayout.CENTER);
144: }
145:
146: // Methods used in creating the GUI
147:
148: /**
149: * Creates a scroll pane containing the actual graph of the results.
150: *
151: * @return a scroll pane containing the graph
152: */
153: private Component createGraphPanel() {
154: graphPanel = new JPanel();
155: graphPanel.setBorder(BorderFactory.createBevelBorder(
156: BevelBorder.LOWERED, Color.lightGray, Color.darkGray));
157: graphPanel.add(graph);
158: graphPanel.setBackground(Color.white);
159: return graphPanel;
160: }
161:
162: // /**
163: // * Creates one of the fields used to display the graph's current
164: // * values.
165: // *
166: // * @param color the color used to draw the value. By convention
167: // * this is the same color that is used to draw the
168: // * graph for this value and in the choose panel.
169: // * @param length the number of digits which the field should be
170: // * able to display
171: // *
172: // * @return a text field configured to display one of the
173: // * current graph values
174: // */
175: // private JTextField createInfoField(Color color, int length)
176: // {
177: // JTextField field = new JTextField(length);
178: // field.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
179: // field.setEditable(false);
180: // field.setForeground(color);
181: // field.setBackground(getBackground());
182: //
183: // // The text field should expand horizontally, but have
184: // // a fixed height
185: // field.setMaximumSize(new Dimension(
186: // field.getMaximumSize().width,
187: // field.getPreferredSize().height));
188: // return field;
189: // }
190:
191: /**
192: * Creates a label for one of the fields used to display the graph's current
193: * values. Neither the label created by this method or the
194: * <code>field</code> passed as a parameter is added to the GUI here.
195: *
196: * @param labelResourceName
197: * the name of the label resource. This is used to look up the
198: * label text using {@link JMeterUtils#getResString(String)}.
199: * @param field
200: * the field this label is being created for.
201: */
202: private JLabel createInfoLabel(String labelResourceName,
203: JTextField field) {
204: JLabel label = new JLabel(JMeterUtils
205: .getResString(labelResourceName));
206: label.setForeground(field.getForeground());
207: label.setLabelFor(field);
208: return label;
209: }
210:
211: /**
212: * Creates the information Panel at the bottom
213: *
214: * @return
215: */
216: private Box createGraphInfoPanel() {
217: Box graphInfoPanel = Box.createHorizontalBox();
218: this .noteField = new JTextField();
219: graphInfoPanel.add(this .createInfoLabel("distribution_note1",
220: this .noteField)); // $NON-NLS-1$
221: return graphInfoPanel;
222: }
223:
224: /**
225: * Method implements Printable, which is suppose to return the correct
226: * internal component. The Action class can then print or save the graphics
227: * to a file.
228: */
229: public JComponent getPrintableComponent() {
230: return this.graphPanel;
231: }
232:
233: }
|