Add location string showing where method or property is defined
This commit is contained in:
@@ -54,7 +54,7 @@ public interface DescriptorRenderer extends Renderer<DeclarationDescriptor> {
|
||||
.setModifiers()
|
||||
.setStartFromName(true).build();
|
||||
|
||||
DescriptorRenderer STARTS_FROM_NAME_WITH_SHORT_TYPES = new DescriptorRendererBuilder()
|
||||
DescriptorRenderer ONLY_NAMES_WITH_SHORT_TYPES = new DescriptorRendererBuilder()
|
||||
.setWithDefinedIn(false)
|
||||
.setModifiers()
|
||||
.setShortNames(true)
|
||||
@@ -62,6 +62,7 @@ public interface DescriptorRenderer extends Renderer<DeclarationDescriptor> {
|
||||
.setWithoutFunctionParameterNames(true)
|
||||
.setReceiverAfterName(true)
|
||||
.setRenderClassObjectName(true)
|
||||
.setWithoutSuperTypes(true)
|
||||
.setStartFromName(true).build();
|
||||
|
||||
DescriptorRenderer FQ_NAMES_IN_TYPES = new DescriptorRendererBuilder().build();
|
||||
|
||||
@@ -41,6 +41,7 @@ public class DescriptorRendererBuilder {
|
||||
private boolean includeSynthesizedParameterNames = true;
|
||||
private boolean withoutFunctionParameterNames = false;
|
||||
private boolean withoutTypeParameters = false;
|
||||
private boolean withoutSuperTypes = false;
|
||||
|
||||
@NotNull
|
||||
private DescriptorRenderer.OverrideRenderingPolicy overrideRenderingPolicy = DescriptorRenderer.OverrideRenderingPolicy.RENDER_OPEN;
|
||||
@@ -187,6 +188,11 @@ public class DescriptorRendererBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public DescriptorRendererBuilder setWithoutSuperTypes(boolean withoutSuperTypes) {
|
||||
this.withoutSuperTypes = withoutSuperTypes;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DescriptorRenderer build() {
|
||||
return new DescriptorRendererImpl(
|
||||
@@ -194,7 +200,7 @@ public class DescriptorRendererBuilder {
|
||||
normalizedVisibilities, showInternalKeyword, prettyFunctionTypes, uninferredTypeParameterAsName,
|
||||
overrideRenderingPolicy, valueParametersHandler, textFormat, excludedAnnotationClasses, includePropertyConstant,
|
||||
includeSynthesizedParameterNames, withoutFunctionParameterNames, withoutTypeParameters, receiverAfterName,
|
||||
renderClassObjectName);
|
||||
renderClassObjectName, withoutSuperTypes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.types.ErrorUtils.UninferredParameterType;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.*;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.CANT_INFER_LAMBDA_PARAM_TYPE;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.DONT_CARE;
|
||||
|
||||
public class DescriptorRendererImpl implements DescriptorRenderer {
|
||||
private final boolean shortNames;
|
||||
@@ -61,8 +62,9 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
||||
private final boolean withoutFunctionParameterNames;
|
||||
private final boolean withoutTypeParameters;
|
||||
private final boolean renderClassObjectName;
|
||||
|
||||
private final boolean withoutSuperTypes;
|
||||
private final boolean receiverAfterName;
|
||||
|
||||
@NotNull
|
||||
private final OverrideRenderingPolicy overrideRenderingPolicy;
|
||||
@NotNull
|
||||
@@ -95,7 +97,8 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
||||
boolean withoutFunctionParameterNames,
|
||||
boolean withoutTypeParameters,
|
||||
boolean receiverAfterName,
|
||||
boolean renderClassObjectName
|
||||
boolean renderClassObjectName,
|
||||
boolean withoutSuperTypes
|
||||
) {
|
||||
this.shortNames = shortNames;
|
||||
this.withDefinedIn = withDefinedIn;
|
||||
@@ -119,6 +122,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
||||
this.withoutTypeParameters = withoutTypeParameters;
|
||||
this.receiverAfterName = receiverAfterName;
|
||||
this.renderClassObjectName = renderClassObjectName;
|
||||
this.withoutSuperTypes = withoutSuperTypes;
|
||||
}
|
||||
|
||||
/* FORMATTING */
|
||||
@@ -807,10 +811,18 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
renderSuperTypes(klass, builder);
|
||||
renderWhereSuffix(typeParameters, builder);
|
||||
}
|
||||
|
||||
private void renderSuperTypes(@NotNull ClassDescriptor klass, @NotNull StringBuilder builder) {
|
||||
if (withoutSuperTypes) return;
|
||||
|
||||
if (!klass.equals(KotlinBuiltIns.getInstance().getNothing())) {
|
||||
Collection<JetType> supertypes = klass.getTypeConstructor().getSupertypes();
|
||||
if (supertypes.isEmpty() || supertypes.size() == 1 && KotlinBuiltIns.getInstance().isAnyOrNullableAny(
|
||||
supertypes.iterator().next())) {
|
||||
|
||||
if (supertypes.isEmpty() ||
|
||||
supertypes.size() == 1 && KotlinBuiltIns.getInstance().isAnyOrNullableAny(supertypes.iterator().next())) {
|
||||
}
|
||||
else {
|
||||
builder.append(" : ");
|
||||
@@ -823,8 +835,6 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderWhereSuffix(typeParameters, builder);
|
||||
}
|
||||
|
||||
private void renderClassKindPrefix(ClassDescriptor klass, StringBuilder builder) {
|
||||
|
||||
@@ -20,8 +20,10 @@ import com.intellij.ide.structureView.StructureViewTreeElement;
|
||||
import com.intellij.ide.util.treeView.smartTree.TreeElement;
|
||||
import com.intellij.navigation.ColoredItemPresentation;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.navigation.LocationPresentation;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.ui.Queryable;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.NavigatablePsiElement;
|
||||
@@ -29,25 +31,28 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.PsiIconUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||
import org.jetbrains.jet.plugin.JetDescriptorIconProvider;
|
||||
import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class JetStructureViewElement implements StructureViewTreeElement, ColoredItemPresentation {
|
||||
public class JetStructureViewElement implements StructureViewTreeElement, ColoredItemPresentation, LocationPresentation, Queryable {
|
||||
private final NavigatablePsiElement element;
|
||||
private final boolean isInherited;
|
||||
|
||||
private String elementText;
|
||||
private String locationString;
|
||||
private Icon icon;
|
||||
private final boolean isInherited;
|
||||
|
||||
public JetStructureViewElement(@NotNull NavigatablePsiElement element, @NotNull DeclarationDescriptor descriptor, boolean isInherited) {
|
||||
this.element = element;
|
||||
@@ -56,6 +61,7 @@ public class JetStructureViewElement implements StructureViewTreeElement, Colore
|
||||
if (!(element instanceof JetElement)) {
|
||||
// Avoid storing descriptor in fields
|
||||
elementText = getElementText(element, descriptor);
|
||||
locationString = isInherited ? getElementLocationString(descriptor) : null;
|
||||
icon = getElementIcon(element, descriptor);
|
||||
}
|
||||
}
|
||||
@@ -141,7 +147,11 @@ public class JetStructureViewElement implements StructureViewTreeElement, Colore
|
||||
@Nullable
|
||||
@Override
|
||||
public String getLocationString() {
|
||||
return null;
|
||||
if (locationString == null) {
|
||||
locationString = isInherited() ? getElementLocationString(getDescriptor()) : null;
|
||||
}
|
||||
|
||||
return locationString;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -154,6 +164,23 @@ public class JetStructureViewElement implements StructureViewTreeElement, Colore
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocationPrefix() {
|
||||
return isInherited() ? " " : LocationPresentation.DEFAULT_LOCATION_PREFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocationSuffix() {
|
||||
return isInherited() ? "" : LocationPresentation.DEFAULT_LOCATION_SUFFIX;
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
@Override
|
||||
public void putInfo(@NotNull Map<String, String> info) {
|
||||
info.put("text", getPresentableText());
|
||||
info.put("location", getLocationString());
|
||||
}
|
||||
|
||||
public boolean isInherited() {
|
||||
return isInherited;
|
||||
}
|
||||
@@ -211,7 +238,7 @@ public class JetStructureViewElement implements StructureViewTreeElement, Colore
|
||||
@Nullable
|
||||
private static String getElementText(@NotNull NavigatablePsiElement navigatablePsiElement, @Nullable DeclarationDescriptor descriptor) {
|
||||
if (descriptor != null) {
|
||||
return DescriptorRenderer.STARTS_FROM_NAME_WITH_SHORT_TYPES.render(descriptor);
|
||||
return DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.render(descriptor);
|
||||
}
|
||||
|
||||
String text = navigatablePsiElement.getName();
|
||||
@@ -225,4 +252,24 @@ public class JetStructureViewElement implements StructureViewTreeElement, Colore
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getElementLocationString(@Nullable DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof CallableMemberDescriptor) {
|
||||
Set<CallableMemberDescriptor> baseCallableDescriptors = OverrideResolver.getDeepestSuperDeclarations((CallableMemberDescriptor) descriptor);
|
||||
CallableMemberDescriptor first = ContainerUtil.getFirstItem(baseCallableDescriptors);
|
||||
if (first != null) {
|
||||
DeclarationDescriptor typeDescriptor = first.getContainingDeclaration();
|
||||
|
||||
String typeName = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.render(typeDescriptor);
|
||||
return withRightArrow(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String withRightArrow(String str) {
|
||||
char rightArrow = '\u2192';
|
||||
return UIUtil.getLabelFont().canDisplay(rightArrow) ? rightArrow + str : "->" + str;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
trait First
|
||||
|
||||
trait Second : First {
|
||||
fun foo()
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
-DoNotShowParentsInLocationJava.kt
|
||||
-Third
|
||||
equals(Any?): Boolean location=→Any
|
||||
foo(): Unit location=→Second
|
||||
hashCode(): Int location=→Any
|
||||
toString(): String location=→Any
|
||||
@@ -0,0 +1,3 @@
|
||||
trait Third: Second
|
||||
|
||||
// WITH_INHERITED
|
||||
@@ -1,6 +1,6 @@
|
||||
-InheritedInnerClasses.kt
|
||||
-B : A
|
||||
equals(Any?): Boolean
|
||||
foo(): Unit
|
||||
hashCode(): Int
|
||||
toString(): String
|
||||
-B
|
||||
equals(Any?): Boolean location=→Any
|
||||
foo(): Unit location=→A
|
||||
hashCode(): Int location=→Any
|
||||
toString(): String location=→Any
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
-InheritedJavaMembers.kt
|
||||
-InheritedJavaMembers : Callable<String>
|
||||
call(): String?
|
||||
clone(): Any
|
||||
equals(Any?): Boolean
|
||||
finalize(): Unit
|
||||
getClass(): Class<out Any?>
|
||||
hashCode(): Int
|
||||
notify(): Unit
|
||||
notifyAll(): Unit
|
||||
-InheritedJavaMembers
|
||||
call(): String? location=→Callable
|
||||
clone(): Any location=→Object
|
||||
equals(Any?): Boolean location=→Any
|
||||
finalize(): Unit location=→Object
|
||||
getClass(): Class<out Any?> location=→Object
|
||||
hashCode(): Int location=→Any
|
||||
notify(): Unit location=→Object
|
||||
notifyAll(): Unit location=→Object
|
||||
test(): Unit
|
||||
toString(): String
|
||||
wait(): Unit
|
||||
wait(Long): Unit
|
||||
wait(Long, Int): Unit
|
||||
toString(): String location=→Any
|
||||
wait(): Unit location=→Object
|
||||
wait(Long): Unit location=→Object
|
||||
wait(Long, Int): Unit location=→Object
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
-InheritedLocalKotlin.kt
|
||||
-A : TA
|
||||
equals(Any?): Boolean
|
||||
hashCode(): Int
|
||||
some(): Unit
|
||||
toString(): String
|
||||
-B : TA
|
||||
-A
|
||||
a: Int
|
||||
equals(Any?): Boolean location=→Any
|
||||
hashCode(): Int location=→Any
|
||||
some(): Unit
|
||||
toString(): String location=→Any
|
||||
-B
|
||||
a: Int location=→TA
|
||||
some(): Unit location=→TA
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
trait TA {
|
||||
fun some()
|
||||
val a: Int
|
||||
}
|
||||
|
||||
class A : TA {
|
||||
override fun some() {
|
||||
}
|
||||
|
||||
override val a: Int = 0
|
||||
}
|
||||
|
||||
abstract class B : TA
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-InheritedMembers.kt
|
||||
-Test
|
||||
equals(Any?): Boolean
|
||||
hashCode(): Int
|
||||
equals(Any?): Boolean location=→Any
|
||||
hashCode(): Int location=→Any
|
||||
test(): Unit
|
||||
toString(): String
|
||||
toString(): String location=→Any
|
||||
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
-InheritedMembersWithSubstitutedTypes.kt
|
||||
-Third : Second<String>
|
||||
a: U
|
||||
equals(Any?): Boolean
|
||||
foo(T): Unit
|
||||
hashCode(): Int
|
||||
toString(): String
|
||||
-Third
|
||||
a: U location=→Second
|
||||
equals(Any?): Boolean location=→Any
|
||||
foo(T): Unit location=→First
|
||||
hashCode(): Int location=→Any
|
||||
toString(): String location=→Any
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
a: Int
|
||||
a: String on Comparable<T>
|
||||
b: Any
|
||||
-Enum1 : Enum<Enum1>
|
||||
FIRST : Enum1
|
||||
SECOND : Enum1
|
||||
-Enum1
|
||||
FIRST
|
||||
SECOND
|
||||
extension1() on String: Unit
|
||||
extension2() on Comparable<T>: Unit
|
||||
test1(): Unit
|
||||
@@ -34,7 +34,7 @@
|
||||
TestWithWhere
|
||||
testWithWhere(): Unit
|
||||
Trait
|
||||
Trait1 : Trait
|
||||
Trait1
|
||||
withDefaulArgs(Int = ..., String = ...): Unit
|
||||
-WithDefaultArgs
|
||||
a: Int
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
-SeveralClasses.kt
|
||||
A
|
||||
B
|
||||
Other : A
|
||||
Some : B, A
|
||||
Other
|
||||
Some
|
||||
|
||||
+3
-2
@@ -21,13 +21,13 @@ import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase
|
||||
import com.intellij.util.ui.tree.TreeUtil
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import java.io.File
|
||||
import com.intellij.testFramework.PlatformTestUtil
|
||||
import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure
|
||||
import com.intellij.ide.util.FileStructurePopup
|
||||
import com.intellij.ide.actions.ViewStructureAction
|
||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider
|
||||
import org.jetbrains.jet.JetTestUtils
|
||||
import org.jetbrains.jet.InTextDirectivesUtils
|
||||
import com.intellij.openapi.ui.Queryable.PrintInfo
|
||||
import org.jetbrains.jet.test.util.configureWithExtraFile
|
||||
|
||||
public abstract class AbstractKotlinFileStructureTest : JetLightCodeInsightFixtureTestCase() {
|
||||
@@ -47,7 +47,8 @@ public abstract class AbstractKotlinFileStructureTest : JetLightCodeInsightFixtu
|
||||
|
||||
popup.setup()
|
||||
|
||||
val popupText = PlatformTestUtil.print(popup.getTree(), false)
|
||||
val printInfo = PrintInfo(array("text"), array("location"))
|
||||
val popupText = StructureViewUtil.print(popup.getTree(), false, printInfo, null)
|
||||
JetTestUtils.assertEqualsToFile(File("${FileUtil.getNameWithoutExtension(path)}.after"), popupText)
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -33,9 +33,12 @@ import org.jetbrains.jet.plugin.structureView.AbstractKotlinFileStructureTest;
|
||||
@TestMetadata("idea/testData/structureView/fileStructure")
|
||||
public class KotlinFileStructureTestGenerated extends AbstractKotlinFileStructureTest {
|
||||
public void testAllFilesPresentInFileStructure() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage",
|
||||
new File("idea/testData/structureView/fileStructure"),
|
||||
Pattern.compile("^([^\\.]+)\\.kt$"), true);
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/structureView/fileStructure"), Pattern.compile("^([^\\.]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("DoNotShowParentsInLocationJava.kt")
|
||||
public void testDoNotShowParentsInLocationJava() throws Exception {
|
||||
doTest("idea/testData/structureView/fileStructure/DoNotShowParentsInLocationJava.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("EmptyFile.kt")
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.structureView;
|
||||
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.openapi.ui.Queryable;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
|
||||
|
||||
/**
|
||||
* Extracted from PlatformTestUtil to print JTree with location string.
|
||||
*/
|
||||
public class StructureViewUtil {
|
||||
@Nullable
|
||||
protected static String toString(@Nullable Object node, @Nullable Queryable.PrintInfo printInfo) {
|
||||
if (node instanceof AbstractTreeNode) {
|
||||
return ((AbstractTreeNode) node).toTestString(printInfo);
|
||||
}
|
||||
|
||||
FilteringTreeStructure.FilteringNode filteringNode = tryCast(node, FilteringTreeStructure.FilteringNode.class);
|
||||
if (filteringNode != null && filteringNode.getDelegate() instanceof AbstractTreeNode) {
|
||||
return ((AbstractTreeNode) filteringNode.getDelegate()).toTestString(printInfo);
|
||||
}
|
||||
|
||||
if (node == null) {
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
return node.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String print(JTree tree, boolean withSelection) {
|
||||
return print(tree, withSelection, null, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String print(
|
||||
JTree tree, boolean withSelection,
|
||||
@Nullable Queryable.PrintInfo printInfo,
|
||||
@Nullable Condition<String> nodePrintCondition) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
Collection<String> strings = printAsList(tree, withSelection, printInfo, nodePrintCondition);
|
||||
for (String string : strings) {
|
||||
buffer.append(string).append("\n");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static Collection<String> printAsList(
|
||||
JTree tree, boolean withSelection,
|
||||
@Nullable Queryable.PrintInfo printInfo,
|
||||
@Nullable Condition<String> nodePrintCondition) {
|
||||
Collection<String> strings = new ArrayList<String>();
|
||||
Object root = tree.getModel().getRoot();
|
||||
printImpl(tree, root, strings, 0, withSelection, printInfo, nodePrintCondition);
|
||||
return strings;
|
||||
}
|
||||
|
||||
private static void printImpl(JTree tree,
|
||||
Object root,
|
||||
Collection<String> strings,
|
||||
int level,
|
||||
boolean withSelection,
|
||||
@Nullable Queryable.PrintInfo printInfo,
|
||||
@Nullable Condition<String> nodePrintCondition) {
|
||||
DefaultMutableTreeNode defaultMutableTreeNode = (DefaultMutableTreeNode)root;
|
||||
|
||||
Object userObject = defaultMutableTreeNode.getUserObject();
|
||||
String nodeText;
|
||||
if (userObject != null) {
|
||||
nodeText = toString(userObject, printInfo);
|
||||
}
|
||||
else {
|
||||
nodeText = "null";
|
||||
}
|
||||
|
||||
if (nodePrintCondition != null && !nodePrintCondition.value(nodeText)) return;
|
||||
|
||||
StringBuilder buff = new StringBuilder();
|
||||
StringUtil.repeatSymbol(buff, ' ', level);
|
||||
|
||||
boolean expanded = tree.isExpanded(new TreePath(defaultMutableTreeNode.getPath()));
|
||||
if (!defaultMutableTreeNode.isLeaf()) {
|
||||
buff.append(expanded ? "-" : "+");
|
||||
}
|
||||
|
||||
boolean selected = tree.getSelectionModel().isPathSelected(new TreePath(defaultMutableTreeNode.getPath()));
|
||||
if (withSelection && selected) {
|
||||
buff.append("[");
|
||||
}
|
||||
|
||||
buff.append(nodeText);
|
||||
|
||||
if (withSelection && selected) {
|
||||
buff.append("]");
|
||||
}
|
||||
|
||||
strings.add(buff.toString());
|
||||
|
||||
int childCount = tree.getModel().getChildCount(root);
|
||||
if (expanded) {
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
printImpl(tree, tree.getModel().getChild(root, i), strings, level + 1, withSelection, printInfo, nodePrintCondition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user