KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > samples > bench > Visualize


1 package org.objectweb.jac.samples.bench;
2
3
4 import java.awt.BorderLayout JavaDoc;
5 import java.awt.Component JavaDoc;
6 import java.awt.Container JavaDoc;
7 import java.awt.Rectangle JavaDoc;
8 import java.awt.event.ActionEvent JavaDoc;
9 import java.awt.event.ActionListener JavaDoc;
10 import java.awt.event.InputEvent JavaDoc;
11 import java.awt.event.MouseAdapter JavaDoc;
12 import java.awt.event.MouseEvent JavaDoc;
13 import java.awt.event.WindowAdapter JavaDoc;
14 import java.awt.event.WindowEvent JavaDoc;
15 import java.io.FileNotFoundException JavaDoc;
16 import java.io.FileReader JavaDoc;
17 import java.io.IOException JavaDoc;
18 import java.io.LineNumberReader JavaDoc;
19 import java.util.Arrays JavaDoc;
20 import java.util.Comparator JavaDoc;
21 import java.util.Date JavaDoc;
22 import java.util.Enumeration JavaDoc;
23 import java.util.Hashtable JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.Vector JavaDoc;
26 import javax.swing.JButton JavaDoc;
27 import javax.swing.JDialog JavaDoc;
28 import javax.swing.JFrame JavaDoc;
29 import javax.swing.JPanel JavaDoc;
30 import javax.swing.JScrollPane JavaDoc;
31 import javax.swing.JTabbedPane JavaDoc;
32 import javax.swing.JTable JavaDoc;
33 import javax.swing.JTextField JavaDoc;
34 import javax.swing.JToolBar JavaDoc;
35 import javax.swing.JTree JavaDoc;
36 import javax.swing.ListSelectionModel JavaDoc;
37 import javax.swing.event.ListSelectionEvent JavaDoc;
38 import javax.swing.event.ListSelectionListener JavaDoc;
39 import javax.swing.event.TableModelEvent JavaDoc;
40 import javax.swing.event.TableModelListener JavaDoc;
41 import javax.swing.table.AbstractTableModel JavaDoc;
42 import javax.swing.table.JTableHeader JavaDoc;
43 import javax.swing.table.TableColumnModel JavaDoc;
44 import javax.swing.table.TableModel JavaDoc;
45 import javax.swing.tree.DefaultTreeCellRenderer JavaDoc;
46 import javax.swing.tree.DefaultTreeModel JavaDoc;
47 import javax.swing.tree.TreeNode JavaDoc;
48
49
50 public class Visualize implements ListSelectionListener JavaDoc {
51    public static void main(String JavaDoc args[]) throws FileNotFoundException JavaDoc,IOException JavaDoc {
52       Visualize v = new Visualize();
53       v.init(args[0]);
54    }
55
56    DefaultTreeModel JavaDoc treeModel;
57    Model JavaDoc tableModel;
58    TableSorter sorter;
59    ListSelectionModel JavaDoc selectionModel;
60    MethodNode root = new MethodNode("<root>");
61    JFrame JavaDoc window;
62    JDialog JavaDoc searchDialog;
63    JTable JavaDoc table;
64    int totalTime = 0;
65
66    /**
67     * Build the window
68     */

69    void init(String JavaDoc filename) throws FileNotFoundException JavaDoc, IOException JavaDoc {
70       window = new JFrame JavaDoc("profiler data : "+filename);
71       searchDialog = new SearchDialog();
72
73       LineNumberReader JavaDoc reader = new LineNumberReader JavaDoc(new FileReader JavaDoc(filename));
74       String JavaDoc line = reader.readLine(); // skip first line
75
tableModel = new Model JavaDoc();
76       buildTree(reader);
77       treeModel = new DefaultTreeModel JavaDoc(root);
78
79       sorter = new TableSorter(tableModel);
80       table = new JTable JavaDoc(sorter);
81       sorter.addMouseListenerToHeaderInTable(table);
82
83       JTree JavaDoc tree = new JTree JavaDoc(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 JavaDoc tabs = new JTabbedPane JavaDoc();
92       tabs.addTab("Methods",new JScrollPane JavaDoc(table));
93       tabs.addTab("Tree",new JScrollPane JavaDoc(tree));
94
95       JToolBar JavaDoc toolBar = new JToolBar JavaDoc();
96       JButton JavaDoc searchButton = new JButton JavaDoc("Search");
97       searchButton.addActionListener(
98          new ActionListener JavaDoc() {
99                public void actionPerformed(ActionEvent JavaDoc 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 JavaDoc () {
112                public void windowClosing( WindowEvent JavaDoc e ) {
113                   System.out.println("Bye bye.");
114                   System.exit(0);
115                }
116             }
117          );
118       window.pack();
119       window.setBounds(new Rectangle JavaDoc(0,0,500,500));
120       window.show();
121    }
122
123    void buildTree(LineNumberReader JavaDoc reader)
124       throws IOException JavaDoc
125    {
126       String JavaDoc line;
127       // build a a node for each method, and compute its children and
128
// its total time and count
129
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       // for each child node previously build, compute its children
142
// and sort them according to their time.
143
Iterator JavaDoc i = nodes.values().iterator();
144       while (i.hasNext()) {
145          MethodNode parent = (MethodNode)i.next();
146          parent.sortChildren();
147          Iterator JavaDoc 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 JavaDoc nodes = new Hashtable JavaDoc();
158
159    /**
160     * Returns a node with a given name
161     */

162    MethodNode getNode(String JavaDoc 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 JavaDoc 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 JavaDoc e) {
198          System.err.println("Could not parse line: "+line);
199          e.printStackTrace();
200          return null;
201       }
202    }
203
204
205    // ListSelectionListener
206

207    public void valueChanged(ListSelectionEvent JavaDoc event) {
208       if (event.getValueIsAdjusting())
209          return;
210
211       ListSelectionModel JavaDoc lsm = (ListSelectionModel JavaDoc)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    /**
227     * Search dialog
228     */

229
230    class SearchDialog extends JDialog JavaDoc {
231       JTextField JavaDoc text = new JTextField JavaDoc();
232       int current = -1;
233       public SearchDialog() {
234          super(window,"Search");
235          Container JavaDoc content = getContentPane();
236          content.add(text);
237          JPanel JavaDoc buttonPanel = new JPanel JavaDoc();
238          JButton JavaDoc nextButton = new JButton JavaDoc("Next");
239          nextButton.addActionListener(
240             new ActionListener JavaDoc() {
241                   public void actionPerformed(ActionEvent JavaDoc 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 JavaDoc 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 JavaDoc closeButton = new JButton JavaDoc("Close");
260          closeButton.addActionListener(
261             new ActionListener JavaDoc() {
262                   public void actionPerformed(ActionEvent JavaDoc 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 JavaDoc implements TableModel JavaDoc {
275       Vector JavaDoc entries = new Vector JavaDoc();
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       // implementation of javax.swing.table.TableModel interface
286
public int getRowCount()
287       {
288          return entries.size();
289       }
290
291       public int getColumnCount()
292       {
293          return 3;
294       }
295
296       public String JavaDoc getColumnName(int col)
297       {
298          return new String JavaDoc[] {"Method","Count","Time", "%"} [col];
299       }
300
301       public Class JavaDoc getColumnClass(int col)
302       {
303          return new Class JavaDoc[] {String JavaDoc.class,Integer JavaDoc.class,Integer JavaDoc.class,Integer JavaDoc.class} [col];
304       }
305
306       public boolean isCellEditable(int param1, int param2)
307       {
308          return false;
309       }
310
311       public Object JavaDoc 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 JavaDoc(entry.count);
319             case 2:
320                return new Integer JavaDoc(entry.time);
321             case 3:
322                return new Integer JavaDoc(100*entry.time/totalTime);
323             default:
324                return null;
325          }
326       }
327
328       public void setValueAt(Object JavaDoc param1, int row, int col)
329       {
330          // TODO: implement this javax.swing.table.TableModel method
331
}
332
333    }
334
335 }
336
337 class Entry {
338    public String JavaDoc callee;
339    public String JavaDoc caller;
340    public int count;
341    public int time;
342 }
343
344 class MethodNode implements TreeNode JavaDoc {
345    public String JavaDoc methodName;
346    public int count = 0;
347    public int time = 0;
348    public int percentage = 0;
349
350    Vector JavaDoc children = new Vector JavaDoc();
351    TreeNode JavaDoc parent;
352
353    public MethodNode(String JavaDoc name) {
354       methodName = name;
355    }
356    public MethodNode(String JavaDoc name, int count, int time) {
357       methodName = name;
358       this.count = count;
359       this.time = time;
360    }
361
362    public Enumeration JavaDoc children() {
363       return children.elements();
364    }
365    public Vector JavaDoc getChildren() {
366       return children;
367    }
368    public void setChildren(Vector JavaDoc children) {
369       this.children = children;
370    }
371    public void sortChildren() {
372       Object JavaDoc[] 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 JavaDoc getChildAt(int i) {
388       return (TreeNode JavaDoc)children.get(i);
389    }
390    public int getChildCount() {
391       return children.size();
392    }
393    public int getIndex(TreeNode JavaDoc node) {
394       return children.indexOf(node);
395    }
396    public TreeNode JavaDoc getParent() {
397       return parent;
398    }
399    public boolean isLeaf() {
400       return getChildCount()==0;
401    }
402    public void add(TreeNode JavaDoc node) {
403       children.add(node);
404    }
405 }
406
407 class TreeNodeRenderer extends DefaultTreeCellRenderer JavaDoc {
408
409    public TreeNodeRenderer() {}
410    
411    public Component JavaDoc getTreeCellRendererComponent( JTree JavaDoc tree,
412                                                   Object JavaDoc 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       // There needs to be a way to specify disabled icons.
429
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 JavaDoc {
450    public int compare(Object JavaDoc a, Object JavaDoc b) {
451       return ((MethodNode)b).time - ((MethodNode)a).time;
452    }
453    public boolean equals(Object JavaDoc comparator) {
454       return comparator instanceof NodeComparator;
455    }
456 }
457
458 class TableMap extends AbstractTableModel JavaDoc
459    implements TableModelListener JavaDoc
460 {
461     protected TableModel JavaDoc model;
462
463     public TableModel JavaDoc getModel() {
464         return model;
465     }
466
467     public void setModel(TableModel JavaDoc model) {
468         this.model = model;
469         model.addTableModelListener(this);
470     }
471
472     // By default, implement TableModel by forwarding all messages
473
// to the model.
474

475     public Object JavaDoc getValueAt(int aRow, int aColumn) {
476         return model.getValueAt(aRow, aColumn);
477     }
478         
479     public void setValueAt(Object JavaDoc 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 JavaDoc getColumnName(int aColumn) {
492         return model.getColumnName(aColumn);
493     }
494
495     public Class JavaDoc 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 //
503
// Implementation of the TableModelListener interface,
504
//
505
// By default forward all events to all the listeners.
506
public void tableChanged(TableModelEvent JavaDoc e) {
507         fireTableChanged(e);
508     }
509 }
510
511 class TableSorter extends TableMap {
512     int indexes[];
513     Vector JavaDoc sortingColumns = new Vector JavaDoc();
514     boolean ascending = true;
515     int compares;
516
517     public TableSorter() {
518         indexes = new int[0]; // for consistency
519
}
520
521     public TableSorter(TableModel JavaDoc model) {
522         setModel(model);
523     }
524
525     public void setModel(TableModel JavaDoc model) {
526         super.setModel(model);
527         reallocateIndexes();
528     }
529
530     public int compareRowsByColumn(int row1, int row2, int column) {
531         Class JavaDoc type = model.getColumnClass(column);
532         TableModel JavaDoc data = model;
533
534         // Check for nulls.
535

536         Object JavaDoc o1 = data.getValueAt(row1, column);
537         Object JavaDoc o2 = data.getValueAt(row2, column);
538
539         // If both values are null, return 0.
540
if (o1 == null && o2 == null) {
541             return 0;
542         } else if (o1 == null) { // Define null less than everything.
543
return -1;
544         } else if (o2 == null) {
545             return 1;
546         }
547
548         /*
549          * We copy all returned values from the getValue call in case
550          * an optimised model is reusing one object to return many
551          * values. The Number subclasses in the JDK are immutable and
552          * so will not be used in this way but other subclasses of
553          * Number might want to do this to save space and avoid
554          * unnecessary heap allocation.
555          */

556
557         if (type.getSuperclass() == java.lang.Number JavaDoc.class) {
558             Number JavaDoc n1 = (Number JavaDoc)data.getValueAt(row1, column);
559             double d1 = n1.doubleValue();
560             Number JavaDoc n2 = (Number JavaDoc)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 JavaDoc.class) {
571             Date JavaDoc d1 = (Date JavaDoc)data.getValueAt(row1, column);
572             long n1 = d1.getTime();
573             Date JavaDoc d2 = (Date JavaDoc)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 JavaDoc.class) {
584             String JavaDoc s1 = (String JavaDoc)data.getValueAt(row1, column);
585             String JavaDoc s2 = (String JavaDoc)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 JavaDoc.class) {
596             Boolean JavaDoc bool1 = (Boolean JavaDoc)data.getValueAt(row1, column);
597             boolean b1 = bool1.booleanValue();
598             Boolean JavaDoc bool2 = (Boolean JavaDoc)data.getValueAt(row2, column);
599             boolean b2 = bool2.booleanValue();
600
601             if (b1 == b2) {
602                 return 0;
603             } else if (b1) { // Define false < true
604
return 1;
605             } else {
606                 return -1;
607             }
608         } else {
609             Object JavaDoc v1 = data.getValueAt(row1, column);
610             String JavaDoc s1 = v1.toString();
611             Object JavaDoc v2 = data.getValueAt(row2, column);
612             String JavaDoc 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 JavaDoc column = (Integer JavaDoc)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         // Set up a new array of indexes with the right number of elements
641
// for the new data model.
642
indexes = new int[rowCount];
643
644         // Initialise with the identity mapping.
645
for (int row = 0; row < rowCount; row++) {
646             indexes[row] = row;
647         }
648     }
649
650     public void tableChanged(TableModelEvent JavaDoc e) {
651         //System.out.println("Sorter: tableChanged");
652
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 JavaDoc sender) {
664         checkModel();
665
666         compares = 0;
667         // n2sort();
668
// qsort(0, indexes.length-1);
669
shuttlesort((int[])indexes.clone(), indexes, 0, indexes.length);
670         //System.out.println("Compares: "+compares);
671
}
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     // This is a home-grown implementation which we have not had time
684
// to research - it may perform poorly in some circumstances. It
685
// requires twice the space of an in-place algorithm and makes
686
// NlogN assigments shuttling the values between the two
687
// arrays. The number of compares appears to vary between N-1 and
688
// NlogN depending on the initial order but the main reason for
689
// using it here is that, unlike qsort, it is stable.
690
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         /* This is an optional short-cut; at each recursive call,
702         check to see if the elements in this subset are already
703         ordered. If so, no further comparisons are needed; the
704         sub-array can just be copied. The array must be copied rather
705         than assigned otherwise sister calls in the recursion might
706         get out of sinc. When the number of elements is three they
707         are partitioned so that the first set, [low, mid), has one
708         element and and the second, [mid, high), has two. We skip the
709         optimisation when the number of elements is three or less as
710         the first compare in the normal merge will produce the same
711         sequence of steps. This optimisation seems to be worthwhile
712         for partially ordered lists but some analysis is needed to
713         find out how the performance drops to Nlog(N) as the initial
714         order diminishes - it may drop very quickly. */

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         // A normal merge.
724

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     // The mapping only affects the contents of the data rows.
742
// Pass all requests to these rows through the mapping array: "indexes".
743

744     public Object JavaDoc 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 JavaDoc 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 JavaDoc(column));
766         sort(this);
767         super.tableChanged(new TableModelEvent JavaDoc(this));
768     }
769
770     // There is no-where else to put this.
771
// Add a mouse listener to the Table to trigger a table sort
772
// when a column heading is clicked in the JTable.
773
public void addMouseListenerToHeaderInTable(JTable JavaDoc table) {
774         final TableSorter sorter = this;
775         final JTable JavaDoc tableView = table;
776         tableView.setColumnSelectionAllowed(false);
777         MouseAdapter JavaDoc listMouseListener = new MouseAdapter JavaDoc() {
778             public void mouseClicked(MouseEvent JavaDoc e) {
779                 TableColumnModel JavaDoc columnModel = tableView.getColumnModel();
780                 int viewColumn = columnModel.getColumnIndexAtX(e.getX());
781                 int column = tableView.convertColumnIndexToModel(viewColumn);
782                 if (e.getClickCount() == 1 && column != -1) {
783                     //System.out.println("Sorting ...");
784
int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK;
785                     boolean ascending = (shiftPressed == 0);
786                     sorter.sortByColumn(column, ascending);
787                 }
788             }
789         };
790         JTableHeader JavaDoc th = tableView.getTableHeader();
791         th.addMouseListener(listMouseListener);
792     }
793 }
794
Popular Tags