This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 193852
Collapse All | Expand All

(-)openide.explorer/src/org/openide/explorer/ExplorerManager.java (-1 / +7 lines)
Lines 1010-1016 Link Here
1010
                    // compare paths to root
1010
                    // compare paths to root
1011
                    Node n_selection = newSel.get(newSel.indexOf(n_remove));
1011
                    Node n_selection = newSel.get(newSel.indexOf(n_remove));
1012
1012
1013
                    if (!Arrays.equals(NodeOp.createPath(n_remove, null), NodeOp.createPath(n_selection, null))) {
1013
                    if (!Arrays.equals(NodeOp.createPath(n_remove, null), NodeOp.createPath(n_selection, null))
1014
                            || isInParentChildren(n_remove)) {
1014
                        it.remove();
1015
                        it.remove();
1015
                    }
1016
                    }
1016
                }
1017
                }
Lines 1028-1032 Link Here
1028
            
1029
            
1029
            
1030
            
1030
        }
1031
        }
1032
1033
        private boolean isInParentChildren (Node node) {
1034
            Node parent = node.getParentNode();
1035
            return parent != null && Arrays.asList(parent.getChildren().getNodes()).contains(node);
1036
        }
1031
    }
1037
    }
1032
}
1038
}
(-)openide.explorer/src/org/openide/explorer/view/VisualizerEvent.java (-4 / +1 lines)
Lines 158-167 Link Here
158
    }
158
    }
159
    
159
    
160
    static final class Destroyed extends VisualizerEvent implements Runnable {
160
    static final class Destroyed extends VisualizerEvent implements Runnable {
161
        private final VisualizerNode toNull;
161
        public Destroyed(VisualizerChildren ch, NodeEvent ev) {
162
        public Destroyed(VisualizerChildren ch, NodeEvent ev, VisualizerNode toNull) {
163
            super(ch, null, ev, null);
162
            super(ch, null, ev, null);
164
            this.toNull = toNull;
165
        }
163
        }
166
        
164
        
167
        @Override
165
        @Override
Lines 173-179 Link Here
173
                    v.nodeDestroyed(originalEvent);
171
                    v.nodeDestroyed(originalEvent);
174
                }
172
                }
175
            }
173
            }
176
            toNull.parent = null;
177
        }
174
        }
178
    }
175
    }
179
}
176
}
(-)openide.explorer/src/org/openide/explorer/view/VisualizerNode.java (-1 / +1 lines)
Lines 399-405 Link Here
399
    @Override
399
    @Override
400
    public void nodeDestroyed(NodeEvent ev) {
400
    public void nodeDestroyed(NodeEvent ev) {
401
        node = Node.EMPTY;
401
        node = Node.EMPTY;
402
        QUEUE.runSafe(new VisualizerEvent.Destroyed(getChildren(false), ev, this));
402
        QUEUE.runSafe(new VisualizerEvent.Destroyed(getChildren(false), ev));
403
    }
403
    }
404
404
405
    /** Change in the node properties (icon, etc.)
405
    /** Change in the node properties (icon, etc.)
(-)openide.explorer/test/unit/src/org/openide/explorer/view/BeanTreeViewTest.java (-1 / +149 lines)
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
    }

Return to bug 193852