Lines 45-56
Link Here
|
45 |
package org.openide.explorer.view; |
45 |
package org.openide.explorer.view; |
46 |
|
46 |
|
47 |
import java.awt.BorderLayout; |
47 |
import java.awt.BorderLayout; |
|
|
48 |
import java.awt.EventQueue; |
48 |
import java.awt.GraphicsEnvironment; |
49 |
import java.awt.GraphicsEnvironment; |
49 |
import java.beans.PropertyVetoException; |
50 |
import java.beans.PropertyVetoException; |
|
|
51 |
import java.io.IOException; |
50 |
import java.lang.ref.WeakReference; |
52 |
import java.lang.ref.WeakReference; |
51 |
import java.lang.reflect.InvocationTargetException; |
53 |
import java.lang.reflect.InvocationTargetException; |
52 |
import java.util.ArrayList; |
54 |
import java.util.ArrayList; |
53 |
import java.util.Arrays; |
55 |
import java.util.Arrays; |
|
|
56 |
import java.util.Collection; |
57 |
import java.util.Collections; |
54 |
import java.util.List; |
58 |
import java.util.List; |
55 |
import javax.swing.JFrame; |
59 |
import javax.swing.JFrame; |
56 |
import javax.swing.JPanel; |
60 |
import javax.swing.JPanel; |
Lines 61-67
Link Here
|
61 |
import junit.framework.Test; |
65 |
import junit.framework.Test; |
62 |
import junit.framework.TestSuite; |
66 |
import junit.framework.TestSuite; |
63 |
import org.netbeans.junit.NbTestCase; |
67 |
import org.netbeans.junit.NbTestCase; |
64 |
import org.netbeans.junit.RandomlyFails; |
|
|
65 |
import org.openide.explorer.ExplorerManager; |
68 |
import org.openide.explorer.ExplorerManager; |
66 |
import org.openide.nodes.AbstractNode; |
69 |
import org.openide.nodes.AbstractNode; |
67 |
import org.openide.nodes.Children; |
70 |
import org.openide.nodes.Children; |
Lines 182-187
Link Here
|
182 |
return awt.p.getExplorerManager(); |
185 |
return awt.p.getExplorerManager(); |
183 |
} |
186 |
} |
184 |
|
187 |
|
|
|
188 |
public void testOnlyChildDestroyedCausesSelectionOfParent () throws Throwable { |
189 |
// node.destroy called on the last selected node of the root node |
190 |
ExplorerManager em = doChildDestroyTest ("one", Collections.singleton("one"), "one"); |
191 |
final List<Node> arr = Arrays.asList(em.getSelectedNodes()); |
192 |
assertEquals("One selected: " + arr, 1, arr.size()); |
193 |
assertEquals("Root selected", em.getRootContext(), arr.get(0)); |
194 |
} |
195 |
|
196 |
public void testChildDestroyedMoreInSelection () throws Throwable { |
197 |
// two children in selection, should not select parent |
198 |
// the second child should be selected in the end |
199 |
ExplorerManager em = doChildDestroyTest ("one", Arrays.asList("one", "two"), "one", "two"); |
200 |
final List<Node> arr = Arrays.asList(em.getSelectedNodes()); |
201 |
assertEquals("One node selected: " + arr, 1, arr.size()); |
202 |
assertEquals("second child selected", "two", arr.get(0).getName()); |
203 |
} |
204 |
|
205 |
public void testChildDestroyedCausesNextChildSelected () throws Throwable { |
206 |
// first selected child is destroyed => selection should move to the next child |
207 |
ExplorerManager em = doChildDestroyTest ("one", Collections.singleton("one"), "one", "two"); |
208 |
final List<Node> arr = Arrays.asList(em.getSelectedNodes()); |
209 |
assertEquals("One selected: " + arr, 1, arr.size()); |
210 |
assertEquals("second child selected", "two", arr.get(0).getName()); |
211 |
} |
212 |
|
213 |
private ExplorerManager doChildDestroyTest (final String name, final Collection<String> toSelect, |
214 |
final String... childrenNames) throws Throwable { |
215 |
|
216 |
class AWTTst implements Runnable { |
217 |
Node[] children; |
218 |
{ |
219 |
List<Node> arr = new ArrayList<Node>(); |
220 |
for (String s : childrenNames) { |
221 |
arr.add(createLeaf(s)); |
222 |
} |
223 |
children = arr.toArray(new Node[0]); |
224 |
} |
225 |
Panel p = new Panel(); |
226 |
BeanTreeView btv = new BeanTreeView(); |
227 |
JFrame f = new JFrame(); |
228 |
JTree tree = btv.tree; |
229 |
Node operateOn; |
230 |
|
231 |
// children must be Children.Keys(lazy) |
232 |
class RefreshableChildren extends Children.Keys<String> { |
233 |
|
234 |
public RefreshableChildren () { |
235 |
super(true); |
236 |
} |
237 |
|
238 |
@Override |
239 |
protected Node[] createNodes (String key) { |
240 |
Node n = null; |
241 |
for (Node cand : children) { |
242 |
if (cand.getName().equals(key)) { |
243 |
n = cand; |
244 |
break; |
245 |
} |
246 |
} |
247 |
return new Node[] { n }; |
248 |
} |
249 |
|
250 |
void refreshKeys (String[] keys) { |
251 |
super.setKeys(keys); |
252 |
} |
253 |
} |
254 |
AbstractNode root = new AbstractNode(new RefreshableChildren()); |
255 |
|
256 |
{ |
257 |
((RefreshableChildren) root.getChildren()).refreshKeys(childrenNames); |
258 |
root.setName("test root"); |
259 |
p.getExplorerManager().setRootContext(root); |
260 |
p.add(BorderLayout.CENTER, btv); |
261 |
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
262 |
f.getContentPane().add(BorderLayout.CENTER, p); |
263 |
f.setVisible(true); |
264 |
} |
265 |
|
266 |
@Override |
267 |
public void run() { |
268 |
|
269 |
List<Node> selection = new ArrayList<Node>(); |
270 |
|
271 |
for (int i = 0; i < children.length; i++) { |
272 |
if (name.equals(children[i].getName())) { |
273 |
// this should select a sibling of the removed node |
274 |
operateOn = children[i]; |
275 |
} |
276 |
if (toSelect.contains(children[i].getName())) { |
277 |
selection.add(children[i]); |
278 |
} |
279 |
} |
280 |
|
281 |
try { |
282 |
p.getExplorerManager().setSelectedNodes(selection.toArray(new Node[selection.size()])); |
283 |
} catch (PropertyVetoException e) { |
284 |
fail("Unexpected PropertyVetoException from ExplorerManager.setSelectedNodes()"); |
285 |
} |
286 |
|
287 |
TreePath[] paths = tree.getSelectionPaths(); |
288 |
assertNotNull("Before removal: one node should be selected, but there are none.", paths); |
289 |
assertEquals("Before removal: one node should be selected, but there are none.", selection.size(), paths.length); |
290 |
if (selection.size() == 1) { |
291 |
assertEquals("Before removal: one node should be selected, but there are none.", operateOn, Visualizer.findNode(paths[0].getLastPathComponent())); |
292 |
assertEquals("Before removal: one node should be selected, but there are none.", operateOn, Visualizer.findNode(tree.getAnchorSelectionPath().getLastPathComponent())); |
293 |
} |
294 |
|
295 |
try { |
296 |
// destroy the node |
297 |
operateOn.destroy(); |
298 |
} catch (IOException ex) { |
299 |
fail(ex.getMessage()); |
300 |
} |
301 |
|
302 |
assertNotNull("After removal: one node should be selected, but there are none.", tree.getSelectionPath()); |
303 |
} |
304 |
|
305 |
public void tryGc() { |
306 |
// somewhere around here it's time to remove the destroyed node from children |
307 |
// the same as DataObject and FolderChildren work |
308 |
EventQueue.invokeLater(new Runnable() { |
309 |
@Override |
310 |
public void run () { |
311 |
List<String> newKeys = new ArrayList<String>(Arrays.asList(childrenNames)); |
312 |
newKeys.remove(name); |
313 |
((RefreshableChildren) root.getChildren()).refreshKeys(newKeys.toArray(new String[newKeys.size()])); |
314 |
children = null; |
315 |
} |
316 |
}); |
317 |
WeakReference<Node> wref = new WeakReference<Node>(operateOn); |
318 |
operateOn = null; |
319 |
assertGC("Node should be released.", wref); |
320 |
} |
321 |
} |
322 |
AWTTst awt = new AWTTst(); |
323 |
holder = awt; |
324 |
try { |
325 |
SwingUtilities.invokeAndWait(awt); |
326 |
} catch (InvocationTargetException ex) { |
327 |
throw ex.getTargetException(); |
328 |
} |
329 |
awt.tryGc(); |
330 |
return awt.p.getExplorerManager(); |
331 |
} |
332 |
|
185 |
public void testVisibleVisNodesAreNotGCed() throws InterruptedException, Throwable { |
333 |
public void testVisibleVisNodesAreNotGCed() throws InterruptedException, Throwable { |
186 |
doTestVisibleVisNodesAreNotGCed(false); |
334 |
doTestVisibleVisNodesAreNotGCed(false); |
187 |
} |
335 |
} |