Java Code Examples for javax.swing.tree.TreeModel#getRoot()

The following examples show how to use javax.swing.tree.TreeModel#getRoot() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ProfilerTreeTable.java    From netbeans with Apache License 2.0 6 votes vote down vote up
public void collapseAll() {
    if (tree != null) try {
        markExpansionTransaction();
        
        TreePath selected = tree.getSelectionPath();
        if (selected != null && selected.getPathCount() > 2) {
            tree.setSelectionPath(new TreePath(new Object[] {
                selected.getPathComponent(0), selected.getPathComponent(1)
            }));
        }
        
        TreeModel tmodel = tree.getModel();
        Object root = tmodel.getRoot();
        
        int nchildren = tmodel.getChildCount(root);
        for (int i = 0; i < nchildren; i++)
            tree.collapsePath(new TreePath(new Object[] {
                root, tmodel.getChild(root, i)
            }));
        
        tree.resetExpandedNodes();
    
    } finally {
        clearExpansionTransaction();
    }
}
 
Example 2
Source File: ReportDesignerFrame.java    From pentaho-reporting with GNU Lesser General Public License v2.1 6 votes vote down vote up
private void createSamplesMenu() {
  final XulMenupopup samplesPopup =
    context.getView().getXulComponent( "help-samples-popup", XulMenupopup.class );// NON-NLS
  if ( samplesPopup == null ) {
    return;
  }

  for ( final XulComponent childNode : new ArrayList<XulComponent>( samplesPopup.getChildNodes() ) ) {
    samplesPopup.removeChild( childNode );
  }

  final TreeModel treeModel = SamplesTreeBuilder.getSampleTreeModel();
  final Object root = treeModel.getRoot();
  try {
    insertReports( treeModel, root, samplesPopup );
  } catch ( XulException e ) {
    logger.warn( "Failed to initialize sample menu", e );
  }
}
 
Example 3
Source File: ElementTreePanel.java    From dragonwell8_jdk with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Updates the tree based on the event type. This will invoke either
 * updateTree with the root element, or handleChange.
 */
protected void updateTree(DocumentEvent event) {
    updatingSelection = true;
    try {
        TreeModel model = getTreeModel();
        Object root = model.getRoot();

        for (int counter = model.getChildCount(root) - 1; counter >= 0;
                counter--) {
            updateTree(event, (Element) model.getChild(root, counter));
        }
    } finally {
        updatingSelection = false;
    }
}
 
Example 4
Source File: ElementTreePanel.java    From jdk8u-jdk with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Updates the tree based on the event type. This will invoke either
 * updateTree with the root element, or handleChange.
 */
protected void updateTree(DocumentEvent event) {
    updatingSelection = true;
    try {
        TreeModel model = getTreeModel();
        Object root = model.getRoot();

        for (int counter = model.getChildCount(root) - 1; counter >= 0;
                counter--) {
            updateTree(event, (Element) model.getChild(root, counter));
        }
    } finally {
        updatingSelection = false;
    }
}
 
Example 5
Source File: MainPanel.java    From java-swing-tips with MIT License 5 votes vote down vote up
private MainPanel() {
  super(new BorderLayout());
  JTree tree = new JTree() {
    @Override public void updateUI() {
      setCellRenderer(null);
      setCellEditor(null);
      super.updateUI();
      // ???#1: JDK 1.6.0 bug??? Nimbus LnF
      setCellRenderer(new CheckBoxNodeRenderer());
      setCellEditor(new CheckBoxNodeEditor());
    }
  };
  TreeModel model = tree.getModel();
  DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
  // Java 9: Collections.list(root.breadthFirstEnumeration()).stream()
  Collections.list((Enumeration<?>) root.breadthFirstEnumeration()).stream()
      .filter(DefaultMutableTreeNode.class::isInstance)
      .map(DefaultMutableTreeNode.class::cast)
      .filter(TreeNode::isLeaf)
      .forEach(node -> {
        boolean isEven = node.getParent().getIndex(node) % 2 == 0;
        node.setUserObject(new CheckBoxNode(Objects.toString(node.getUserObject(), ""), isEven));
      });

  tree.setEditable(true);
  tree.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));

  for (int i = 0; i < tree.getRowCount(); i++) {
    tree.expandRow(i);
  }

  setBorder(BorderFactory.createTitledBorder("JCheckBoxes as JTree Leaf Nodes"));
  add(new JScrollPane(tree));
  setPreferredSize(new Dimension(320, 240));
}
 
Example 6
Source File: ElementTreePanel.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Updates the tree based on the event type. This will invoke either
 * updateTree with the root element, or handleChange.
 */
protected void updateTree(DocumentEvent event) {
    updatingSelection = true;
    try {
        TreeModel model = getTreeModel();
        Object root = model.getRoot();

        for (int counter = model.getChildCount(root) - 1; counter >= 0;
                counter--) {
            updateTree(event, (Element) model.getChild(root, counter));
        }
    } finally {
        updatingSelection = false;
    }
}
 
Example 7
Source File: ProfilerTreeTable.java    From netbeans with Apache License 2.0 5 votes vote down vote up
private TreePath getSimilarPath(TreePath oldPath) {
    if (oldPath == null || oldPath.getPathCount() < 1) return null;

    TreeModel currentModel = getModel();
    Object currentRoot = currentModel.getRoot();
    if (!currentRoot.equals(oldPath.getPathComponent(0))) return null;

    TreePath p = new TreePath(currentRoot);
    Object[] op = oldPath.getPath();
    Object n = currentRoot;

    for (int i = 1; i < op.length; i++) {
        Object nn = null;

        for (int ii = 0; ii < currentModel.getChildCount(n); ii++) {
            Object c = currentModel.getChild(n, ii);
            if (c.equals(op[i])) {
                nn = c;
                break;
            }
        }

        if (nn == null) return null;

        n = nn;
        p = p.pathByAddingChild(n);
    }

    return p;
}
 
Example 8
Source File: ElementTreePanel.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Updates the tree based on the event type. This will invoke either
 * updateTree with the root element, or handleChange.
 */
protected void updateTree(DocumentEvent event) {
    updatingSelection = true;
    try {
        TreeModel model = getTreeModel();
        Object root = model.getRoot();

        for (int counter = model.getChildCount(root) - 1; counter >= 0;
                counter--) {
            updateTree(event, (Element) model.getChild(root, counter));
        }
    } finally {
        updatingSelection = false;
    }
}
 
Example 9
Source File: TreeUtil.java    From nextreports-designer with Apache License 2.0 5 votes vote down vote up
/**
 * Search for a path in the specified tree model, whose nodes have
 * the same name (compared using <code>equals()</code>)
 * as the ones specified in the old path.
 *
 * @return a new path for the specified model, or null if no such path
 *         could be found.
 */
public static TreePath searchPath(TreeModel model, TreePath oldPath) {
    Object treenode = model.getRoot();
    Object[] oldPathNodes = oldPath.getPath();
    TreePath newPath = new TreePath(treenode);
    for (int i = 0; i < oldPathNodes.length; ++i) {
        Object oldPathNode = oldPathNodes[i];
        if (treenode.toString().equals(oldPathNode.toString())) {
            if (i == (oldPathNodes.length - 1)) {
                return newPath;
            } else {
                if (model.isLeaf(treenode)) {
                    return null; // not found
                } else {
                    int count = model.getChildCount(treenode);
                    boolean foundChild = false;
                    for (int j = 0; j < count; ++j) {
                        Object child = model.getChild(treenode, j);
                        if (child.toString().equals(oldPathNodes[i + 1].toString())) {
                            newPath = newPath.pathByAddingChild(child);
                            treenode = child;
                            foundChild = true;
                            break;
                        }
                    }
                    if (!foundChild) {
                        return null; // couldn't find child with same name
                    }
                }
            }
        }
    }
    return null;
}
 
Example 10
Source File: ElementTreePanel.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Updates the tree based on the event type. This will invoke either
 * updateTree with the root element, or handleChange.
 */
protected void updateTree(DocumentEvent event) {
    updatingSelection = true;
    try {
        TreeModel model = getTreeModel();
        Object root = model.getRoot();

        for (int counter = model.getChildCount(root) - 1; counter >= 0;
                counter--) {
            updateTree(event, (Element) model.getChild(root, counter));
        }
    } finally {
        updatingSelection = false;
    }
}
 
Example 11
Source File: CasAnnotationViewerTest.java    From uima-uimaj with Apache License 2.0 4 votes vote down vote up
public void testAddAnnotationToTree() throws Exception {
  try {
    // create an annotation
    createExampleFS(this.cas);
    FSIterator iter = this.cas.getAnnotationIndex(exampleType).iterator();
    AnnotationFS annot = (AnnotationFS) iter.get();

    // init viewer
    viewer.setCAS(this.cas);

    // add to tree
    viewer.addAnnotationToTree(annot);

    // inspect results
    TreeModel model = viewer.getSelectedAnnotationTree().getModel();
    DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
    assertEquals("Annotations", root.getUserObject().toString());
    DefaultMutableTreeNode typeNode = (DefaultMutableTreeNode) root.getChildAt(0);
    assertEquals("Example", typeNode.getUserObject().toString());
    DefaultMutableTreeNode fsNode = (DefaultMutableTreeNode) typeNode.getChildAt(0);
    Enumeration children = fsNode.children();
    assertEquals("begin = 1", ((DefaultMutableTreeNode) children.nextElement()).getUserObject()
            .toString());
    assertEquals("end = 5", ((DefaultMutableTreeNode) children.nextElement()).getUserObject()
            .toString());
    assertEquals("floatFeature = " + (float) 99.99, ((DefaultMutableTreeNode) children
            .nextElement()).getUserObject().toString());
    assertEquals("stringFeature = aaaaaaa", ((DefaultMutableTreeNode) children.nextElement())
            .getUserObject().toString());
    assertEquals("boolFeature = true", ((DefaultMutableTreeNode) children.nextElement())
            .getUserObject().toString());
    assertEquals("byteFeature = 122", ((DefaultMutableTreeNode) children.nextElement())
            .getUserObject().toString());
    assertEquals("shortFeature = " + Short.MIN_VALUE, ((DefaultMutableTreeNode) children
            .nextElement()).getUserObject().toString());
    assertEquals("longFeature = " + Long.MIN_VALUE, ((DefaultMutableTreeNode) children
            .nextElement()).getUserObject().toString());
    assertEquals("doubleFeature = " + Double.MAX_VALUE, ((DefaultMutableTreeNode) children
            .nextElement()).getUserObject().toString());

    assertEquals("intArrayFeature = [" + Integer.MAX_VALUE + "," + (Integer.MAX_VALUE - 1)
            + ",42," + (Integer.MIN_VALUE + 1) + "," + Integer.MIN_VALUE + "]",
            ((DefaultMutableTreeNode) children.nextElement()).getUserObject().toString());
    assertEquals("floatArrayFeature = [" + Float.MAX_VALUE + ","
            + (float) (Float.MAX_VALUE / 1000.0) + "," + 42.0 + ","
            + (float) (Float.MIN_VALUE * 1000) + "," + Float.MIN_VALUE + "]",
            ((DefaultMutableTreeNode) children.nextElement()).getUserObject().toString());
    assertEquals("stringArrayFeature = [zzzzzz,yyyyyy,xxxxxx,wwwwww,vvvvvv]",
            ((DefaultMutableTreeNode) children.nextElement()).getUserObject().toString());
    assertEquals("boolArrayFeature = [true,false,true,false,true,false,true,false]",
            ((DefaultMutableTreeNode) children.nextElement()).getUserObject().toString());
    assertEquals("byteArrayFeature = [8,16,64,-128,-1]", ((DefaultMutableTreeNode) children
            .nextElement()).getUserObject().toString());
    assertEquals("shortArrayFeature = [" + Short.MAX_VALUE + "," + (Short.MAX_VALUE - 1) + ","
            + (Short.MAX_VALUE - 2) + "," + (Short.MAX_VALUE - 3) + "," + (Short.MAX_VALUE - 4)
            + "]", ((DefaultMutableTreeNode) children.nextElement()).getUserObject().toString());
    assertEquals("longArrayFeature = [" + Long.MAX_VALUE + "," + (Long.MAX_VALUE - 1) + ","
            + (Long.MAX_VALUE - 2) + "," + (Long.MAX_VALUE - 3) + "," + (Long.MAX_VALUE - 4)
            + "]", ((DefaultMutableTreeNode) children.nextElement()).getUserObject().toString());
    assertEquals("doubleArrayFeature = [" + Double.MAX_VALUE + "," + Double.MIN_VALUE + ","
            + Double.parseDouble("1.5555") + "," + Double.parseDouble("99.000000005") + ","
            + Double.parseDouble("4.44444444444444444") + "]", ((DefaultMutableTreeNode) children
            .nextElement()).getUserObject().toString());

  } catch (Exception e) {
    JUnitExtension.handleException(e);
  }
}
 
Example 12
Source File: RefactoringTestCase.java    From netbeans with Apache License 2.0 4 votes vote down vote up
protected void browseRoot(JTree tree) {
    TreeModel model = tree.getModel();
    Object root = model.getRoot();
    browseChildren(model, root, 0);
}
 
Example 13
Source File: GuiUtilities.java    From netbeans with Apache License 2.0 4 votes vote down vote up
/**
 * Creates a testing project.
 * @param projectName name of project
 * @param workDir working directory for project
 * @return path to project directory
 */
public static String createProject(String projectName, String workDir) {
    NewProjectWizardOperator opc = NewProjectWizardOperator.invoke();
    
    // close project if it exits (it was not closed during last test)
    ProjectsTabOperator pto = new ProjectsTabOperator();
    JTreeOperator tree = pto.tree();        

    TreeModel tm = tree.getModel();
    Object root = tm.getRoot();
    for (int i=0; i<tm.getChildCount(root); i++) {
        // if project is opened, close it, it may be opened several times
        // by mistake, so go through all cases
        if ((tm.getChild(root, i).toString().equals(projectName)) ||
        (tm.getChild(root, i).toString().equals(projectName+" [Main]"))) {
                Node pn = new ProjectsTabOperator().getProjectRootNode(
                        tm.getChild(root, i).toString());
                pn.select();
                pn.performPopupAction(
                        org.netbeans.jellytools.Bundle.getString(
                        "org.openide.nodes.Bundle", "Button_close"));
                i--; 
                Utilities.takeANap(1000);
        }            
    }
    
    // delete workdir if it exists (it was not deleted during last test)
    File f = new File(workDir);
    if (f.exists()) {
        Utilities.deleteDirectory(f);
    }
    
    // wait till all fields are loaded
    JDialogOperator jdo = new JDialogOperator(
            org.netbeans.jellytools.Bundle.getString(
            "org.netbeans.modules.project.ui.Bundle",
            "LBL_NewProjectWizard_Title"));
    JTreeOperator jto = new JTreeOperator(jdo, 0);
    
    boolean exitLoop = false;
    System.out.println("Waiting for 'General'");
    for (int i=0; i<20; i++) {
        System.out.println("Round "+i);
        Utilities.takeANap(2000);
        for (int j=0; j<jto.getChildCount(jto.getRoot()); j++) {
            if (jto.getChild(jto.getRoot(), j).toString() == Bundle.getString(
                    "org.netbeans.modules.java.j2seproject.ui.wizards.Bundle",
                    "Templates/Project/AntJava")) {
                exitLoop = true;
                System.out.println("General found");
                break;
            }
        }
        if (exitLoop) break;
    }
    
    new Node(jto, Bundle.getString(
            "org.netbeans.modules.java.j2seproject.ui.wizards.Bundle",
            "Templates/Project/AntJava")).select();
    // java project
    opc.selectProject(Bundle.getString(
            "org.netbeans.modules.java.j2seproject.ui.wizards.Bundle",
            "TXT_NewJavaApp"));
    opc.next();
    
    // set project name, no main class, created in workdir
    NewJavaProjectNameLocationStepOperator npnlso = new
            NewJavaProjectNameLocationStepOperator();
    npnlso.txtProjectName().setText(projectName);
    npnlso.cbCreateMainClass().setSelected(false);
    npnlso.txtProjectLocation().setText(workDir);
    npnlso.finish();
    
    String projectDir = workDir+"/"+projectName;
    
    //ProjectSupport.waitScanFinished();
    
    // "Scanning Project Classpaths" - NO MORE IN 4.2
    /* String titleScanning = Bundle.getString(
            "org.netbeans.modules.javacore.Bundle",
            "TXT_ApplyingPathsTitle");
    NbDialogOperator scanningDialogOper = new NbDialogOperator(titleScanning);
    
    // scanning can last for a long time => wait max. 5 minutes
    scanningDialogOper.getTimeouts().setTimeout(
            "ComponentOperator.WaitStateTimeout", 300000);
    scanningDialogOper.waitClosed(); */
    
    // wait project appear in projects view
    new EventTool().waitNoEvent(3000);
    new ProjectsTabOperator().getProjectRootNode(projectName);
    
    return projectDir;
}
 
Example 14
Source File: ElementTreePanel.java    From jdk8u60 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Messaged when the selection in the editor has changed. Will update
 * the selection in the tree.
 */
public void caretUpdate(CaretEvent e) {
    if (!updatingSelection) {
        int selBegin = Math.min(e.getDot(), e.getMark());
        int end = Math.max(e.getDot(), e.getMark());
        List<TreePath> paths = new ArrayList<TreePath>();
        TreeModel model = getTreeModel();
        Object root = model.getRoot();
        int rootCount = model.getChildCount(root);

        // Build an array of all the paths to all the character elements
        // in the selection.
        for (int counter = 0; counter < rootCount; counter++) {
            int start = selBegin;

            while (start <= end) {
                TreePath path = getPathForIndex(start, root,
                        (Element) model.getChild(root, counter));
                Element charElement = (Element) path.getLastPathComponent();

                paths.add(path);
                if (start >= charElement.getEndOffset()) {
                    start++;
                } else {
                    start = charElement.getEndOffset();
                }
            }
        }

        // If a path was found, select it (them).
        int numPaths = paths.size();

        if (numPaths > 0) {
            TreePath[] pathArray = new TreePath[numPaths];

            paths.toArray(pathArray);
            updatingSelection = true;
            try {
                getTree().setSelectionPaths(pathArray);
                getTree().scrollPathToVisible(pathArray[0]);
            } finally {
                updatingSelection = false;
            }
        }
    }
}
 
Example 15
Source File: ProcessorNames.java    From incubator-taverna-language with Apache License 2.0 4 votes vote down vote up
public String treeModelAsString(TreeModel treeModel) {
	StringBuffer sb = new StringBuffer();
	Object root = treeModel.getRoot();
	treeModelAsString(treeModel, root, sb, "");
	return sb.toString();
}
 
Example 16
Source File: ElementTreePanel.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Messaged when the selection in the editor has changed. Will update
 * the selection in the tree.
 */
public void caretUpdate(CaretEvent e) {
    if (!updatingSelection) {
        int selBegin = Math.min(e.getDot(), e.getMark());
        int end = Math.max(e.getDot(), e.getMark());
        List<TreePath> paths = new ArrayList<TreePath>();
        TreeModel model = getTreeModel();
        Object root = model.getRoot();
        int rootCount = model.getChildCount(root);

        // Build an array of all the paths to all the character elements
        // in the selection.
        for (int counter = 0; counter < rootCount; counter++) {
            int start = selBegin;

            while (start <= end) {
                TreePath path = getPathForIndex(start, root,
                        (Element) model.getChild(root, counter));
                Element charElement = (Element) path.getLastPathComponent();

                paths.add(path);
                if (start >= charElement.getEndOffset()) {
                    start++;
                } else {
                    start = charElement.getEndOffset();
                }
            }
        }

        // If a path was found, select it (them).
        int numPaths = paths.size();

        if (numPaths > 0) {
            TreePath[] pathArray = new TreePath[numPaths];

            paths.toArray(pathArray);
            updatingSelection = true;
            try {
                getTree().setSelectionPaths(pathArray);
                getTree().scrollPathToVisible(pathArray[0]);
            } finally {
                updatingSelection = false;
            }
        }
    }
}
 
Example 17
Source File: ElementTreePanel.java    From hottub with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Messaged when the selection in the editor has changed. Will update
 * the selection in the tree.
 */
public void caretUpdate(CaretEvent e) {
    if (!updatingSelection) {
        int selBegin = Math.min(e.getDot(), e.getMark());
        int end = Math.max(e.getDot(), e.getMark());
        List<TreePath> paths = new ArrayList<TreePath>();
        TreeModel model = getTreeModel();
        Object root = model.getRoot();
        int rootCount = model.getChildCount(root);

        // Build an array of all the paths to all the character elements
        // in the selection.
        for (int counter = 0; counter < rootCount; counter++) {
            int start = selBegin;

            while (start <= end) {
                TreePath path = getPathForIndex(start, root,
                        (Element) model.getChild(root, counter));
                Element charElement = (Element) path.getLastPathComponent();

                paths.add(path);
                if (start >= charElement.getEndOffset()) {
                    start++;
                } else {
                    start = charElement.getEndOffset();
                }
            }
        }

        // If a path was found, select it (them).
        int numPaths = paths.size();

        if (numPaths > 0) {
            TreePath[] pathArray = new TreePath[numPaths];

            paths.toArray(pathArray);
            updatingSelection = true;
            try {
                getTree().setSelectionPaths(pathArray);
                getTree().scrollPathToVisible(pathArray[0]);
            } finally {
                updatingSelection = false;
            }
        }
    }
}
 
Example 18
Source File: ProcessorNames.java    From incubator-taverna-language with Apache License 2.0 4 votes vote down vote up
public String treeModelAsString(TreeModel treeModel) {
	StringBuffer sb = new StringBuffer();
	Object root = treeModel.getRoot();
	treeModelAsString(treeModel, root, sb, "");
	return sb.toString();
}
 
Example 19
Source File: ElementTreePanel.java    From jdk8u-dev-jdk with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Messaged when the selection in the editor has changed. Will update
 * the selection in the tree.
 */
public void caretUpdate(CaretEvent e) {
    if (!updatingSelection) {
        int selBegin = Math.min(e.getDot(), e.getMark());
        int end = Math.max(e.getDot(), e.getMark());
        List<TreePath> paths = new ArrayList<TreePath>();
        TreeModel model = getTreeModel();
        Object root = model.getRoot();
        int rootCount = model.getChildCount(root);

        // Build an array of all the paths to all the character elements
        // in the selection.
        for (int counter = 0; counter < rootCount; counter++) {
            int start = selBegin;

            while (start <= end) {
                TreePath path = getPathForIndex(start, root,
                        (Element) model.getChild(root, counter));
                Element charElement = (Element) path.getLastPathComponent();

                paths.add(path);
                if (start >= charElement.getEndOffset()) {
                    start++;
                } else {
                    start = charElement.getEndOffset();
                }
            }
        }

        // If a path was found, select it (them).
        int numPaths = paths.size();

        if (numPaths > 0) {
            TreePath[] pathArray = new TreePath[numPaths];

            paths.toArray(pathArray);
            updatingSelection = true;
            try {
                getTree().setSelectionPaths(pathArray);
                getTree().scrollPathToVisible(pathArray[0]);
            } finally {
                updatingSelection = false;
            }
        }
    }
}
 
Example 20
Source File: InspectorTreeUI.java    From flutter-intellij with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
@Override
protected void paintVerticalPartOfLeg(final Graphics g, final Rectangle clipBounds, final Insets insets, final TreePath path) {
  final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
  if (node.getChildCount() < 2) {
    // We could draw lines for nodes with a single child but we omit them
    // to more of an emphasis of lines for nodes with multiple children.
    return;
  }
  final DiagnosticsNode diagnostic = maybeGetDiagnostic(node);
  if (diagnostic != null && !diagnostic.hasChildren()) {
    // This avoids drawing lines for nodes with only property children.
    return;
  }

  final int depth = path.getPathCount() - 1;
  if (depth == 0 && !getShowsRootHandles() && !isRootVisible()) {
    return;
  }

  int lineX = getRowX(-1, depth);
  if (leftToRight) {
    lineX = lineX - getRightChildIndent() + insets.left;
  }
  else {
    lineX = tree.getWidth() - lineX - insets.right +
            getRightChildIndent() - 1;
  }
  final int clipLeft = clipBounds.x;
  final int clipRight = clipBounds.x + (clipBounds.width - 1);

  if (lineX >= clipLeft && lineX <= clipRight) {
    final int clipTop = clipBounds.y;
    final int clipBottom = clipBounds.y + clipBounds.height;
    Rectangle parentBounds = getPathBounds(tree, path);
    boolean previousDashed = false;

    int top;
    if (parentBounds == null) {
      top = Math.max(insets.top + getVerticalLegBuffer(),
                     clipTop);
    }
    else {
      top = Math.max(parentBounds.y + parentBounds.height +
                     getVerticalLegBuffer(), clipTop);
    }

    if (depth == 0 && !isRootVisible()) {
      final TreeModel model = getModel();

      if (model != null) {
        final Object root = model.getRoot();

        if (model.getChildCount(root) > 0) {
          parentBounds = getPathBounds(tree, path.
            pathByAddingChild(model.getChild(root, 0)));
          if (parentBounds != null) {
            top = Math.max(insets.top + getVerticalLegBuffer(),
                           parentBounds.y +
                           parentBounds.height / 2);
          }
        }
      }
    }

    for (int i = 0; i < node.getChildCount(); ++i) {
      final DefaultMutableTreeNode child = (DefaultMutableTreeNode)node.getChildAt(i);
      final DiagnosticsNode childDiagnostic = maybeGetDiagnostic(child);
      boolean dashed = false;
      if (childDiagnostic != null) {
        dashed = childDiagnostic.getStyle() == DiagnosticsTreeStyle.offstage;
      }

      final Rectangle childBounds = getPathBounds(tree, path.pathByAddingChild(child));
      if (childBounds == null)
      // This shouldn't happen, but if the model is modified
      // in another thread it is possible for this to happen.
      // Swing isn't multithreaded, but I'll add this check in
      // anyway.
      {
        continue;
      }

      final int bottom = Math.min(childBounds.y +
                                  (childBounds.height / 2), clipBottom);

      if (top <= bottom && bottom >= clipTop && top <= clipBottom) {
        g.setColor(JBColor.GRAY);
        paintVerticalLine(g, tree, lineX, top, bottom, dashed);
      }
      top = bottom;
      previousDashed = dashed;
    }
  }
}