1 11 package org.eclipse.swt.tools.internal; 12 13 import org.eclipse.swt.*; 14 import org.eclipse.swt.graphics.*; 15 import org.eclipse.swt.widgets.*; 16 import java.io.*; 17 18 25 public class Sleak { 26 Display display; 27 Shell shell; 28 List list; 29 Canvas canvas; 30 Button start, stop, check; 31 Text text; 32 Label label; 33 34 Object [] oldObjects = new Object [0]; 35 Error [] oldErrors = new Error [0]; 36 Object [] objects = new Object [0]; 37 Error [] errors = new Error [0]; 38 39 public static void main (String [] args) { 40 DeviceData data = new DeviceData(); 41 data.tracking = true; 42 Display display = new Display (data); 43 Sleak sleak = new Sleak (); 44 sleak.open (); 45 46 58 while (!sleak.shell.isDisposed ()) { 59 if (!display.readAndDispatch ()) display.sleep (); 60 } 61 display.dispose (); 62 } 63 64 void open () { 65 display = Display.getCurrent (); 66 shell = new Shell (display); 67 shell.setText ("S-Leak"); 68 list = new List (shell, SWT.BORDER | SWT.V_SCROLL); 69 list.addListener (SWT.Selection, new Listener () { 70 public void handleEvent (Event event) { 71 refreshObject (); 72 } 73 }); 74 text = new Text (shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); 75 canvas = new Canvas (shell, SWT.BORDER); 76 canvas.addListener (SWT.Paint, new Listener () { 77 public void handleEvent (Event event) { 78 paintCanvas (event); 79 } 80 }); 81 check = new Button (shell, SWT.CHECK); 82 check.setText ("Stack"); 83 check.addListener (SWT.Selection, new Listener () { 84 public void handleEvent (Event e) { 85 toggleStackTrace (); 86 } 87 }); 88 start = new Button (shell, SWT.PUSH); 89 start.setText ("Snap"); 90 start.addListener (SWT.Selection, new Listener () { 91 public void handleEvent (Event event) { 92 refreshAll (); 93 } 94 }); 95 stop = new Button (shell, SWT.PUSH); 96 stop.setText ("Diff"); 97 stop.addListener (SWT.Selection, new Listener () { 98 public void handleEvent (Event event) { 99 refreshDifference (); 100 } 101 }); 102 label = new Label (shell, SWT.BORDER); 103 label.setText ("0 object(s)"); 104 shell.addListener (SWT.Resize, new Listener () { 105 public void handleEvent (Event e) { 106 layout (); 107 } 108 }); 109 check.setSelection (false); 110 text.setVisible (false); 111 Point size = shell.getSize (); 112 shell.setSize (size.x / 2, size.y / 2); 113 shell.open (); 114 } 115 116 void refreshLabel () { 117 int colors = 0, cursors = 0, fonts = 0, gcs = 0, images = 0, regions = 0; 118 for (int i=0; i<objects.length; i++) { 119 Object object = objects [i]; 120 if (object instanceof Color) colors++; 121 if (object instanceof Cursor) cursors++; 122 if (object instanceof Font) fonts++; 123 if (object instanceof GC) gcs++; 124 if (object instanceof Image) images++; 125 if (object instanceof Region) regions++; 126 } 127 String string = ""; 128 if (colors != 0) string += colors + " Color(s)\n"; 129 if (cursors != 0) string += cursors + " Cursor(s)\n"; 130 if (fonts != 0) string += fonts + " Font(s)\n"; 131 if (gcs != 0) string += gcs + " GC(s)\n"; 132 if (images != 0) string += images + " Image(s)\n"; 133 if (regions != 0) string += regions + " Region(s)\n"; 134 if (string.length () != 0) { 135 string = string.substring (0, string.length () - 1); 136 } 137 label.setText (string); 138 } 139 140 void refreshDifference () { 141 DeviceData info = display.getDeviceData (); 142 if (!info.tracking) { 143 MessageBox dialog = new MessageBox (shell, SWT.ICON_WARNING | SWT.OK); 144 dialog.setText (shell.getText ()); 145 dialog.setMessage ("Warning: Device is not tracking resource allocation"); 146 dialog.open (); 147 } 148 Object [] newObjects = info.objects; 149 Error [] newErrors = info.errors; 150 Object [] diffObjects = new Object [newObjects.length]; 151 Error [] diffErrors = new Error [newErrors.length]; 152 int count = 0; 153 for (int i=0; i<newObjects.length; i++) { 154 int index = 0; 155 while (index < oldObjects.length) { 156 if (newObjects [i] == oldObjects [index]) break; 157 index++; 158 } 159 if (index == oldObjects.length) { 160 diffObjects [count] = newObjects [i]; 161 diffErrors [count] = newErrors [i]; 162 count++; 163 } 164 } 165 objects = new Object [count]; 166 errors = new Error [count]; 167 System.arraycopy (diffObjects, 0, objects, 0, count); 168 System.arraycopy (diffErrors, 0, errors, 0, count); 169 list.removeAll (); 170 text.setText (""); 171 canvas.redraw (); 172 for (int i=0; i<objects.length; i++) { 173 list.add (objectName (objects [i])); 174 } 175 refreshLabel (); 176 layout (); 177 } 178 179 String objectName (Object object) { 180 String string = object.toString (); 181 int index = string.lastIndexOf ('.'); 182 if (index == -1) return string; 183 return string.substring (index + 1, string.length ()); 184 } 185 186 void toggleStackTrace () { 187 refreshObject (); 188 layout (); 189 } 190 191 void paintCanvas (Event event) { 192 canvas.setCursor (null); 193 int index = list.getSelectionIndex (); 194 if (index == -1) return; 195 GC gc = event.gc; 196 Object object = objects [index]; 197 if (object instanceof Color) { 198 if (((Color)object).isDisposed ()) return; 199 gc.setBackground ((Color) object); 200 gc.fillRectangle (canvas.getClientArea()); 201 return; 202 } 203 if (object instanceof Cursor) { 204 if (((Cursor)object).isDisposed ()) return; 205 canvas.setCursor ((Cursor) object); 206 return; 207 } 208 if (object instanceof Font) { 209 if (((Font)object).isDisposed ()) return; 210 gc.setFont ((Font) object); 211 FontData [] array = gc.getFont ().getFontData (); 212 String string = ""; 213 String lf = text.getLineDelimiter (); 214 for (int i=0; i<array.length; i++) { 215 FontData data = array [i]; 216 String style = "NORMAL"; 217 int bits = data.getStyle (); 218 if (bits != 0) { 219 if ((bits & SWT.BOLD) != 0) style = "BOLD "; 220 if ((bits & SWT.ITALIC) != 0) style += "ITALIC"; 221 } 222 string += data.getName () + " " + data.getHeight () + " " + style + lf; 223 } 224 gc.drawString (string, 0, 0); 225 return; 226 } 227 if (object instanceof Image) { 232 if (((Image)object).isDisposed ()) return; 233 gc.drawImage ((Image) object, 0, 0); 234 return; 235 } 236 if (object instanceof Region) { 237 if (((Region)object).isDisposed ()) return; 238 String string = ((Region)object).getBounds().toString(); 239 gc.drawString (string, 0, 0); 240 return; 241 } 242 } 243 244 void refreshObject () { 245 int index = list.getSelectionIndex (); 246 if (index == -1) return; 247 if (check.getSelection ()) { 248 ByteArrayOutputStream stream = new ByteArrayOutputStream (); 249 PrintStream s = new PrintStream (stream); 250 errors [index].printStackTrace (s); 251 text.setText (stream.toString ()); 252 text.setVisible (true); 253 canvas.setVisible (false); 254 } else { 255 canvas.setVisible (true); 256 text.setVisible (false); 257 canvas.redraw (); 258 } 259 } 260 261 void refreshAll () { 262 oldObjects = new Object [0]; 263 oldErrors = new Error [0]; 264 refreshDifference (); 265 oldObjects = objects; 266 oldErrors = errors; 267 } 268 269 void layout () { 270 Rectangle rect = shell.getClientArea (); 271 int width = 0; 272 String [] items = list.getItems (); 273 GC gc = new GC (list); 274 for (int i=0; i<objects.length; i++) { 275 width = Math.max (width, gc.stringExtent (items [i]).x); 276 } 277 gc.dispose (); 278 Point size1 = start.computeSize (SWT.DEFAULT, SWT.DEFAULT); 279 Point size2 = stop.computeSize (SWT.DEFAULT, SWT.DEFAULT); 280 Point size3 = check.computeSize (SWT.DEFAULT, SWT.DEFAULT); 281 Point size4 = label.computeSize (SWT.DEFAULT, SWT.DEFAULT); 282 width = Math.max (size1.x, Math.max (size2.x, Math.max (size3.x, width))); 283 width = Math.max (64, Math.max (size4.x, list.computeSize (width, SWT.DEFAULT).x)); 284 start.setBounds (0, 0, width, size1.y); 285 stop.setBounds (0, size1.y, width, size2.y); 286 check.setBounds (0, size1.y + size2.y, width, size3.y); 287 label.setBounds (0, rect.height - size4.y, width, size4.y); 288 int height = size1.y + size2.y + size3.y; 289 list.setBounds (0, height, width, rect.height - height - size4.y); 290 text.setBounds (width, 0, rect.width - width, rect.height); 291 canvas.setBounds (width, 0, rect.width - width, rect.height); 292 } 293 294 } 295 | Popular Tags |