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 35954
Collapse All | Expand All

(-)a/openide.explorer/apichanges.xml (+15 lines)
Lines 47-52 Link Here
47
<apidef name="explorer">Explorer API</apidef>
47
<apidef name="explorer">Explorer API</apidef>
48
</apidefs>
48
</apidefs>
49
<changes>
49
<changes>
50
    <change id="ListView.setShowParentNode">
51
        <api name="explorer"/>
52
        <summary>ListView can now display ".." item</summary>
53
        <version major="6" minor="28"/>
54
        <date day="24" month="4" year="2010"/>
55
        <author login="jtulach"/>
56
        <compatibility binary="compatible" source="compatible" deprecation="no" deletion="no" addition="yes"/>
57
        <description>
58
            To simplify navigation "up" in the <code>ListView</code> one
59
            can turn on <a href="@TOP@/org/openide/explorer/view/ListView.html#setShowParentNode(boolean)">showParentNode</a>
60
            property.
61
        </description>
62
        <class package="org.openide.explorer.view" name="ListView"/>
63
        <issue number="35954"/>
64
    </change>
50
    <change id="OutlineView.setPropertyColumns">
65
    <change id="OutlineView.setPropertyColumns">
51
        <api name="explorer"/>
66
        <api name="explorer"/>
52
        <summary><code>OutlineView.setPropertyColumns</code>,
67
        <summary><code>OutlineView.setPropertyColumns</code>,
(-)a/openide.explorer/manifest.mf (-1 / +1 lines)
Lines 2-6 Link Here
2
OpenIDE-Module: org.openide.explorer
2
OpenIDE-Module: org.openide.explorer
3
OpenIDE-Module-Localizing-Bundle: org/openide/explorer/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/openide/explorer/Bundle.properties
4
AutoUpdate-Essential-Module: true
4
AutoUpdate-Essential-Module: true
5
OpenIDE-Module-Specification-Version: 6.27
5
OpenIDE-Module-Specification-Version: 6.28
6
6
(-)a/openide.explorer/src/org/openide/explorer/view/Bundle.properties (+2 lines)
Lines 53-58 Link Here
53
VetoSelectedNodes=Selected Nodes
53
VetoSelectedNodes=Selected Nodes
54
LBL_QUICKSEARCH=Search:
54
LBL_QUICKSEARCH=Search:
55
55
56
LBL_UP=..
57
56
# TreeViewCellEditor
58
# TreeViewCellEditor
57
# {0} - old name
59
# {0} - old name
58
# {1} - new name
60
# {1} - new name
(-)a/openide.explorer/src/org/openide/explorer/view/ListView.java (-3 / +41 lines)
Lines 101-106 Link Here
101
import org.openide.nodes.Node.Property;
101
import org.openide.nodes.Node.Property;
102
import org.openide.nodes.NodeOp;
102
import org.openide.nodes.NodeOp;
103
import org.openide.util.ContextAwareAction;
103
import org.openide.util.ContextAwareAction;
104
import org.openide.util.Exceptions;
104
import org.openide.util.Mutex;
105
import org.openide.util.Mutex;
105
import org.openide.util.NbBundle;
106
import org.openide.util.NbBundle;
106
import org.openide.util.Utilities;
107
import org.openide.util.Utilities;
Lines 181-186 Link Here
181
    /** if true, the hierarchy traversal is allowed, if false, it is disabled */
182
    /** if true, the hierarchy traversal is allowed, if false, it is disabled */
182
    private boolean traversalAllowed = true;
183
    private boolean traversalAllowed = true;
183
184
185
    /** show parent node */
186
    private boolean showParentNode;
187
184
    /** action preformer */
188
    /** action preformer */
185
    private ActionListener defaultProcessor;
189
    private ActionListener defaultProcessor;
186
190
Lines 299-304 Link Here
299
        traversalAllowed = value;
303
        traversalAllowed = value;
300
    }
304
    }
301
305
306
    /** Is parent node (e.g. explored context shown)?
307
     * @return true or false. Default is false.
308
     * @since 6.28
309
     */
310
    public boolean isShowParentNode() {
311
        return showParentNode;
312
    }
313
314
    /** Shall the first node in the list be ".." representing currently
315
     * explored context? By default it is not, but if you want to simplify
316
     * the navigation in the {@link  Node} hierarchy, you can turn this
317
     * property on.
318
     * 
319
     * @param show true to show the "..", false to not to do so
320
     * @since 6.28
321
     */
322
    public void setShowParentNode(boolean show) {
323
        showParentNode = show;
324
    }
325
302
    /** Get the current processor for default actions.
326
    /** Get the current processor for default actions.
303
    * If not <code>null</code>, double-clicks or pressing Enter on
327
    * If not <code>null</code>, double-clicks or pressing Enter on
304
    * items in the view will not perform the default action on the selected node; rather the processor
328
    * items in the view will not perform the default action on the selected node; rather the processor
Lines 557-562 Link Here
557
    // Working methods
581
    // Working methods
558
    //
582
    //
559
583
584
    final void setNode(Node n) {
585
        boolean show = showParentNode && n != manager.getRootContext();
586
        model.setNode(n, show);
587
    }
588
560
    /* Initilizes the view.
589
    /* Initilizes the view.
561
    */
590
    */
562
    @Override
591
    @Override
Lines 577-583 Link Here
577
            manager.addVetoableChangeListener(wlvc = WeakListeners.vetoableChange(managerListener, manager));
606
            manager.addVetoableChangeListener(wlvc = WeakListeners.vetoableChange(managerListener, manager));
578
            manager.addPropertyChangeListener(wlpc = WeakListeners.propertyChange(managerListener, manager));
607
            manager.addPropertyChangeListener(wlpc = WeakListeners.propertyChange(managerListener, manager));
579
608
580
            model.setNode(manager.getExploredContext());
609
            setNode(manager.getExploredContext());
581
610
582
            updateSelection();
611
            updateSelection();
583
        } else {
612
        } else {
Lines 595-601 Link Here
595
624
596
            // bugfix #23974, model doesn't reflect an explorer context change
625
            // bugfix #23974, model doesn't reflect an explorer context change
597
            // because any listener was not active
626
            // because any listener was not active
598
            model.setNode(manager.getExploredContext());
627
            setNode(manager.getExploredContext());
599
            list.addMouseListener(popupSupport);
628
            list.addMouseListener(popupSupport);
600
        }
629
        }
601
    }
630
    }
Lines 662-667 Link Here
662
            return;
691
            return;
663
        }
692
        }
664
693
694
        if (showParentNode && NodeListModel.findVisualizerDepth(model, v) == -1) {
695
            try {
696
                manager.setExploredContextAndSelection(node.getParentNode(), new Node[] { node });
697
            } catch (PropertyVetoException ex) {
698
                // OK, let it be
699
            }
700
            return;
701
        }
702
665
        // on double click - invoke default action, if there is any
703
        // on double click - invoke default action, if there is any
666
        // (unless user holds CTRL key what means that we should always dive into the context)
704
        // (unless user holds CTRL key what means that we should always dive into the context)
667
        Action a = node.getPreferredAction();
705
        Action a = node.getPreferredAction();
Lines 1393-1399 Link Here
1393
            }
1431
            }
1394
1432
1395
            if (ExplorerManager.PROP_EXPLORED_CONTEXT.equals(evt.getPropertyName())) {
1433
            if (ExplorerManager.PROP_EXPLORED_CONTEXT.equals(evt.getPropertyName())) {
1396
                model.setNode(manager.getExploredContext());
1434
                setNode(manager.getExploredContext());
1397
1435
1398
                //System.out.println("Children: " + java.util.Arrays.asList (list.getValues ())); // NOI18N
1436
                //System.out.println("Children: " + java.util.Arrays.asList (list.getValues ())); // NOI18N
1399
                return;
1437
                return;
(-)a/openide.explorer/src/org/openide/explorer/view/NodeListModel.java (-10 / +30 lines)
Lines 66-71 Link Here
66
    /** parent node */
66
    /** parent node */
67
    private transient VisualizerNode parent;
67
    private transient VisualizerNode parent;
68
68
69
    /** should parent node be visible? */
70
    private transient boolean showParent;
71
69
    /** originally selected item */
72
    /** originally selected item */
70
    private transient Object selectedObject;
73
    private transient Object selectedObject;
71
74
Lines 100-106 Link Here
100
    /** Changes the root of the model. This is thread safe method.
103
    /** Changes the root of the model. This is thread safe method.
101
    * @param root the root of the model
104
    * @param root the root of the model
102
    */
105
    */
103
    public void setNode(final Node root) {
106
    public void setNode(Node root) {
107
        setNode(root, false);
108
    }
109
110
    final void setNode(final Node root, final boolean showRoot) {
104
        Mutex.EVENT.readAccess(new Runnable() {
111
        Mutex.EVENT.readAccess(new Runnable() {
105
            @Override
112
            @Override
106
            public void run() {
113
            public void run() {
Lines 110-116 Link Here
110
                }
117
                }
111
                VisualizerNode v = VisualizerNode.getVisualizer(null, root);
118
                VisualizerNode v = VisualizerNode.getVisualizer(null, root);
112
119
113
                if (v == parent) {
120
                if (v == parent && showParent == showRoot) {
114
                    // no change
121
                    // no change
115
                    return;
122
                    return;
116
                }
123
                }
Lines 118-123 Link Here
118
                removeAll();
125
                removeAll();
119
                parent.removeNodeModel(listener());
126
                parent.removeNodeModel(listener());
120
127
128
                showParent = showRoot;
121
                parent = v;
129
                parent = v;
122
                selectedObject = v;
130
                selectedObject = v;
123
                clearChildrenCount();
131
                clearChildrenCount();
Lines 172-178 Link Here
172
    */
180
    */
173
    @Override
181
    @Override
174
    public int getSize() {
182
    public int getSize() {
175
        int s = findSize(parent, -1, depth);
183
        int s = findSize(parent, showParent, -1, depth);
176
        return s;
184
        return s;
177
    }
185
    }
178
186
Lines 180-186 Link Here
180
    */
188
    */
181
    @Override
189
    @Override
182
    public Object getElementAt(int i) {
190
    public Object getElementAt(int i) {
183
        return findElementAt(parent, i, -1, depth);
191
        return findElementAt(parent, showParent, i, -1, depth);
184
    }
192
    }
185
193
186
    /** Finds index of given object.
194
    /** Finds index of given object.
Lines 223-234 Link Here
223
    * @param depth the depth to scan
231
    * @param depth the depth to scan
224
    * @return number of children
232
    * @return number of children
225
    */
233
    */
226
    private int findSize(VisualizerNode vis, int index, int depth) {
234
    private int findSize(VisualizerNode vis, boolean includeOwnself, int index, int depth) {
227
        Info info = childrenCount.get(vis);
235
        Info info = childrenCount.get(vis);
228
        if (info != null) {
236
        if (info != null) {
229
            return info.childrenCount;
237
            return info.childrenCount;
230
        }
238
        }
231
239
240
        if (includeOwnself) {
241
            index++;
242
        }
243
232
        // only my children
244
        // only my children
233
        int tmp = 0;
245
        int tmp = 0;
234
246
Lines 247-257 Link Here
247
                // count node v
259
                // count node v
248
                tmp++;
260
                tmp++;
249
                // now count children of node v
261
                // now count children of node v
250
                tmp += findSize(v, index + tmp, depth);
262
                tmp += findSize(v, false, index + tmp, depth);
251
            }
263
            }
252
        }
264
        }
253
265
254
        info.childrenCount = tmp;
266
        info.childrenCount = includeOwnself ? tmp + 1 : tmp;
255
        childrenCount.put(vis, info);
267
        childrenCount.put(vis, info);
256
        return tmp;
268
        return tmp;
257
    }
269
    }
Lines 263-269 Link Here
263
    * @param depth the depth to scan
275
    * @param depth the depth to scan
264
    * @return the children
276
    * @return the children
265
    */
277
    */
266
    private VisualizerNode findElementAt(VisualizerNode vis, int indx, int realIndx, int depth) {
278
    private VisualizerNode findElementAt(VisualizerNode vis, boolean countSelf, int indx, int realIndx, int depth) {
279
        if (countSelf) {
280
            if (indx == 0) {
281
                return vis;
282
            } else {
283
                indx--;
284
            }
285
        }
286
267
        if (--depth == 0) {
287
        if (--depth == 0) {
268
            // last depth is handled in special way
288
            // last depth is handled in special way
269
            return (VisualizerNode) vis.getChildAt(indx);
289
            return (VisualizerNode) vis.getChildAt(indx);
Lines 277-287 Link Here
277
                return v;
297
                return v;
278
            }
298
            }
279
299
280
            int s = findSize(v, ++realIndx, depth);
300
            int s = findSize(v, false, ++realIndx, depth);
281
301
282
            if (indx < s) {
302
            if (indx < s) {
283
                // search this child
303
                // search this child
284
                return findElementAt(v, indx, realIndx, depth);
304
                return findElementAt(v, false, indx, realIndx, depth);
285
            }
305
            }
286
306
287
            // go to next child
307
            // go to next child
(-)a/openide.explorer/src/org/openide/explorer/view/NodeRenderer.java (-1 / +7 lines)
Lines 50-55 Link Here
50
50
51
import javax.swing.*;
51
import javax.swing.*;
52
import javax.swing.tree.TreeCellRenderer;
52
import javax.swing.tree.TreeCellRenderer;
53
import org.openide.util.NbBundle;
53
54
54
55
55
/** Default renderer for nodes. Can paint either Nodes directly or
56
/** Default renderer for nodes. Can paint either Nodes directly or
Lines 158-165 Link Here
158
        }
159
        }
159
160
160
        String text = vis.getHtmlDisplayName();
161
        String text = vis.getHtmlDisplayName();
162
        if (list.getModel() instanceof NodeListModel) {
163
            int depth = NodeListModel.findVisualizerDepth(list.getModel(), vis);
164
            if (depth == -1) {
165
                text = NbBundle.getMessage(NodeRenderer.class, "LBL_UP");
166
            }
167
        }
161
        boolean isHtml = text != null;
168
        boolean isHtml = text != null;
162
163
        if (!isHtml) {
169
        if (!isHtml) {
164
            text = vis.getDisplayName();
170
            text = vis.getDisplayName();
165
        }
171
        }
(-)067c411a9044 (+193 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.openide.explorer.view;
43
44
import java.awt.EventQueue;
45
import java.util.ArrayList;
46
import java.util.List;
47
import java.util.concurrent.Callable;
48
import java.util.concurrent.atomic.AtomicReference;
49
import javax.swing.JFrame;
50
import org.netbeans.junit.NbTestCase;
51
import org.openide.explorer.ExplorerManager;
52
import org.openide.nodes.AbstractNode;
53
import org.openide.nodes.Children;
54
import org.openide.nodes.Node;
55
56
/**
57
 * A test that verifies few aspects of the ListView implementation.
58
 * 
59
 * @author  Petr Nejedly
60
 */
61
public final class ListViewWithUpTest extends NbTestCase {
62
    
63
    private ListView view;
64
    private ExplorerWindow testWindow;
65
    
66
    public ListViewWithUpTest(String testName) {
67
        super(testName);
68
    }
69
70
    /**
71
     * Tests whether the ListView doesn't try to scroll to a changed node
72
     * on a change event. See issue 88209
73
     */
74
    public void testNoScrollOnIconChange() throws Exception {
75
        assert !EventQueue.isDispatchThread();
76
        
77
        testWindow = new ExplorerWindow();
78
        testWindow.getContentPane().add(view = new ListView());
79
        view.setShowParentNode(true);
80
81
        Ch20 ch = new Ch20("");
82
        Node root = new AbstractNode(ch);
83
        root.setName("Root");
84
        
85
        testWindow.getExplorerManager().setRootContext(root);
86
        awtRequest(new Callable<Void>() {
87
            @Override
88
            public Void call() {
89
                testWindow.pack();
90
                testWindow.setVisible(true);
91
                return null;
92
            }
93
        });
94
95
        while (!awtRequest(new Callable<Boolean>() {
96
            @Override
97
            public Boolean call() throws Exception {
98
                return testWindow.isShowing();
99
            }
100
        })) {
101
            Thread.sleep(100);
102
        }
103
104
        assertEquals("Just 20 items for root", 20, view.model.getSize());
105
        testWindow.getExplorerManager().setExploredContext(root.getChildren().getNodeAt(10));
106
        awtRequest(new Callable<Void>() {
107
            @Override
108
            public Void call() {
109
                return null;
110
            }
111
        });
112
        assertEquals("21 items for non-root", 21, view.model.getSize());
113
        awtRequest(new Callable<Void>() {
114
            @Override
115
            public Void call() {
116
                view.performObjectAt(0, 0);
117
                return null;
118
            }
119
        });
120
        assertEquals("Moved back to root", root, testWindow.getExplorerManager().getExploredContext());
121
        
122
        // cleanup
123
        awtRequest(new Callable<Void>() {
124
            @Override
125
            public Void call() {
126
                testWindow.setVisible(false);
127
                return null;
128
            }
129
        });
130
    }
131
132
    private static final class Ch20 extends Children.Keys<Integer> {
133
        private final String prefix;
134
135
        public Ch20(String prefix) {
136
            this.prefix = prefix;
137
        }
138
139
140
        @Override
141
        protected void addNotify() {
142
            List<Integer> arr = new ArrayList<Integer>();
143
            for (int i = 0; i < 20; i++) {
144
                arr.add(i);
145
            }
146
            setKeys(arr);
147
        }
148
149
150
        @Override
151
        protected Node[] createNodes(Integer key) {
152
            AbstractNode an = new AbstractNode(new Ch20(prefix + key));
153
            an.setName(prefix + key);
154
            return new Node[] { an };
155
        }
156
157
    }
158
        
159
    
160
    private static final class ExplorerWindow extends JFrame
161
                               implements ExplorerManager.Provider {
162
        
163
        private final ExplorerManager explManager = new ExplorerManager();
164
        
165
        ExplorerWindow() {
166
            super("ListView test");                                     //NOI18N
167
        }
168
        
169
        @Override
170
        public ExplorerManager getExplorerManager() {
171
            return explManager;
172
        }
173
    }
174
    
175
    private static <T> T awtRequest(final Callable<T> call) throws Exception {
176
        final AtomicReference<T> value = new AtomicReference<T>();
177
        final Exception[] exc = new Exception[1];
178
        EventQueue.invokeAndWait(new Runnable() {
179
            @Override
180
            public void run() {
181
                try {
182
                    value.set(call.call());
183
                } catch (Exception ex) {
184
                    exc[0] = ex;
185
                }
186
            }
187
        });
188
        
189
        if (exc[0] != null) throw exc[0];
190
        return value.get();
191
    }
192
    
193
}
(-)a/openide.explorer/test/unit/src/org/openide/explorer/view/NodeListModelTest.java (-1 / +22 lines)
Lines 44-49 Link Here
44
import java.lang.ref.WeakReference;
44
import java.lang.ref.WeakReference;
45
import java.util.LinkedList;
45
import java.util.LinkedList;
46
import java.util.List;
46
import java.util.List;
47
import javax.swing.tree.TreeNode;
47
import org.netbeans.junit.NbTestCase;
48
import org.netbeans.junit.NbTestCase;
48
import org.openide.nodes.AbstractNode;
49
import org.openide.nodes.AbstractNode;
49
import org.openide.nodes.Children;
50
import org.openide.nodes.Children;
Lines 60-65 Link Here
60
        super(name);
61
        super(name);
61
    }
62
    }
62
63
64
    @Override
63
    protected boolean runInEQ() {
65
    protected boolean runInEQ() {
64
        return true;
66
        return true;
65
    }
67
    }
Lines 114-119 Link Here
114
        // childrenCount
116
        // childrenCount
115
        model.getSize();
117
        model.getSize();
116
    }
118
    }
119
120
    public void testIsRootIncluded() {
121
        Node c = new AbstractNode(new CNodeChildren());
122
        NodeListModel model = new NodeListModel();
123
        model.setNode(c, true);
124
125
        assertEquals(NO_OF_NODES + 1, model.getSize());
126
127
        assertNode("Parent is first", c, model.getElementAt(0));
128
        for (int i= 0; i < NO_OF_NODES; i++) {
129
            assertNode(i + "th node", c.getChildren().getNodeAt(i), model.getElementAt(i + 1));
130
        }
131
    }
132
133
    private static void assertNode(String msg, Node n, Object e) {
134
        TreeNode v = Visualizer.findVisualizer(n);
135
        assertEquals(msg, v, e);
136
    }
117
    
137
    
118
    /*
138
    /*
119
     * Children for testNodesAreReferenced.
139
     * Children for testNodesAreReferenced.
Lines 122-133 Link Here
122
        public CNodeChildren() {
142
        public CNodeChildren() {
123
            List myKeys = new LinkedList();
143
            List myKeys = new LinkedList();
124
            for (int i = 0; i < NO_OF_NODES; i++) {
144
            for (int i = 0; i < NO_OF_NODES; i++) {
125
                myKeys.add(new Integer(i));
145
                myKeys.add(Integer.valueOf(i));
126
            }
146
            }
127
            
147
            
128
            setKeys(myKeys);
148
            setKeys(myKeys);
129
        }
149
        }
130
        
150
        
151
        @Override
131
        protected Node[] createNodes(Object key) {
152
        protected Node[] createNodes(Object key) {
132
            AbstractNode an = new AbstractNode(Children.LEAF);
153
            AbstractNode an = new AbstractNode(Children.LEAF);
133
            an.setName(key.toString());
154
            an.setName(key.toString());

Return to bug 35954