javax.swing.tree.TreeModel#getRoot ( )源码实例Demo

下面列出了javax.swing.tree.TreeModel#getRoot ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: pentaho-reporting   文件: ReportDesignerFrame.java
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 );
  }
}
 
源代码2 项目: netbeans   文件: ProfilerTreeTable.java
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();
    }
}
 
源代码3 项目: dragonwell8_jdk   文件: ElementTreePanel.java
/**
 * 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;
    }
}
 
源代码4 项目: jdk8u60   文件: ElementTreePanel.java
/**
 * 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;
    }
}
 
源代码5 项目: nextreports-designer   文件: TreeUtil.java
/**
 * 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;
}
 
源代码6 项目: openjdk-8   文件: ElementTreePanel.java
/**
 * 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;
    }
}
 
源代码7 项目: netbeans   文件: ProfilerTreeTable.java
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;
}
 
源代码8 项目: openjdk-8-source   文件: ElementTreePanel.java
/**
 * 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;
    }
}
 
源代码9 项目: java-swing-tips   文件: MainPanel.java
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));
}
 
源代码10 项目: jdk8u-jdk   文件: ElementTreePanel.java
/**
 * 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;
    }
}
 
源代码11 项目: jdk8u-dev-jdk   文件: ElementTreePanel.java
/**
 * 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;
            }
        }
    }
}
 
public String treeModelAsString(TreeModel treeModel) {
	StringBuffer sb = new StringBuffer();
	Object root = treeModel.getRoot();
	treeModelAsString(treeModel, root, sb, "");
	return sb.toString();
}
 
源代码13 项目: hottub   文件: ElementTreePanel.java
/**
 * 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;
            }
        }
    }
}
 
源代码14 项目: openjdk-8   文件: ElementTreePanel.java
/**
 * 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;
            }
        }
    }
}
 
public String treeModelAsString(TreeModel treeModel) {
	StringBuffer sb = new StringBuffer();
	Object root = treeModel.getRoot();
	treeModelAsString(treeModel, root, sb, "");
	return sb.toString();
}
 
源代码16 项目: jdk8u60   文件: ElementTreePanel.java
/**
 * 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;
            }
        }
    }
}
 
源代码17 项目: uima-uimaj   文件: CasAnnotationViewerTest.java
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);
  }
}
 
源代码18 项目: netbeans   文件: RefactoringTestCase.java
protected void browseRoot(JTree tree) {
    TreeModel model = tree.getModel();
    Object root = model.getRoot();
    browseChildren(model, root, 0);
}
 
源代码19 项目: netbeans   文件: GuiUtilities.java
/**
 * 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;
}
 
源代码20 项目: flutter-intellij   文件: InspectorTreeUI.java
@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;
    }
  }
}