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