1 package org.objectweb.jac.samples.bench; 2 3 4 import java.awt.BorderLayout ; 5 import java.awt.Component ; 6 import java.awt.Container ; 7 import java.awt.Rectangle ; 8 import java.awt.event.ActionEvent ; 9 import java.awt.event.ActionListener ; 10 import java.awt.event.InputEvent ; 11 import java.awt.event.MouseAdapter ; 12 import java.awt.event.MouseEvent ; 13 import java.awt.event.WindowAdapter ; 14 import java.awt.event.WindowEvent ; 15 import java.io.FileNotFoundException ; 16 import java.io.FileReader ; 17 import java.io.IOException ; 18 import java.io.LineNumberReader ; 19 import java.util.Arrays ; 20 import java.util.Comparator ; 21 import java.util.Date ; 22 import java.util.Enumeration ; 23 import java.util.Hashtable ; 24 import java.util.Iterator ; 25 import java.util.Vector ; 26 import javax.swing.JButton ; 27 import javax.swing.JDialog ; 28 import javax.swing.JFrame ; 29 import javax.swing.JPanel ; 30 import javax.swing.JScrollPane ; 31 import javax.swing.JTabbedPane ; 32 import javax.swing.JTable ; 33 import javax.swing.JTextField ; 34 import javax.swing.JToolBar ; 35 import javax.swing.JTree ; 36 import javax.swing.ListSelectionModel ; 37 import javax.swing.event.ListSelectionEvent ; 38 import javax.swing.event.ListSelectionListener ; 39 import javax.swing.event.TableModelEvent ; 40 import javax.swing.event.TableModelListener ; 41 import javax.swing.table.AbstractTableModel ; 42 import javax.swing.table.JTableHeader ; 43 import javax.swing.table.TableColumnModel ; 44 import javax.swing.table.TableModel ; 45 import javax.swing.tree.DefaultTreeCellRenderer ; 46 import javax.swing.tree.DefaultTreeModel ; 47 import javax.swing.tree.TreeNode ; 48 49 50 public class Visualize implements ListSelectionListener { 51 public static void main(String args[]) throws FileNotFoundException ,IOException { 52 Visualize v = new Visualize(); 53 v.init(args[0]); 54 } 55 56 DefaultTreeModel treeModel; 57 Model tableModel; 58 TableSorter sorter; 59 ListSelectionModel selectionModel; 60 MethodNode root = new MethodNode("<root>"); 61 JFrame window; 62 JDialog searchDialog; 63 JTable table; 64 int totalTime = 0; 65 66 69 void init(String filename) throws FileNotFoundException , IOException { 70 window = new JFrame ("profiler data : "+filename); 71 searchDialog = new SearchDialog(); 72 73 LineNumberReader reader = new LineNumberReader (new FileReader (filename)); 74 String line = reader.readLine(); tableModel = new Model (); 76 buildTree(reader); 77 treeModel = new DefaultTreeModel (root); 78 79 sorter = new TableSorter(tableModel); 80 table = new JTable (sorter); 81 sorter.addMouseListenerToHeaderInTable(table); 82 83 JTree tree = new JTree (treeModel); 84 tree.setRootVisible(false); 85 tree.setCellRenderer(new TreeNodeRenderer()); 86 87 selectionModel = table.getSelectionModel(); 88 selectionModel.addListSelectionListener(this); 89 table.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 90 91 JTabbedPane tabs = new JTabbedPane (); 92 tabs.addTab("Methods",new JScrollPane (table)); 93 tabs.addTab("Tree",new JScrollPane (tree)); 94 95 JToolBar toolBar = new JToolBar (); 96 JButton searchButton = new JButton ("Search"); 97 searchButton.addActionListener( 98 new ActionListener () { 99 public void actionPerformed(ActionEvent event) { 100 searchDialog.show(); 101 searchDialog.toFront(); 102 } 103 } 104 ); 105 toolBar.add(searchButton); 106 107 108 window.getContentPane().add(toolBar,BorderLayout.NORTH); 109 110 window.getContentPane().add(tabs); 111 window.addWindowListener ( new WindowAdapter () { 112 public void windowClosing( WindowEvent e ) { 113 System.out.println("Bye bye."); 114 System.exit(0); 115 } 116 } 117 ); 118 window.pack(); 119 window.setBounds(new Rectangle (0,0,500,500)); 120 window.show(); 121 } 122 123 void buildTree(LineNumberReader reader) 124 throws IOException 125 { 126 String line; 127 while ((line=reader.readLine())!=null) { 130 Entry entry = parseLine(line); 131 MethodNode calleeNode = getNode(entry.callee); 132 calleeNode.count += entry.count; 133 calleeNode.time += entry.time; 134 totalTime += entry.time; 135 if (entry.caller!=null) { 136 MethodNode callerNode = getNode(entry.caller); 137 callerNode.add(new MethodNode(entry.callee,entry.count,entry.time)); 138 } 139 } 140 141 Iterator i = nodes.values().iterator(); 144 while (i.hasNext()) { 145 MethodNode parent = (MethodNode)i.next(); 146 parent.sortChildren(); 147 Iterator children = parent.getChildren().iterator(); 148 while (children.hasNext()) { 149 MethodNode child = (MethodNode)children.next(); 150 MethodNode node = getNode(child.methodName); 151 child.setChildren(node.getChildren()); 152 } 153 } 154 155 } 156 157 Hashtable nodes = new Hashtable (); 158 159 162 MethodNode getNode(String name) { 163 MethodNode result = (MethodNode)nodes.get(name); 164 if (result==null) { 165 result = new MethodNode(name); 166 tableModel.addEntry(result); 167 nodes.put(name,result); 168 } 169 return result; 170 } 171 172 static Entry parseLine(String line) { 173 try { 174 Entry result = new Entry(); 175 int a=0,b; 176 b = line.indexOf(" "); 177 result.count = Integer.parseInt(line.substring(a,b)); 178 179 a=b+1; 180 b = line.indexOf(" ",a); 181 result.callee = line.substring(a,b); 182 183 a=b+1; 184 if (line.charAt(a)=='<') { 185 b = line.indexOf(">",a); 186 result.caller = null; 187 b++; 188 } else { 189 b = line.indexOf(" ",a); 190 result.caller = line.substring(a,b); 191 } 192 193 a=b+1; 194 result.time = Integer.parseInt(line.substring(a)); 195 196 return result; 197 } catch (Exception e) { 198 System.err.println("Could not parse line: "+line); 199 e.printStackTrace(); 200 return null; 201 } 202 } 203 204 205 207 public void valueChanged(ListSelectionEvent event) { 208 if (event.getValueIsAdjusting()) 209 return; 210 211 ListSelectionModel lsm = (ListSelectionModel )event.getSource(); 212 213 boolean isAdjusting = event.getValueIsAdjusting(); 214 215 if (!isAdjusting) { 216 root = new MethodNode("<root>"); 217 if (!lsm.isSelectionEmpty()) { 218 for (int i=lsm.getMinSelectionIndex(); i<=lsm.getMaxSelectionIndex(); i++) { 219 root.add(sorter.getEntry(i)); 220 } 221 } 222 treeModel.setRoot(root); 223 } 224 } 225 226 229 230 class SearchDialog extends JDialog { 231 JTextField text = new JTextField (); 232 int current = -1; 233 public SearchDialog() { 234 super(window,"Search"); 235 Container content = getContentPane(); 236 content.add(text); 237 JPanel buttonPanel = new JPanel (); 238 JButton nextButton = new JButton ("Next"); 239 nextButton.addActionListener( 240 new ActionListener () { 241 public void actionPerformed(ActionEvent event) { 242 current++; 243 while (current<sorter.getRowCount()) { 244 MethodNode entry = sorter.getEntry(current); 245 if (entry.methodName.indexOf(text.getText())!=-1) { 246 selectionModel.setSelectionInterval(current,current); 247 Rectangle rect = table.getCellRect(current,1,true); 248 table.scrollRectToVisible(rect); 249 return; 250 } 251 current++; 252 } 253 current = -1; 254 } 255 } 256 ); 257 buttonPanel.add(nextButton); 258 259 JButton closeButton = new JButton ("Close"); 260 closeButton.addActionListener( 261 new ActionListener () { 262 public void actionPerformed(ActionEvent event) { 263 searchDialog.hide(); 264 } 265 } 266 ); 267 buttonPanel.add(closeButton); 268 269 content.add(buttonPanel,BorderLayout.SOUTH); 270 pack(); 271 } 272 } 273 274 class Model extends AbstractTableModel implements TableModel { 275 Vector entries = new Vector (); 276 277 public void addEntry(MethodNode entry) { 278 entries.add(entry); 279 } 280 281 public MethodNode getEntry(int row) { 282 return (MethodNode)entries.get(row); 283 } 284 285 public int getRowCount() 287 { 288 return entries.size(); 289 } 290 291 public int getColumnCount() 292 { 293 return 3; 294 } 295 296 public String getColumnName(int col) 297 { 298 return new String [] {"Method","Count","Time", "%"} [col]; 299 } 300 301 public Class getColumnClass(int col) 302 { 303 return new Class [] {String .class,Integer .class,Integer .class,Integer .class} [col]; 304 } 305 306 public boolean isCellEditable(int param1, int param2) 307 { 308 return false; 309 } 310 311 public Object getValueAt(int row, int col) 312 { 313 MethodNode entry = getEntry(row); 314 switch(col) { 315 case 0: 316 return entry.methodName; 317 case 1: 318 return new Integer (entry.count); 319 case 2: 320 return new Integer (entry.time); 321 case 3: 322 return new Integer (100*entry.time/totalTime); 323 default: 324 return null; 325 } 326 } 327 328 public void setValueAt(Object param1, int row, int col) 329 { 330 } 332 333 } 334 335 } 336 337 class Entry { 338 public String callee; 339 public String caller; 340 public int count; 341 public int time; 342 } 343 344 class MethodNode implements TreeNode { 345 public String methodName; 346 public int count = 0; 347 public int time = 0; 348 public int percentage = 0; 349 350 Vector children = new Vector (); 351 TreeNode parent; 352 353 public MethodNode(String name) { 354 methodName = name; 355 } 356 public MethodNode(String name, int count, int time) { 357 methodName = name; 358 this.count = count; 359 this.time = time; 360 } 361 362 public Enumeration children() { 363 return children.elements(); 364 } 365 public Vector getChildren() { 366 return children; 367 } 368 public void setChildren(Vector children) { 369 this.children = children; 370 } 371 public void sortChildren() { 372 Object [] array = children.toArray(); 373 Arrays.sort(array, new NodeComparator()); 374 for (int i=0; i<array.length; i++) { 375 MethodNode child = (MethodNode)array[i]; 376 if (time!=0) { 377 child.percentage = 100*child.time/time; 378 } else { 379 child.percentage = 0; 380 } 381 children.set(i,child); 382 } 383 } 384 public boolean getAllowsChildren() { 385 return true; 386 } 387 public TreeNode getChildAt(int i) { 388 return (TreeNode )children.get(i); 389 } 390 public int getChildCount() { 391 return children.size(); 392 } 393 public int getIndex(TreeNode node) { 394 return children.indexOf(node); 395 } 396 public TreeNode getParent() { 397 return parent; 398 } 399 public boolean isLeaf() { 400 return getChildCount()==0; 401 } 402 public void add(TreeNode node) { 403 children.add(node); 404 } 405 } 406 407 class TreeNodeRenderer extends DefaultTreeCellRenderer { 408 409 public TreeNodeRenderer() {} 410 411 public Component getTreeCellRendererComponent( JTree tree, 412 Object value, 413 boolean sel, 414 boolean expanded, 415 boolean leaf, 416 int row, 417 boolean hasFocus) { 418 this.hasFocus = hasFocus; 419 MethodNode node=(MethodNode)value; 420 setText( 421 "["+node.time+"/"+node.percentage+"%/"+node.count+"] "+ 422 node.methodName.substring(0,node.methodName.indexOf(")")+1)); 423 424 if(sel) 425 setForeground(getTextSelectionColor()); 426 else 427 setForeground(getTextNonSelectionColor()); 428 if (!tree.isEnabled()) { 430 setEnabled(false); 431 if (leaf) { 432 setDisabledIcon(getLeafIcon()); 433 } else if (expanded) { 434 setDisabledIcon(getOpenIcon()); 435 } else { 436 setDisabledIcon(getClosedIcon()); 437 } 438 } 439 else { 440 setEnabled(true); 441 } 442 setComponentOrientation(tree.getComponentOrientation()); 443 selected = sel; 444 445 return this; 446 } 447 } 448 449 class NodeComparator implements Comparator { 450 public int compare(Object a, Object b) { 451 return ((MethodNode)b).time - ((MethodNode)a).time; 452 } 453 public boolean equals(Object comparator) { 454 return comparator instanceof NodeComparator; 455 } 456 } 457 458 class TableMap extends AbstractTableModel 459 implements TableModelListener 460 { 461 protected TableModel model; 462 463 public TableModel getModel() { 464 return model; 465 } 466 467 public void setModel(TableModel model) { 468 this.model = model; 469 model.addTableModelListener(this); 470 } 471 472 475 public Object getValueAt(int aRow, int aColumn) { 476 return model.getValueAt(aRow, aColumn); 477 } 478 479 public void setValueAt(Object aValue, int aRow, int aColumn) { 480 model.setValueAt(aValue, aRow, aColumn); 481 } 482 483 public int getRowCount() { 484 return (model == null) ? 0 : model.getRowCount(); 485 } 486 487 public int getColumnCount() { 488 return (model == null) ? 0 : model.getColumnCount(); 489 } 490 491 public String getColumnName(int aColumn) { 492 return model.getColumnName(aColumn); 493 } 494 495 public Class getColumnClass(int aColumn) { 496 return model.getColumnClass(aColumn); 497 } 498 499 public boolean isCellEditable(int row, int column) { 500 return model.isCellEditable(row, column); 501 } 502 public void tableChanged(TableModelEvent e) { 507 fireTableChanged(e); 508 } 509 } 510 511 class TableSorter extends TableMap { 512 int indexes[]; 513 Vector sortingColumns = new Vector (); 514 boolean ascending = true; 515 int compares; 516 517 public TableSorter() { 518 indexes = new int[0]; } 520 521 public TableSorter(TableModel model) { 522 setModel(model); 523 } 524 525 public void setModel(TableModel model) { 526 super.setModel(model); 527 reallocateIndexes(); 528 } 529 530 public int compareRowsByColumn(int row1, int row2, int column) { 531 Class type = model.getColumnClass(column); 532 TableModel data = model; 533 534 536 Object o1 = data.getValueAt(row1, column); 537 Object o2 = data.getValueAt(row2, column); 538 539 if (o1 == null && o2 == null) { 541 return 0; 542 } else if (o1 == null) { return -1; 544 } else if (o2 == null) { 545 return 1; 546 } 547 548 556 557 if (type.getSuperclass() == java.lang.Number .class) { 558 Number n1 = (Number )data.getValueAt(row1, column); 559 double d1 = n1.doubleValue(); 560 Number n2 = (Number )data.getValueAt(row2, column); 561 double d2 = n2.doubleValue(); 562 563 if (d1 < d2) { 564 return -1; 565 } else if (d1 > d2) { 566 return 1; 567 } else { 568 return 0; 569 } 570 } else if (type == java.util.Date .class) { 571 Date d1 = (Date )data.getValueAt(row1, column); 572 long n1 = d1.getTime(); 573 Date d2 = (Date )data.getValueAt(row2, column); 574 long n2 = d2.getTime(); 575 576 if (n1 < n2) { 577 return -1; 578 } else if (n1 > n2) { 579 return 1; 580 } else { 581 return 0; 582 } 583 } else if (type == String .class) { 584 String s1 = (String )data.getValueAt(row1, column); 585 String s2 = (String )data.getValueAt(row2, column); 586 int result = s1.compareTo(s2); 587 588 if (result < 0) { 589 return -1; 590 } else if (result > 0) { 591 return 1; 592 } else { 593 return 0; 594 } 595 } else if (type == Boolean .class) { 596 Boolean bool1 = (Boolean )data.getValueAt(row1, column); 597 boolean b1 = bool1.booleanValue(); 598 Boolean bool2 = (Boolean )data.getValueAt(row2, column); 599 boolean b2 = bool2.booleanValue(); 600 601 if (b1 == b2) { 602 return 0; 603 } else if (b1) { return 1; 605 } else { 606 return -1; 607 } 608 } else { 609 Object v1 = data.getValueAt(row1, column); 610 String s1 = v1.toString(); 611 Object v2 = data.getValueAt(row2, column); 612 String s2 = v2.toString(); 613 int result = s1.compareTo(s2); 614 615 if (result < 0) { 616 return -1; 617 } else if (result > 0) { 618 return 1; 619 } else { 620 return 0; 621 } 622 } 623 } 624 625 public int compare(int row1, int row2) { 626 compares++; 627 for (int level = 0; level < sortingColumns.size(); level++) { 628 Integer column = (Integer )sortingColumns.elementAt(level); 629 int result = compareRowsByColumn(row1, row2, column.intValue()); 630 if (result != 0) { 631 return ascending ? result : -result; 632 } 633 } 634 return 0; 635 } 636 637 public void reallocateIndexes() { 638 int rowCount = model.getRowCount(); 639 640 indexes = new int[rowCount]; 643 644 for (int row = 0; row < rowCount; row++) { 646 indexes[row] = row; 647 } 648 } 649 650 public void tableChanged(TableModelEvent e) { 651 reallocateIndexes(); 653 654 super.tableChanged(e); 655 } 656 657 public void checkModel() { 658 if (indexes.length != model.getRowCount()) { 659 System.err.println("Sorter not informed of a change in model."); 660 } 661 } 662 663 public void sort(Object sender) { 664 checkModel(); 665 666 compares = 0; 667 shuttlesort((int[])indexes.clone(), indexes, 0, indexes.length); 670 } 672 673 public void n2sort() { 674 for (int i = 0; i < getRowCount(); i++) { 675 for (int j = i+1; j < getRowCount(); j++) { 676 if (compare(indexes[i], indexes[j]) == -1) { 677 swap(i, j); 678 } 679 } 680 } 681 } 682 683 public void shuttlesort(int from[], int to[], int low, int high) { 691 if (high - low < 2) { 692 return; 693 } 694 int middle = (low + high)/2; 695 shuttlesort(to, from, low, middle); 696 shuttlesort(to, from, middle, high); 697 698 int p = low; 699 int q = middle; 700 701 715 716 if (high - low >= 4 && compare(from[middle-1], from[middle]) <= 0) { 717 for (int i = low; i < high; i++) { 718 to[i] = from[i]; 719 } 720 return; 721 } 722 723 725 for (int i = low; i < high; i++) { 726 if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) { 727 to[i] = from[p++]; 728 } 729 else { 730 to[i] = from[q++]; 731 } 732 } 733 } 734 735 public void swap(int i, int j) { 736 int tmp = indexes[i]; 737 indexes[i] = indexes[j]; 738 indexes[j] = tmp; 739 } 740 741 744 public Object getValueAt(int aRow, int aColumn) { 745 checkModel(); 746 return model.getValueAt(indexes[aRow], aColumn); 747 } 748 749 public MethodNode getEntry(int row) { 750 return ((Visualize.Model)model).getEntry(indexes[row]); 751 } 752 753 public void setValueAt(Object aValue, int aRow, int aColumn) { 754 checkModel(); 755 model.setValueAt(aValue, indexes[aRow], aColumn); 756 } 757 758 public void sortByColumn(int column) { 759 sortByColumn(column, true); 760 } 761 762 public void sortByColumn(int column, boolean ascending) { 763 this.ascending = ascending; 764 sortingColumns.removeAllElements(); 765 sortingColumns.addElement(new Integer (column)); 766 sort(this); 767 super.tableChanged(new TableModelEvent (this)); 768 } 769 770 public void addMouseListenerToHeaderInTable(JTable table) { 774 final TableSorter sorter = this; 775 final JTable tableView = table; 776 tableView.setColumnSelectionAllowed(false); 777 MouseAdapter listMouseListener = new MouseAdapter () { 778 public void mouseClicked(MouseEvent e) { 779 TableColumnModel columnModel = tableView.getColumnModel(); 780 int viewColumn = columnModel.getColumnIndexAtX(e.getX()); 781 int column = tableView.convertColumnIndexToModel(viewColumn); 782 if (e.getClickCount() == 1 && column != -1) { 783 int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK; 785 boolean ascending = (shiftPressed == 0); 786 sorter.sortByColumn(column, ascending); 787 } 788 } 789 }; 790 JTableHeader th = tableView.getTableHeader(); 791 th.addMouseListener(listMouseListener); 792 } 793 } 794 | Popular Tags |