Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ide/projectui/nbproject/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.8</specification-version>
<specification-version>6.97</specification-version>
</run-dependency>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,11 @@ public final class OpenProjectList {
public static Comparator<Project> projectByDisplayName() {
return new ProjectByDisplayNameComparator();
}


static Comparator<? super Project> projectByPath() {
return new ProjectByPathComparator();
}

// Property names
public static final String PROPERTY_OPEN_PROJECTS = "OpenProjects";
public static final String PROPERTY_WILL_OPEN_PROJECTS = "willOpenProjects"; // NOI18N
Expand Down Expand Up @@ -1965,6 +1969,21 @@ public int compare(Project p1, Project p2) {
}

}
private static class ProjectByPathComparator implements Comparator<Project> {
@Override
public int compare(Project p1, Project p2) {
if (p1 == null && p2 == null) {
return 0;
}
if (p1 == null) {
return -1;
}
if (p2 == null) {
return 1;
}
return p1.getProjectDirectory().getPath().compareTo(p2.getProjectDirectory().getPath());
}
}

private final class NbProjectDeletionListener extends FileChangeAdapter {

Expand Down
36 changes: 36 additions & 0 deletions ide/projectui/src/org/netbeans/modules/project/ui/ProjectTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
Expand All @@ -67,6 +69,7 @@
import javax.swing.event.ChangeListener;
import javax.swing.text.DefaultEditorKit;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
Expand All @@ -89,6 +92,7 @@
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
import org.openide.explorer.view.BeanTreeView;
import org.openide.explorer.view.NodeRenderer;
import org.openide.explorer.view.Visualizer;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
Expand Down Expand Up @@ -417,6 +421,34 @@ public void writeExternal (ObjectOutput out) throws IOException {
}
}

private static class DepthRespectingRenderer extends NodeRenderer {
DepthRespectingRenderer() {
}

@Override
protected int findIndent(Object model, TreeNode vis) {
var node = Visualizer.findNode(vis);
while (node != null) {
if (node instanceof ProjectsRootNode.BadgingNode) {
var badge = (ProjectsRootNode.BadgingNode) node;
return badge.pair.depth;
}
node = node.getParentNode();
}
return 0;
}

private static final int parents(FileObject fo) {
int cnt = 0;
while (fo != null) {
cnt++;
fo = fo.getParent();
}
return cnt;
}

}

private class KeepExpansion implements Runnable {
final RequestProcessor.Task task;
final List<String[]> exPaths;
Expand Down Expand Up @@ -719,6 +751,10 @@ private void restoreTreeView() {
/** Extending bean treeview. To be able to persist the selected paths
*/
private class ProjectTreeView extends BeanTreeView {
{
this.tree.setCellRenderer(new DepthRespectingRenderer());
}

public void scrollToNode(final Node n) {
// has to be delayed to be sure that events for Visualizers
// were processed and TreeNodes are already in hierarchy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -274,7 +275,7 @@ public ProjectChildren( int type ) {
// Children.Keys impl --------------------------------------------------

@Override
public void addNotify() {
public void addNotify() {
OpenProjectList.getDefault().addPropertyChangeListener(this);
RP.post(new Runnable() {
@Override
Expand Down Expand Up @@ -455,21 +456,33 @@ public void stateChanged( ChangeEvent e ) {
}

final void refresh(Project p) {
refreshKey(new Pair(p, type));
for (var k : getKeys()) {
if (k.project == p) {
refreshKey(k);
}
}
}

// Own methods ---------------------------------------------------------

public Collection<Pair> getKeys() {
List<Project> projects = Arrays.asList( OpenProjectList.getDefault().getOpenProjects() );
projects.sort(OpenProjectList.projectByDisplayName());
projects.sort(OpenProjectList.projectByPath());

final List<Pair> dirs = new ArrayList<>(projects.size());
final java.util.Map<Project,Pair> snapshot = new HashMap<>();
for (Project project : projects) {
final Pair p = new Pair(project, type);
var nested = new LinkedList<FileObject>();
for (Project prj : projects) {
while (!nested.isEmpty()) {
if (FileUtil.isParentOf(nested.peekLast(), prj.getProjectDirectory())) {
break;
}
nested.removeLast();
}
var p = new Pair(prj, type, nested.size());
nested.add(prj.getProjectDirectory());
dirs.add(p);
snapshot.put(project, p);
snapshot.put(prj, p);
}
synchronized (projects2Pairs) {
projects2Pairs.clear();
Expand All @@ -491,13 +504,15 @@ static final class Pair extends Object {
final FileObject fo;
private final int type;
private Union2<LogicalViewProvider,org.openide.util.Pair<Sources,SourceGroup[]>> data;
final int depth;

public Pair(
final Project project,
final int type) {
final int type, int depth) {
this.project = project;
this.fo = project.getProjectDirectory();
this.type = type;
this.depth = depth;
this.data = createData(project, type);
}

Expand Down Expand Up @@ -563,7 +578,7 @@ static final class BadgingNode extends FilterNode implements ChangeListener, Pro
private volatile Boolean mainCache;
private final ProjectChildren ch;
private final boolean logicalView;
private final ProjectChildren.Pair pair;
final ProjectChildren.Pair pair;
private final Set<FileObject> projectDirsListenedTo = Collections.newSetFromMap(new WeakHashMap<>());
private static final int DELAY = 50;
private final FileChangeListener newSubDirListener = new FileChangeAdapter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ public void saveProject(Project project) throws IOException, ClassCastException
Project prj = ProjectManager.getDefault().findProject(root);
assertNotNull(prj);
System.setProperty("test.nodelay", "true");
ProjectsRootNode.BadgingNode node = new ProjectsRootNode.BadgingNode(null, new ProjectsRootNode.ProjectChildren.Pair(prj, ProjectsRootNode.LOGICAL_VIEW),
ProjectsRootNode.BadgingNode node = new ProjectsRootNode.BadgingNode(null, new ProjectsRootNode.ProjectChildren.Pair(prj, ProjectsRootNode.LOGICAL_VIEW, 0),
new AbstractNode(Children.LEAF, Lookups.singleton(prj)) {
public @Override String getDisplayName() {return "Prj";}
public @Override String getHtmlDisplayName() {return "Prj";}
Expand Down Expand Up @@ -363,7 +363,7 @@ void disable() {
ProjectIconAnnotatorImpl annotator = new ProjectIconAnnotatorImpl();
MockLookup.setInstances(annotator);
System.setProperty("test.nodelay", "true");
ProjectsRootNode.BadgingNode node = new ProjectsRootNode.BadgingNode(null, new ProjectsRootNode.ProjectChildren.Pair(prj, ProjectsRootNode.LOGICAL_VIEW),
ProjectsRootNode.BadgingNode node = new ProjectsRootNode.BadgingNode(null, new ProjectsRootNode.ProjectChildren.Pair(prj, ProjectsRootNode.LOGICAL_VIEW, 0),
new AbstractNode(Children.LEAF, Lookups.singleton(prj)), true);
assertEquals(icon3, node.getIcon(BeanInfo.ICON_COLOR_16x16));
assertEquals(icon2, node.getOpenedIcon(BeanInfo.ICON_COLOR_16x16));
Expand Down Expand Up @@ -399,7 +399,7 @@ public void testReplaceProjectSingleNonRootNode() throws Exception { // #197864
final LazyProject lp = new LazyProject(d.toURL(), "p", new ExtIcon());
Children ch = new ProjectsRootNode.ProjectChildren(ProjectsRootNode.PHYSICAL_VIEW) {
public @Override void addNotify() {
setKeys(Collections.singleton(new ProjectsRootNode.ProjectChildren.Pair(lp, ProjectsRootNode.PHYSICAL_VIEW)));
setKeys(Collections.singleton(new ProjectsRootNode.ProjectChildren.Pair(lp, ProjectsRootNode.PHYSICAL_VIEW, 0)));
}
};
ProjectsRootNode.checkNoLazyNode(ch);
Expand Down
16 changes: 15 additions & 1 deletion platform/openide.explorer/apichanges.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,27 @@
under the License.

-->
<!DOCTYPE apichanges PUBLIC "-//NetBeans//DTD API changes list 1.0//EN" "../../nbbuild/javadoctools/apichanges.dtd">
<!DOCTYPE apichanges PUBLIC "-//NetBeans//DTD API changes list 1.0//EN" "../../nbbuild/javadoctools/apichanges-1.1.dtd">

<apichanges>
<apidefs>
<apidef name="explorer">Explorer API</apidef>
</apidefs>
<changes>
<change id="findIndent">
<api name="explorer"/>
<summary>NodeRenderer.findIndent</summary>
<version major="6" minor="97"/>
<date day="11" month="9" year="2026"/>
<author login="jtulach"/>
<compatibility binary="compatible" source="compatible" deprecation="no" deletion="no" addition="yes"/>
<description>
Control <b>NodeRenderer</b> indentation by overriding its
<code>findIndent</code> method.
</description>
<class package="org.openide.explorer.view" name="NodeRenderer"/>
<issue number="NETBEANS-5146"/>
</change>
<change id="ScrollOnExpand">
<api name="explorer"/>
<summary>Expose scrollOnExpand property on TreeView.</summary>
Expand Down
2 changes: 1 addition & 1 deletion platform/openide.explorer/manifest.mf
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Manifest-Version: 1.0
OpenIDE-Module: org.openide.explorer
OpenIDE-Module-Localizing-Bundle: org/openide/explorer/Bundle.properties
AutoUpdate-Essential-Module: true
OpenIDE-Module-Specification-Version: 6.96
OpenIDE-Module-Specification-Version: 6.97

Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.*;

import javax.swing.*;
import javax.swing.tree.TreeNode;
import org.openide.nodes.Children;


Expand Down Expand Up @@ -295,7 +296,7 @@ private VisualizerNode findElementAt(VisualizerNode vis, boolean countSelf, int
* @param o the visualizer node
* @return depth or 0 if not found
*/
static int findVisualizerDepth(ListModel m, VisualizerNode o) {
static int findVisualizerDepth(ListModel m, TreeNode o) {
if (m instanceof NodeListModel) {
NodeListModel n = (NodeListModel) m;
Info i = n.childrenCount.get(o);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

import javax.swing.*;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;

Expand Down Expand Up @@ -135,7 +137,9 @@ public Component getTreeCellRendererComponent(

//Do our additional configuration - set up the icon and possibly
//do some hacks to make it look focused for TreeTableView
configureFrom(renderer, tree, expanded, sel, vis);
int iconWidth = configureFrom(renderer, tree, expanded, sel, vis);

renderer.setIndent(iconWidth * findIndent(tree.getModel(), vis));

return result;
}
Expand All @@ -156,7 +160,7 @@ public Component getListCellRendererComponent(

String text = vis.getHtmlDisplayName();
if (list.getModel() instanceof NodeListModel) {
int depth = NodeListModel.findVisualizerDepth(list.getModel(), vis);
int depth = findIndent(list, vis);
if (depth == -1) {
text = NbBundle.getMessage(NodeRenderer.class, "LBL_UP");
}
Expand Down Expand Up @@ -187,7 +191,7 @@ public Component getListCellRendererComponent(
//in the node tree. Only does anything if you've subclassed and
//overridden createModel(). Does anybody do that?
if (list.getModel() instanceof NodeListModel && (((NodeListModel) list.getModel()).getDepth() > 1)) {
int indent = iconWidth * NodeListModel.findVisualizerDepth(list.getModel(), vis);
int indent = iconWidth * findIndent(list.getModel(), vis);

renderer.setIndent(indent);
}
Expand All @@ -196,6 +200,23 @@ public Component getListCellRendererComponent(
return result;
}

/** Finds the indentation level of a node.
*
* @param model the model (either {@link ListModel} or {@link TreeModel}) that's currently being rendered
* @param visualizer the visualizer to find indentation for
* @return the indentation level for the renderer of the given {@code visualizer};
* return {@code 0} for no indentation or positive number to indent the rendering to right
* @see Visualizer#findNode(java.lang.Object)
* @sincet 6.97
*/
protected int findIndent(Object model, TreeNode visualizer) {
if (model instanceof ListModel) {
return NodeListModel.findVisualizerDepth((ListModel) model, visualizer);
} else {
return 0;
}
}

/** Utility method which performs configuration which is common to all of the renderer
* implementations - sets the icon and focus properties on the renderer
* from the VisualizerNode.
Expand Down
Loading