1 19 20 package org.openide.explorer.view; 21 22 import java.awt.BorderLayout ; 23 import java.awt.event.ActionEvent ; 24 import java.awt.event.ActionListener ; 25 import java.beans.PropertyChangeListener ; 26 import java.lang.ref.WeakReference ; 27 import java.util.ArrayList ; 28 import java.util.List ; 29 import javax.swing.JComponent ; 30 import javax.swing.JPanel ; 31 import javax.swing.SwingUtilities ; 32 import javax.swing.Timer ; 33 import junit.textui.TestRunner; 34 import org.netbeans.junit.NbTestCase; 35 import org.netbeans.junit.NbTestSuite; 36 import org.openide.explorer.ExplorerManager; 37 import org.openide.explorer.ExplorerPanel; 38 import org.openide.loaders.DataFilter; 39 import org.openide.loaders.RepositoryNodeFactory; 40 import org.openide.nodes.AbstractNode; 41 import org.openide.nodes.Children; 42 import org.openide.nodes.Node; 43 import org.openide.nodes.PropertySupport; 44 import org.openide.nodes.Sheet; 45 import org.openide.windows.TopComponent; 46 47 48 52 public class TTVTest extends NbTestCase { 53 54 private TreeTableView ttv; 55 private ExplorerPanel ep; 56 private NodeHolderProperty[] props; 57 private NodeStructure nodeStructure; 58 private WeakReference [] weakNodes; 59 private int result; 60 61 public TTVTest(String testName) { 62 super(testName); 63 } 64 65 public static void main(java.lang.String [] args) { 66 TestRunner.run(new NbTestSuite(TTVTest.class)); 67 } 69 70 public void testNodesReleasing () { 71 SwingUtilities.invokeLater(new Runnable () { 72 public void run() { 73 fillAndShowTTV(); 74 Timer timer = new Timer (5000, new ActionListener () { 78 public void actionPerformed (ActionEvent evt) { 79 TTVTest.this.cleanAndCheckTTV(); 80 } 81 }); 82 timer.setRepeats(false); 83 timer.start(); 84 } 85 }); 86 synchronized (this) { 88 try { 89 wait(); 90 } catch (InterruptedException exc) { 91 fail("Test was interrupted somehow."); 92 } 93 } 94 if (result > 0) { 96 System.out.println("OK, TreeTableView released nodes after " + result + " GC cycles"); 97 } else { 98 System.out.println("TreeTableView leaks memory! Nodes were not freed even after 10 GC cycles."); 99 fail("TreeTableView leaks memory! Nodes were not freed even after 10 GC cycles."); 100 } 101 } 102 103 private void fillAndShowTTV () { 104 ttv = createTTV(); 105 props = createProperties(); 106 nodeStructure = createNodeStructure(props); 107 setupTTV(nodeStructure.rootNode, props); 108 showTTV(); 109 weakNodes = createWeakNodes(nodeStructure.childrenNodes); 110 } 111 112 private int repaintCount = 0; 113 private Timer repaintTimer; 114 115 private void cleanAndCheckTTV () { 116 replaceTTVContent(); 118 nodeStructure = null; 119 props = null; 120 repaintTimer = new Timer (1000, new ActionListener () { 123 public void actionPerformed (ActionEvent evt) { 124 if (repaintCount < 10) { 125 ep.invalidate(); 126 ep.validate(); 127 ep.repaint(); 128 repaintCount++; 129 SwingUtilities.invokeLater(new Runnable () { 133 public void run() { 134 System.gc(); 135 if (checkWeakRefs(weakNodes)) { 136 repaintTimer.stop(); 137 result = repaintCount; 138 synchronized (TTVTest.this) { 140 TTVTest.this.notifyAll(); 141 } 142 } else { 143 System.out.println("Refs still alive after GC #" + repaintCount); 144 } 145 } 146 }); 147 } else { 148 repaintTimer.stop(); 149 result = -1; 150 synchronized (TTVTest.this) { 152 TTVTest.this.notifyAll(); 153 } 154 } 155 } 156 }); 157 repaintTimer.start(); 158 } 159 160 private boolean checkWeakRefs (WeakReference [] weakNodes) { 161 for (int j = 0; j < weakNodes.length; j++) { 162 if (weakNodes[j].get() != null) { 163 return false; 164 } 165 } 166 return true; 167 } 168 169 private TreeTableView createTTV () { 170 return new TreeTableView(); 171 } 172 173 private static NodeHolderProperty[] createProperties () { 174 return new NodeHolderProperty[] { 175 new NodeHolderProperty("boolean_prop", Boolean.TYPE, "boolean prop.", "Short desc") { public Object getValue () { 178 return Boolean.TRUE; 179 } 180 }, 181 new NodeHolderProperty("string_prop", String .class, "string prop", "Test string prop") { public Object getValue () { 184 return "value"; } 186 } 187 }; 188 } 189 190 private static final class NodeStructure { 191 public Node[] childrenNodes; 192 public Node rootNode; 193 } 194 195 198 private static abstract class NodeHolderProperty extends PropertySupport.ReadOnly { 199 private Node heldNode; 200 201 NodeHolderProperty (String propName, Class propClass, String name, String hint) { 202 super(propName, propClass, name, hint); 203 } 204 205 public void holdNode (Node node) { 206 heldNode = node; 207 } 208 209 } 210 211 private NodeStructure createNodeStructure (NodeHolderProperty[] props) { 212 NodeStructure createdData = new NodeStructure(); 213 createdData.childrenNodes = new Node[100]; 214 Children rootChildren = new Children.Array(); 215 createdData.rootNode = new AbstractNode(rootChildren); 216 createdData.rootNode.setDisplayName("Root test node"); 217 for (int i = 0; i < 100; i++) { 218 Node newNode = new TestNode(); 219 newNode.setDisplayName("node #" + i); 220 createdData.childrenNodes[i] = newNode; 221 } 222 rootChildren.add(createdData.childrenNodes); 223 return createdData; 224 } 225 226 private static final class TestNode extends AbstractNode { 227 228 TestNode () { 229 super(Children.LEAF); 230 } 231 232 public Sheet createSheet () { 233 Sheet s = Sheet.createDefault (); 234 Sheet.Set ss = s.get (Sheet.PROPERTIES); 235 NodeHolderProperty[] props = createProperties(); 236 ss.put(props); 237 wireNode(this, props); 238 return s; 239 } 240 241 } 243 private static void wireNode (Node node, NodeHolderProperty[] props) { 244 for (int i = 0; i < props.length; i++) { 245 props[i].holdNode(node); 246 } 247 } 248 249 private void setupTTV (Node rootNode, Node.Property[] props) { 250 ttv.setProperties(props); 251 ttv.setRootVisible(false); 252 253 ExplorerManager em = new ExplorerManager(); 254 em.setRootContext(rootNode); 255 ep = new ExplorerPanel(em); 256 ep.add(ttv, BorderLayout.CENTER); 257 } 258 259 private void replaceTTVContent () { 260 Children children = new Children.Array(); 261 children.add(new Node[] { new TestNode() }); 262 263 ep.getExplorerManager().setRootContext(new AbstractNode (children)); 264 } 265 266 private void showTTV () { 267 ep.open(); 268 } 269 270 private WeakReference [] createWeakNodes (Node[] nodes) { 271 WeakReference [] weakNodes = new WeakReference [nodes.length]; 272 for (int i = 0; i < nodes.length; i++) { 273 weakNodes[i] = new WeakReference (nodes[i]); 274 } 275 return weakNodes; 276 } 277 278 279 } 280 | Popular Tags |