1 package org.eclipse.tips.manual.tests; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.PrintStream; 5 6 /* 7 * Copyright (c) 2000, 2018 IBM Corp. All rights reserved. 8 * This file is made available under the terms of the Common Public License v1.0 9 * which accompanies this distribution, and is available at 10 * http://www.eclipse.org/legal/cpl-v10.html 11 */ 12 import org.eclipse.swt.SWT; 13 import org.eclipse.swt.graphics.Color; 14 import org.eclipse.swt.graphics.Cursor; 15 import org.eclipse.swt.graphics.DeviceData; 16 import org.eclipse.swt.graphics.Font; 17 import org.eclipse.swt.graphics.FontData; 18 import org.eclipse.swt.graphics.GC; 19 import org.eclipse.swt.graphics.Image; 20 import org.eclipse.swt.graphics.Point; 21 import org.eclipse.swt.graphics.Rectangle; 22 import org.eclipse.swt.graphics.Region; 23 import org.eclipse.swt.widgets.Button; 24 import org.eclipse.swt.widgets.Canvas; 25 import org.eclipse.swt.widgets.Display; 26 import org.eclipse.swt.widgets.Event; 27 import org.eclipse.swt.widgets.Label; 28 import org.eclipse.swt.widgets.List; 29 import org.eclipse.swt.widgets.MessageBox; 30 import org.eclipse.swt.widgets.Shell; 31 import org.eclipse.swt.widgets.Text; 32 33 public class Sleak { 34 Display display; 35 Shell shell; 36 List list; 37 Canvas canvas; 38 Button start, stop, check; 39 Text text; 40 Label label; 41 42 Object[] oldObjects = new Object[0]; 43 Error[] oldErrors = new Error[0]; 44 Object[] objects = new Object[0]; 45 Error[] errors = new Error[0]; 46 open()47 public void open() { 48 display = Display.getCurrent(); 49 shell = new Shell(display); 50 shell.setText("S-Leak"); 51 list = new List(shell, SWT.BORDER | SWT.V_SCROLL); 52 list.addListener(SWT.Selection, event -> refreshObject()); 53 text = new Text(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); 54 canvas = new Canvas(shell, SWT.BORDER); 55 canvas.addListener(SWT.Paint, event -> paintCanvas(event)); 56 check = new Button(shell, SWT.CHECK); 57 check.setText("Stack"); 58 check.addListener(SWT.Selection, e -> toggleStackTrace()); 59 start = new Button(shell, SWT.PUSH); 60 start.setText("Snap"); 61 start.addListener(SWT.Selection, event -> refreshAll()); 62 stop = new Button(shell, SWT.PUSH); 63 stop.setText("Diff"); 64 stop.addListener(SWT.Selection, event -> refreshDifference()); 65 label = new Label(shell, SWT.BORDER); 66 label.setText("0 object(s)"); 67 shell.addListener(SWT.Resize, e -> layout()); 68 check.setSelection(false); 69 text.setVisible(false); 70 Point size = shell.getSize(); 71 shell.setSize(size.x / 2, size.y / 2); 72 shell.open(); 73 refreshAll(); 74 } 75 refreshLabel()76 void refreshLabel() { 77 int colors = 0, cursors = 0, fonts = 0, gcs = 0, images = 0; 78 for (Object object : objects) { 79 if (object instanceof Color) { 80 colors++; 81 } 82 if (object instanceof Cursor) { 83 cursors++; 84 } 85 if (object instanceof Font) { 86 fonts++; 87 } 88 if (object instanceof GC) { 89 gcs++; 90 } 91 if (object instanceof Image) { 92 images++; 93 } 94 } 95 String string = ""; 96 if (colors != 0) { 97 string += colors + " Color(s)\n"; 98 } 99 if (cursors != 0) { 100 string += cursors + " Cursor(s)\n"; 101 } 102 if (fonts != 0) { 103 string += fonts + " Font(s)\n"; 104 } 105 if (gcs != 0) { 106 string += gcs + " GC(s)\n"; 107 } 108 if (images != 0) { 109 string += images + " Image(s)\n"; 110 } 111 /* Currently regions are not counted. */ 112 // if (regions != 0) string += regions + " Region(s)\n"; 113 if (string.length() != 0) { 114 string = string.substring(0, string.length() - 1); 115 } 116 label.setText(string); 117 } 118 refreshDifference()119 void refreshDifference() { 120 DeviceData info = display.getDeviceData(); 121 if (!info.tracking) { 122 MessageBox dialog = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK); 123 dialog.setText(shell.getText()); 124 dialog.setMessage("Warning: Device is not tracking resource allocation"); 125 dialog.open(); 126 } 127 Object[] newObjects = info.objects; 128 Error[] newErrors = info.errors; 129 Object[] diffObjects = new Object[newObjects.length]; 130 Error[] diffErrors = new Error[newErrors.length]; 131 int count = 0; 132 for (int i = 0; i < newObjects.length; i++) { 133 int index = 0; 134 while (index < oldObjects.length) { 135 if (newObjects[i] == oldObjects[index]) { 136 break; 137 } 138 index++; 139 } 140 if (index == oldObjects.length) { 141 diffObjects[count] = newObjects[i]; 142 diffErrors[count] = newErrors[i]; 143 count++; 144 } 145 } 146 objects = new Object[count]; 147 errors = new Error[count]; 148 System.arraycopy(diffObjects, 0, objects, 0, count); 149 System.arraycopy(diffErrors, 0, errors, 0, count); 150 list.removeAll(); 151 text.setText(""); 152 canvas.redraw(); 153 for (Object object : objects) { 154 list.add(objectName(object)); 155 } 156 refreshLabel(); 157 layout(); 158 } 159 objectName(Object object)160 String objectName(Object object) { 161 String string = object.toString(); 162 int index = string.lastIndexOf('.'); 163 if (index == -1) { 164 return string; 165 } 166 return string.substring(index + 1, string.length()); 167 } 168 toggleStackTrace()169 void toggleStackTrace() { 170 refreshObject(); 171 layout(); 172 } 173 paintCanvas(Event event)174 void paintCanvas(Event event) { 175 canvas.setCursor(null); 176 int index = list.getSelectionIndex(); 177 if (index == -1) { 178 return; 179 } 180 GC gc = event.gc; 181 Object object = objects[index]; 182 if (object instanceof Color) { 183 if (((Color) object).isDisposed()) { 184 return; 185 } 186 gc.setBackground((Color) object); 187 gc.fillRectangle(canvas.getClientArea()); 188 return; 189 } 190 if (object instanceof Cursor) { 191 if (((Cursor) object).isDisposed()) { 192 return; 193 } 194 canvas.setCursor((Cursor) object); 195 return; 196 } 197 if (object instanceof Font) { 198 if (((Font) object).isDisposed()) { 199 return; 200 } 201 gc.setFont((Font) object); 202 FontData[] array = gc.getFont().getFontData(); 203 String string = ""; 204 String lf = text.getLineDelimiter(); 205 for (FontData data : array) { 206 String style = "NORMAL"; 207 int bits = data.getStyle(); 208 if (bits != 0) { 209 if ((bits & SWT.BOLD) != 0) { 210 style = "BOLD "; 211 } 212 if ((bits & SWT.ITALIC) != 0) { 213 style += "ITALIC"; 214 } 215 } 216 string += data.getName() + " " + data.getHeight() + " " + style + lf; 217 } 218 gc.drawString(string, 0, 0); 219 return; 220 } 221 // NOTHING TO DRAW FOR GC 222 // if (object instanceof GC) { 223 // return; 224 // } 225 if (object instanceof Image) { 226 if (((Image) object).isDisposed()) { 227 return; 228 } 229 gc.drawImage((Image) object, 0, 0); 230 return; 231 } 232 if (object instanceof Region) { 233 if (((Region) object).isDisposed()) { 234 return; 235 } 236 String string = ((Region) object).getBounds().toString(); 237 gc.drawString(string, 0, 0); 238 return; 239 } 240 } 241 refreshObject()242 void refreshObject() { 243 int index = list.getSelectionIndex(); 244 if (index == -1) { 245 return; 246 } 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 refreshAll()261 void refreshAll() { 262 oldObjects = new Object[0]; 263 oldErrors = new Error[0]; 264 refreshDifference(); 265 oldObjects = objects; 266 oldErrors = errors; 267 } 268 layout()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 main(String[] args)294 public static void main(String[] args) { 295 Display display = new Display(); 296 Sleak sleak = new Sleak(); 297 sleak.open(); 298 while (!sleak.shell.isDisposed()) { 299 if (!display.readAndDispatch()) { 300 display.sleep(); 301 } 302 } 303 display.dispose(); 304 } 305 306 } 307