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: package org.apache.jmeter.visualizers;
018:
019: import java.util.HashMap;
020: import java.awt.BorderLayout;
021: import java.awt.Color;
022: import java.awt.Dimension;
023: import java.awt.Font;
024: import java.awt.FlowLayout;
025:
026: import javax.swing.ImageIcon;
027: import javax.swing.JLabel;
028: import javax.swing.JPanel;
029: import javax.swing.JScrollPane;
030: import javax.swing.JSplitPane;
031: import javax.swing.JTree;
032: import javax.swing.tree.DefaultMutableTreeNode;
033: import javax.swing.tree.DefaultTreeModel;
034: import javax.swing.tree.TreeSelectionModel;
035: import javax.swing.event.TreeSelectionListener;
036: import javax.swing.event.TreeSelectionEvent;
037:
038: import org.apache.jmeter.samplers.Clearable;
039: import org.apache.jmeter.samplers.SampleResult;
040: import org.apache.jmeter.util.JMeterUtils;
041:
042: public class MonitorPerformancePanel extends JSplitPane implements
043: TreeSelectionListener, MonitorListener, Clearable {
044:
045: private JScrollPane TREEPANE;
046:
047: private JPanel GRAPHPANEL;
048:
049: private JTree SERVERTREE;
050:
051: private DefaultTreeModel TREEMODEL;
052:
053: private MonitorGraph GRAPH;
054:
055: private DefaultMutableTreeNode ROOTNODE;
056:
057: private HashMap SERVERMAP;
058:
059: private MonitorAccumModel MODEL;
060:
061: private SampleResult ROOTSAMPLE;
062:
063: public static final String LEGEND_HEALTH = JMeterUtils
064: .getResString("monitor_legend_health"); //$NON-NLS-1$
065:
066: public static final String LEGEND_LOAD = JMeterUtils
067: .getResString("monitor_legend_load"); //$NON-NLS-1$
068:
069: public static final String LEGEND_MEM = JMeterUtils
070: .getResString("monitor_legend_memory_per"); //$NON-NLS-1$
071:
072: public static final String LEGEND_THREAD = JMeterUtils
073: .getResString("monitor_legend_thread_per"); //$NON-NLS-1$
074:
075: public static final ImageIcon LEGEND_HEALTH_ICON = JMeterUtils
076: .getImage("monitor-green-legend.gif"); //$NON-NLS-1$
077:
078: public static final ImageIcon LEGEND_LOAD_ICON = JMeterUtils
079: .getImage("monitor-blue-legend.gif"); //$NON-NLS-1$
080:
081: public static final ImageIcon LEGEND_MEM_ICON = JMeterUtils
082: .getImage("monitor-orange-legend.gif"); //$NON-NLS-1$
083:
084: public static final ImageIcon LEGEND_THREAD_ICON = JMeterUtils
085: .getImage("monitor-red-legend.gif"); //$NON-NLS-1$
086:
087: public static final String GRID_LABEL_TOP = JMeterUtils
088: .getResString("monitor_label_left_top"); //$NON-NLS-1$
089:
090: public static final String GRID_LABEL_MIDDLE = JMeterUtils
091: .getResString("monitor_label_left_middle"); //$NON-NLS-1$
092:
093: public static final String GRID_LABEL_BOTTOM = JMeterUtils
094: .getResString("monitor_label_left_bottom"); //$NON-NLS-1$
095:
096: public static final String GRID_LABEL_HEALTHY = JMeterUtils
097: .getResString("monitor_label_right_healthy"); //$NON-NLS-1$
098:
099: public static final String GRID_LABEL_ACTIVE = JMeterUtils
100: .getResString("monitor_label_right_active"); //$NON-NLS-1$
101:
102: public static final String GRID_LABEL_WARNING = JMeterUtils
103: .getResString("monitor_label_right_warning"); //$NON-NLS-1$
104:
105: public static final String GRID_LABEL_DEAD = JMeterUtils
106: .getResString("monitor_label_right_dead"); //$NON-NLS-1$
107:
108: public static final String PERF_TITLE = JMeterUtils
109: .getResString("monitor_performance_title"); //$NON-NLS-1$
110:
111: public static final String SERVER_TITLE = JMeterUtils
112: .getResString("monitor_performance_servers"); //$NON-NLS-1$
113:
114: protected Font plaintext = new Font("plain", Font.TRUETYPE_FONT, 10); //$NON-NLS-1$
115:
116: /**
117: *
118: * @deprecated Only for use in unit testing
119: */
120: public MonitorPerformancePanel() {
121: // log.warn("Only for use in unit testing");
122: }
123:
124: /**
125: *
126: */
127: public MonitorPerformancePanel(MonitorAccumModel model,
128: MonitorGraph graph) {
129: super ();
130: this .SERVERMAP = new HashMap();
131: this .MODEL = model;
132: this .MODEL.addListener(this );
133: this .GRAPH = graph;
134: init();
135: }
136:
137: /**
138: * init() will create all the necessary swing panels, labels and icons for
139: * the performance panel.
140: */
141: protected void init() {
142: ROOTSAMPLE = new SampleResult();
143: ROOTSAMPLE.setSampleLabel(SERVER_TITLE);
144: ROOTSAMPLE.setSuccessful(true);
145: ROOTNODE = new DefaultMutableTreeNode(ROOTSAMPLE);
146: TREEMODEL = new DefaultTreeModel(ROOTNODE);
147: SERVERTREE = new JTree(TREEMODEL);
148: SERVERTREE.getSelectionModel().setSelectionMode(
149: TreeSelectionModel.SINGLE_TREE_SELECTION);
150: SERVERTREE.addTreeSelectionListener(this );
151: SERVERTREE.setShowsRootHandles(true);
152: TREEPANE = new JScrollPane(SERVERTREE);
153: TREEPANE.setPreferredSize(new Dimension(150, 200));
154: this .add(TREEPANE, JSplitPane.LEFT);
155: this .setDividerLocation(0.18);
156:
157: JPanel right = new JPanel();
158: right.setLayout(new BorderLayout());
159: JLabel title = new JLabel(" " + PERF_TITLE);
160: title.setPreferredSize(new Dimension(200, 40));
161: GRAPHPANEL = new JPanel();
162: GRAPHPANEL.setLayout(new BorderLayout());
163: GRAPHPANEL.setMaximumSize(new Dimension(MODEL.getBufferSize(),
164: MODEL.getBufferSize()));
165: GRAPHPANEL.setBackground(Color.white);
166: GRAPHPANEL.add(GRAPH, BorderLayout.CENTER);
167: right.add(GRAPHPANEL, BorderLayout.CENTER);
168:
169: right.add(title, BorderLayout.NORTH);
170: right.add(createLegend(), BorderLayout.SOUTH);
171: right.add(createLeftGridLabels(), BorderLayout.WEST);
172: right.add(createRightGridLabels(), BorderLayout.EAST);
173: this .add(right, JSplitPane.RIGHT);
174: }
175:
176: /**
177: * Method will create the legends at the bottom of the performance tab
178: * explaining the meaning of each line.
179: *
180: * @return JPanel
181: */
182: public JPanel createLegend() {
183: Dimension lsize = new Dimension(130, 18);
184:
185: JPanel legend = new JPanel();
186: legend.setLayout(new FlowLayout());
187:
188: JLabel load = new JLabel(LEGEND_LOAD);
189: load.setFont(plaintext);
190: load.setPreferredSize(lsize);
191: load.setIcon(LEGEND_LOAD_ICON);
192: legend.add(load);
193:
194: JLabel mem = new JLabel(LEGEND_MEM);
195: mem.setFont(plaintext);
196: mem.setPreferredSize(lsize);
197: mem.setIcon(LEGEND_MEM_ICON);
198: legend.add(mem);
199:
200: JLabel thd = new JLabel(LEGEND_THREAD);
201: thd.setFont(plaintext);
202: thd.setPreferredSize(lsize);
203: thd.setIcon(LEGEND_THREAD_ICON);
204: legend.add(thd);
205:
206: JLabel health = new JLabel(LEGEND_HEALTH);
207: health.setFont(plaintext);
208: health.setPreferredSize(lsize);
209: health.setIcon(LEGEND_HEALTH_ICON);
210: legend.add(health);
211:
212: return legend;
213: }
214:
215: /**
216: * Method is responsible for creating the left grid labels.
217: *
218: * @return JPanel
219: */
220: public JPanel createLeftGridLabels() {
221: Dimension lsize = new Dimension(33, 20);
222: JPanel labels = new JPanel();
223: labels.setLayout(new BorderLayout());
224:
225: JLabel top = new JLabel(" " + GRID_LABEL_TOP);
226: top.setFont(plaintext);
227: top.setPreferredSize(lsize);
228: labels.add(top, BorderLayout.NORTH);
229:
230: JLabel mid = new JLabel(" " + GRID_LABEL_MIDDLE);
231: mid.setFont(plaintext);
232: mid.setPreferredSize(lsize);
233: labels.add(mid, BorderLayout.CENTER);
234:
235: JLabel bottom = new JLabel(" " + GRID_LABEL_BOTTOM);
236: bottom.setFont(plaintext);
237: bottom.setPreferredSize(lsize);
238: labels.add(bottom, BorderLayout.SOUTH);
239: return labels;
240: }
241:
242: /**
243: * Method is responsible for creating the grid labels on the right for
244: * "healthy" and "dead"
245: *
246: * @return JPanel
247: */
248: public JPanel createRightGridLabels() {
249: JPanel labels = new JPanel();
250: labels.setLayout(new BorderLayout());
251: labels.setPreferredSize(new Dimension(40,
252: GRAPHPANEL.getWidth() - 100));
253: Dimension lsize = new Dimension(40, 20);
254: JLabel h = new JLabel(GRID_LABEL_HEALTHY);
255: h.setFont(plaintext);
256: h.setPreferredSize(lsize);
257: labels.add(h, BorderLayout.NORTH);
258:
259: JLabel d = new JLabel(GRID_LABEL_DEAD);
260: d.setFont(plaintext);
261: d.setPreferredSize(lsize);
262: labels.add(d, BorderLayout.SOUTH);
263: return labels;
264: }
265:
266: /**
267: * MonitorAccumModel will call this method to notify the component data has
268: * changed.
269: */
270: public synchronized void addSample(MonitorModel model) {
271: if (!SERVERMAP.containsKey(model.getURL())) {
272: DefaultMutableTreeNode newnode = new DefaultMutableTreeNode(
273: model);
274: newnode.setAllowsChildren(false);
275: SERVERMAP.put(model.getURL(), newnode);
276: ROOTNODE.add(newnode);
277: this .TREEPANE.updateUI();
278: }
279: DefaultMutableTreeNode node = (DefaultMutableTreeNode) SERVERTREE
280: .getLastSelectedPathComponent();
281: if (node != null) {
282: Object usrobj = node.getUserObject();
283: if (usrobj instanceof MonitorModel) {
284: GRAPH.updateGui((MonitorModel) usrobj);
285: }
286: }
287: }
288:
289: /**
290: * When the user selects a different node in the tree, we get the selected
291: * node. From the node, we get the UserObject used to create the treenode in
292: * the constructor.
293: */
294: public void valueChanged(TreeSelectionEvent e) {
295: // we check to see if the lastSelectedPath is null
296: // after we clear, it would return null
297: if (SERVERTREE.getLastSelectedPathComponent() != null) {
298: DefaultMutableTreeNode node = (DefaultMutableTreeNode) SERVERTREE
299: .getLastSelectedPathComponent();
300: Object usrobj = node.getUserObject();
301: if (usrobj != null && usrobj instanceof MonitorModel) {
302: MonitorModel mo = (MonitorModel) usrobj;
303: GRAPH.updateGui(mo);
304: this .updateUI();
305: }
306: TREEPANE.updateUI();
307: }
308: }
309:
310: /**
311: * clear will remove all child nodes from the ROOTNODE, clear the HashMap,
312: * update the graph and jpanel for the server tree.
313: */
314: public void clearData() {
315: this.SERVERMAP.clear();
316: ROOTNODE.removeAllChildren();
317: SERVERTREE.updateUI();
318: GRAPH.clearData();
319: }
320: }
|