Coverage Report - net.wotonomy.ui.swing.ReferenceInspector
 
Classes in this File Line Coverage Branch Coverage Complexity
ReferenceInspector
0% 
0% 
2
 
 1  
 /*
 2  
 Wotonomy: OpenStep design patterns for pure Java applications.
 3  
 Copyright (C) 2001 Intersect Software Corporation
 4  
 
 5  
 This library is free software; you can redistribute it and/or
 6  
 modify it under the terms of the GNU Lesser General Public
 7  
 License as published by the Free Software Foundation; either
 8  
 version 2.1 of the License, or (at your option) any later version.
 9  
 
 10  
 This library is distributed in the hope that it will be useful,
 11  
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
 Lesser General Public License for more details.
 14  
 
 15  
 You should have received a copy of the GNU Lesser General Public
 16  
 License along with this library; if not, see http://www.gnu.org
 17  
 */
 18  
 
 19  
 package net.wotonomy.ui.swing;
 20  
 
 21  
 import java.awt.BorderLayout;
 22  
 import java.awt.Dimension;
 23  
 import java.awt.Insets;
 24  
 import java.awt.event.ActionEvent;
 25  
 import java.awt.event.ActionListener;
 26  
 import java.awt.event.MouseEvent;
 27  
 import java.awt.event.MouseListener;
 28  
 import java.lang.ref.ReferenceQueue;
 29  
 import java.lang.ref.WeakReference;
 30  
 
 31  
 import javax.swing.JFrame;
 32  
 import javax.swing.JLabel;
 33  
 import javax.swing.JPanel;
 34  
 import javax.swing.JScrollPane;
 35  
 import javax.swing.JTable;
 36  
 import javax.swing.border.EmptyBorder;
 37  
 import javax.swing.table.TableColumn;
 38  
 
 39  
 import net.wotonomy.foundation.NSArray;
 40  
 import net.wotonomy.ui.EOAssociation;
 41  
 import net.wotonomy.ui.EODisplayGroup;
 42  
 import net.wotonomy.ui.swing.components.ButtonPanel;
 43  
 import net.wotonomy.ui.swing.util.WindowUtilities;
 44  
 
 45  
 /**
 46  
 * ReferenceInspector tracks objects until they are garbage collected.
 47  
 * Use it to track objects that you suspect are not being GCed.
 48  
 * ReferenceInspector retains only weak references to the objects that
 49  
 * it tracks, so when those weak references cannot be resolved, the
 50  
 * object has been garbage collected.  Note that under some GC 
 51  
 * implementations, adding a weak reference to an object will delay
 52  
 * garbage collection for that object.
 53  
 *
 54  
 * @author michael@mpowers.net
 55  
 * @version $Revision: 904 $
 56  
 */
 57  
 
 58  0
 public class ReferenceInspector
 59  
     implements MouseListener, ActionListener
 60  
 {
 61  
     protected JTable table;
 62  
     protected JLabel memoryLabel;
 63  
     
 64  
     static protected EODisplayGroup displayGroup;
 65  
     static protected JFrame window;
 66  
 
 67  
     /* Reference queue for cleared WeakKeys */
 68  0
     private static ReferenceQueue queue = new ReferenceQueue();
 69  
     
 70  
     // key command to copy contents to clipboard
 71  
     static public final String COPY = "COPY";
 72  
 
 73  
 /**
 74  
 * Launches a new ReferenceInspector if one does not already exist.
 75  
 */
 76  0
     public ReferenceInspector()
 77  0
     {
 78  0
         if ( window == null )
 79  
         {
 80  0
             table = new JTable();
 81  0
             memoryLabel = new JLabel();            
 82  
     
 83  0
             displayGroup = new EODisplayGroup();
 84  
             
 85  
             TableColumn column;
 86  
             TableColumnAssociation assoc;
 87  
             
 88  0
             column = new TableColumn();
 89  0
             column.setHeaderValue( "Object" );
 90  
     
 91  0
             assoc = new TableColumnAssociation( column );
 92  0
             assoc.bindAspect( EOAssociation.ValueAspect, displayGroup, "" );
 93  0
             assoc.setTable( table );
 94  0
             assoc.establishConnection();
 95  
             
 96  0
             column = new TableColumn();
 97  0
             column.setHeaderValue( "Address" );
 98  0
             column.setMaxWidth( 100 );
 99  
     
 100  0
             assoc = new TableColumnAssociation( column );
 101  0
             assoc.bindAspect( EOAssociation.ValueAspect, displayGroup, "identityHashCode" );
 102  0
             assoc.setTable( table );
 103  0
             assoc.establishConnection();
 104  
     
 105  0
             initLayout();
 106  
         }
 107  0
         window.show();
 108  0
     }
 109  
 
 110  
 /**
 111  
 * Adds the specified object to the ReferenceInspector, launching 
 112  
 * a new ReferenceInspector if one does not already exist.
 113  
 */
 114  
     public ReferenceInspector( Object anObject )
 115  
     {
 116  0
         this();
 117  0
         displayGroup.insertObjectAtIndex( new ExtendedWeakReference( anObject, queue ), 0 );
 118  0
         window.show();
 119  0
     }
 120  
     
 121  
     protected void initLayout()
 122  
     {
 123  0
         table.addMouseListener( this ); // listen for double-clicks
 124  
 
 125  0
         JPanel panel = new JPanel();
 126  0
         panel.setBorder( new EmptyBorder( new Insets( 10, 10, 10, 10 ) ) );
 127  0
         panel.setLayout( new BorderLayout( 10, 10 ) );
 128  
                 
 129  0
         JScrollPane scrollPane = new JScrollPane( table );
 130  0
         scrollPane.setPreferredSize( new Dimension( 500, 250 ) );
 131  0
         panel.add( scrollPane, BorderLayout.CENTER );
 132  
 
 133  0
         ButtonPanel buttonPanel = new ButtonPanel( new String[] { "Update" } );
 134  0
         buttonPanel.addActionListener( this );
 135  
 
 136  0
         JPanel bottomPanel = new JPanel();
 137  0
         bottomPanel.setLayout( new BorderLayout() );
 138  0
         bottomPanel.add( buttonPanel, BorderLayout.EAST );                
 139  0
         bottomPanel.add( memoryLabel, BorderLayout.CENTER );                
 140  0
         panel.add( bottomPanel, BorderLayout.SOUTH );
 141  
 
 142  0
         window = new JFrame();
 143  0
         window.setTitle( "Reference Inspector" );
 144  0
         window.getContentPane().add( panel );
 145  
 
 146  
 //        javax.swing.Timer timer = new javax.swing.Timer( 10000, this );
 147  
 //        timer.restart();
 148  
     
 149  0
         window.pack();
 150  0
         WindowUtilities.cascade( window );
 151  0
         window.show();
 152  0
     }
 153  
 
 154  
     /* Remove all invalidated entries from the map, that is, remove all entries
 155  
        whose keys have been discarded.  This method should be invoked once by
 156  
        each public mutator in this class.  We don't invoke this method in
 157  
        public accessors because that can lead to surprising
 158  
        ConcurrentModificationExceptions. */
 159  
     private static void processQueue() 
 160  
     {
 161  
 //        System.out.println( "ReferenceInspector.processQueue:");
 162  0
         synchronized ( displayGroup )
 163  
         {
 164  
             int idx;
 165  
             WeakReference rk;
 166  0
             while ((rk = (WeakReference)queue.poll()) != null) 
 167  
             {
 168  
 //                System.out.println( "ReferenceInspector.processQueue: removing object: " + rk );
 169  0
                 if ( rk != null )
 170  
                 {
 171  0
                     idx = displayGroup.displayedObjects().indexOfIdenticalObject( rk );                
 172  0
                     if ( idx != NSArray.NotFound )
 173  
                     {
 174  0
                         displayGroup.deleteObjectAtIndex( idx );
 175  0
                     }
 176  
                 }
 177  
             }
 178  0
             displayGroup.updateDisplayedObjects();
 179  0
         }
 180  0
     }
 181  
 
 182  
     // interface ActionListener
 183  
     
 184  
     public void actionPerformed( ActionEvent evt ) 
 185  
     {
 186  0
         Runtime runtime = Runtime.getRuntime();
 187  0
         runtime.gc();
 188  0
         processQueue();
 189  
         
 190  0
         long totalMemory = runtime.totalMemory() / 1024;
 191  0
         long freeMemory = runtime.freeMemory() / 1024;
 192  0
         memoryLabel.setText( 
 193  0
             Long.toString( totalMemory - freeMemory ) + "K / " +
 194  0
             Long.toString( totalMemory ) + "K" );
 195  0
     }
 196  
 
 197  
     // interface MouseListener
 198  
 
 199  
     /**
 200  
     * Double click to launch object inspector.
 201  
     */
 202  
 
 203  
     public void mouseClicked(MouseEvent e)
 204  
     {
 205  0
         if ( e.getSource() == table )
 206  
         {
 207  0
             if ( e.getClickCount() > 1 )
 208  
             {
 209  0
                 int row = table.rowAtPoint( e.getPoint() );
 210  0
                 int col = table.columnAtPoint( e.getPoint() );
 211  0
                 col = table.convertColumnIndexToModel( col );
 212  
 
 213  0
                 if ( row == -1 ) return;
 214  
                 
 215  0
                 if ( col == 0 ) // time
 216  
                 {
 217  
                 }
 218  
                 else
 219  
                 {
 220  
                 }
 221  
             }
 222  
         }
 223  0
     }
 224  
 
 225  0
     public void mouseReleased(MouseEvent e) {}
 226  0
     public void mousePressed(MouseEvent e) {}
 227  0
     public void mouseEntered(MouseEvent e) {}
 228  0
     public void mouseExited(MouseEvent e) {}
 229  
     
 230  
     public class ExtendedWeakReference extends WeakReference
 231  
     {
 232  
         public ExtendedWeakReference(Object referent, ReferenceQueue q) 
 233  0
         {
 234  0
             super( referent, q );
 235  0
         }
 236  
         
 237  
         public String toString() 
 238  
         {
 239  0
             if ( get() != null )
 240  
             {
 241  0
                 return get().toString();
 242  
             }
 243  0
             return null;
 244  
         }
 245  
         
 246  
         public String identityHashCode()
 247  
         {
 248  0
             if ( get() != null )
 249  
             {
 250  0
                 return Integer.toHexString( System.identityHashCode( get() ) );
 251  
             }
 252  0
             return null;
 253  
         }
 254  
         
 255  
     }
 256  
 }
 257  
     
 258  
 /*
 259  
  * $Log$
 260  
  * Revision 1.2  2006/02/18 23:19:05  cgruber
 261  
  * Update imports and maven dependencies.
 262  
  *
 263  
  * Revision 1.1  2006/02/16 13:22:22  cgruber
 264  
  * Check in all sources in eclipse-friendly maven-enabled packages.
 265  
  *
 266  
  * Revision 1.5  2003/08/06 23:07:52  chochos
 267  
  * general code cleanup (mostly, removing unused imports)
 268  
  *
 269  
  * Revision 1.4  2002/03/22 22:39:59  mpowers
 270  
  * Now shows the window even if previously hidden.
 271  
  *
 272  
  * Revision 1.3  2001/10/02 14:22:39  mpowers
 273  
  * Now shows used and heap memory usage.
 274  
  *
 275  
  * Revision 1.2  2001/07/10 16:39:32  mpowers
 276  
  * Removed printlns.
 277  
  *
 278  
  * Revision 1.1  2001/07/10 16:32:50  mpowers
 279  
  * Adding the reference inspector.
 280  
  *
 281  
  *
 282  
  */
 283