Exemplo n.º 1
0
 public static List<TreePath> collectExpandedPaths(@NotNull final JTree tree) {
   final ArrayList<TreePath> result = new ArrayList<TreePath>();
   final Object root = tree.getModel().getRoot();
   final TreePath rootPath = new TreePath(root);
   result.addAll(collectExpandedPaths(tree, rootPath));
   return result;
 }
 public void reset() {
   mySelectedSchema = new CustomActionsSchema();
   mySelectedSchema.copyFrom(CustomActionsSchema.getInstance());
   patchActionsTreeCorrespondingToSchema(
       (DefaultMutableTreeNode) myActionsTree.getModel().getRoot());
   myRestoreAllDefaultButton.setEnabled(mySelectedSchema.isModified(new CustomActionsSchema()));
 }
Exemplo n.º 3
0
 public static List<TreePath> collectExpandedPaths(final JTree tree, TreePath path) {
   final ArrayList<TreePath> result = new ArrayList<TreePath>();
   if (!tree.isExpanded(path)) return result;
   final Object lastPathComponent = path.getLastPathComponent();
   final TreeModel model = tree.getModel();
   if (model.isLeaf(lastPathComponent)) {
     result.add(path);
   } else {
     boolean pathWasAdded = false;
     for (int i = model.getChildCount(lastPathComponent) - 1; i >= 0; i--) {
       final TreePath childPath = path.pathByAddingChild(model.getChild(lastPathComponent, i));
       if (model.isLeaf(lastPathComponent)) {
         if (!pathWasAdded) {
           result.add(path);
           pathWasAdded = true;
         }
       } else if (tree.isExpanded(childPath)) {
         result.addAll(collectExpandedPaths(tree, childPath));
       } else {
         if (!pathWasAdded) {
           result.add(path);
           pathWasAdded = true;
         }
       }
     }
   }
   return result;
 }
 private void updateImmediately() {
   if (myProject.isDisposed()) return;
   checkNodeValidity((DefaultMutableTreeNode) myTree.getModel().getRoot());
   if (myUsagePreviewPanel != null) {
     myUsagePreviewPanel.updateLayout(getSelectedUsageInfos());
   }
 }
Exemplo n.º 5
0
  // reorder the nodes
  private void reorder(Vector nodes) {

    debug("reorder nodes");

    // remove all the children of topNode (they'll be added back later)
    topNode.removeAllChildren();

    // Create an array of the elements for sorting & copy the elements
    // into the array.
    DefaultMutableTreeNode[] array = new DefaultMutableTreeNode[nodes.size()];
    nodes.copyInto(array);

    // Sort the array (Quick Sort)
    quickSort(array, 0, array.length - 1);

    // Reload the topNode. Everthing is in order now.
    for (int i = 0; i < array.length; i++) {
      topNode.add((DefaultMutableTreeNode) array[i]);
    }

    // Tell the tree to repaint itself
    ((DefaultTreeModel) tree.getModel()).reload();
    tree.invalidate();
    tree.repaint();
  }
Exemplo n.º 6
0
 public static ActionCallback selectFirstNode(final JTree tree) {
   final TreeModel model = tree.getModel();
   final Object root = model.getRoot();
   TreePath selectionPath = new TreePath(root);
   if (!tree.isRootVisible() && model.getChildCount(root) > 0)
     selectionPath = selectionPath.pathByAddingChild(model.getChild(root, 0));
   return selectPath(tree, selectionPath);
 }
Exemplo n.º 7
0
 /**
  * Constructor.
  *
  * @param tree a JTree
  */
 public CheckTreeManager(JTree tree) {
   this.tree = tree;
   selectionModel = new CheckTreeSelectionModel(tree.getModel());
   tree.setCellRenderer(new CheckTreeCellRenderer(tree.getCellRenderer(), selectionModel));
   tree.addMouseListener(this);
   tree.addMouseMotionListener(this);
   selectionModel.addTreeSelectionListener(this);
 }
Exemplo n.º 8
0
  /**
   * @param tree JTree to collect expanded paths from.
   * @param paths output parameter.
   */
  public static void collectExpandedPaths(
      @NotNull final JTree tree, @NotNull final List<TreePath> paths) {
    final TreeModel model = tree.getModel();
    final Object root = model.getRoot();
    LOG.assertTrue(root != null);

    collectExpandedPathsImpl(tree, paths, new TreePath(root));
  }
 public void addSelectionPathTo(final Object element) {
   DefaultMutableTreeNode node = myAbstractTreeBuilder.getNodeForElement(element);
   if (node != null) {
     final JTree tree = getTree();
     final TreePath path = new TreePath(node.getPath());
     if (node == tree.getModel().getRoot() && !tree.isExpanded(path)) tree.expandPath(path);
     tree.addSelectionPath(path);
   }
 }
Exemplo n.º 10
0
  @Override
  public void adoptElement(SceneElement elem) {
    if (!(elem instanceof NenyaImageSceneElement
        || elem instanceof NenyaTileSceneElement
        || elem instanceof NenyaComponentSceneElement)) {
      enableEditor(false);
      return;
    }

    DefaultComboBoxModel dcm = (DefaultComboBoxModel) itemList.getModel();

    // Important: Work on a copy, not on the original. Otherwise we mess up the undomanager
    sceneElement = elem.copy();

    if ((sceneElement instanceof NenyaImageSceneElement) && !locked) {
      dcm.removeAllElements();
      String[] tmp = ((NenyaImageSceneElement) sceneElement).getPath();
      dcm.addElement(tmp[tmp.length - 1]);
    }
    if ((sceneElement instanceof NenyaTileSceneElement) && !locked) {
      dcm.removeAllElements();
      dcm.addElement(((NenyaTileSceneElement) sceneElement).getTileName());
    }
    if ((sceneElement instanceof NenyaComponentSceneElement) && !locked) {
      dcm.removeAllElements();
      NenyaComponentItem[] ni = ((NenyaComponentSceneElement) sceneElement).getComponents();
      for (NenyaComponentItem element : ni) {
        dcm.addElement(element);
      }
    }

    try {
      ClassedItem[] cols = null;
      if (elem instanceof NenyaTileSceneElement)
        cols = ((NenyaTileSceneElement) elem).getColorList();
      if (elem instanceof NenyaImageSceneElement)
        cols = ((NenyaImageSceneElement) elem).getColorList();
      if (elem instanceof NenyaComponentSceneElement) {
        NenyaComponentItem nci = (NenyaComponentItem) dcm.getSelectedItem();
        cols = nci.getColorList();
      }
      Vector<TreePath> collect = new Vector<TreePath>();
      TreeNode root = (TreeNode) colors.getModel().getRoot();
      for (ClassedItem col : cols) {
        String[] tmp = {root.toString(), col.getClassName(), col.getItemName()};
        collect.add(TreeUtil.findPath(root, tmp));
      }
      TreePath[] path = collect.toArray(new TreePath[0]);
      colors.getSelectionModel().setSelectionPaths(path);
    } catch (Exception e) {
      // Either the tree is filtered away or the selected item is not colorized.
    }

    enableEditor(true);
    itemList.setEnabled(elem instanceof NenyaComponentSceneElement);
  }
 private void patchActionsTreeCorrespondingToSchema(DefaultMutableTreeNode root) {
   root.removeAllChildren();
   if (mySelectedSchema != null) {
     mySelectedSchema.fillActionGroups(root);
     for (final ActionUrl actionUrl : mySelectedSchema.getActions()) {
       ActionUrl.changePathInActionsTree(myActionsTree, actionUrl);
     }
   }
   ((DefaultTreeModel) myActionsTree.getModel()).reload();
 }
Exemplo n.º 12
0
 public static void moveSelectedRow(final JTree tree, final int direction) {
   final TreePath selectionPath = tree.getSelectionPath();
   final DefaultMutableTreeNode treeNode =
       (DefaultMutableTreeNode) selectionPath.getLastPathComponent();
   final DefaultMutableTreeNode parent = (DefaultMutableTreeNode) treeNode.getParent();
   final int idx = parent.getIndex(treeNode);
   parent.remove(treeNode);
   parent.insert(treeNode, idx + direction);
   ((DefaultTreeModel) tree.getModel()).reload(parent);
   selectNode(tree, treeNode);
 }
Exemplo n.º 13
0
 public static void expandAll(final JTree tree) {
   tree.expandPath(new TreePath(tree.getModel().getRoot()));
   int oldRowCount = 0;
   do {
     int rowCount = tree.getRowCount();
     if (rowCount == oldRowCount) break;
     oldRowCount = rowCount;
     for (int i = 0; i < rowCount; i++) {
       tree.expandRow(i);
     }
   } while (true);
 }
Exemplo n.º 14
0
 @Nullable
 private DefaultMutableTreeNode getNodeForPath(String path) {
   Enumeration enumeration =
       ((DefaultMutableTreeNode) myTree.getModel().getRoot()).preorderEnumeration();
   while (enumeration.hasMoreElements()) {
     DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
     if (Comparing.equal(getPath(node), path)) {
       return node;
     }
   }
   return null;
 }
 @Nullable
 private DefaultMutableTreeNode findNodeOnToolbar(String actionId) {
   final TreeNode toolbar =
       ((DefaultMutableTreeNode) myActionsTree.getModel().getRoot()).getChildAt(1);
   for (int i = 0; i < toolbar.getChildCount(); i++) {
     final DefaultMutableTreeNode child = (DefaultMutableTreeNode) toolbar.getChildAt(i);
     final String childId = getActionId(child);
     if (childId != null && childId.equals(actionId)) {
       return child;
     }
   }
   return null;
 }
Exemplo n.º 16
0
 private ArrayList<DefaultMutableTreeNode> getNodesByPaths(ArrayList<String> paths) {
   final ArrayList<DefaultMutableTreeNode> result = new ArrayList<DefaultMutableTreeNode>();
   Enumeration enumeration =
       ((DefaultMutableTreeNode) myTree.getModel().getRoot()).preorderEnumeration();
   while (enumeration.hasMoreElements()) {
     DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
     final String path = getPath(node);
     if (paths.contains(path)) {
       result.add(node);
     }
   }
   return result;
 }
 private void restoreUsageExpandState(final Collection<UsageState> states) {
   // always expand the last level group
   final DefaultMutableTreeNode root = (DefaultMutableTreeNode) myTree.getModel().getRoot();
   for (int i = root.getChildCount() - 1; i >= 0; i--) {
     final DefaultMutableTreeNode child = (DefaultMutableTreeNode) root.getChildAt(i);
     if (child instanceof GroupNode) {
       final TreePath treePath = new TreePath(child.getPath());
       myTree.expandPath(treePath);
     }
   }
   myTree.getSelectionModel().clearSelection();
   for (final UsageState usageState : states) {
     usageState.restore();
   }
 }
Exemplo n.º 18
0
  private void reset(
      final Keymap keymap,
      final QuickList[] allQuickLists,
      String filter,
      @Nullable KeyboardShortcut shortcut) {
    myKeymap = keymap;

    final PathsKeeper pathsKeeper = new PathsKeeper();
    pathsKeeper.storePaths();

    myRoot.removeAllChildren();

    ActionManager actionManager = ActionManager.getInstance();
    Project project =
        CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(myComponent));
    Group mainGroup =
        ActionsTreeUtil.createMainGroup(
            project,
            myKeymap,
            allQuickLists,
            filter,
            true,
            ActionsTreeUtil.isActionFiltered(actionManager, myKeymap, shortcut, filter, true));
    if ((filter != null && filter.length() > 0 || shortcut != null)
        && mainGroup.initIds().isEmpty()) {
      mainGroup =
          ActionsTreeUtil.createMainGroup(
              project,
              myKeymap,
              allQuickLists,
              filter,
              false,
              ActionsTreeUtil.isActionFiltered(actionManager, myKeymap, shortcut, filter, false));
    }
    myRoot = ActionsTreeUtil.createNode(mainGroup);
    myMainGroup = mainGroup;
    MyModel model = (MyModel) myTree.getModel();
    model.setRoot(myRoot);
    model.nodeStructureChanged(myRoot);

    pathsKeeper.restorePaths();
  }
  // Public Methods
  public void appendNextTreeGeneration(Vector generation) {
    DefaultMutableTreeNode nextGeneration = generationNodeBuilder(generation);

    generations.add(nextGeneration);

    // If Generations contains leaf nodes (generated objects)
    // Enabled Save All Menu Item
    if (generations.getLeafCount() > 0) miSaveAll.setEnabled(true);
    else miSaveAll.setEnabled(false);

    // Update JTree View

    // affected nodes needing updating
    int[] nodeRangeToUpdate = {generations.getIndex(nextGeneration)};
    ((DefaultTreeModel) tree.getModel()).nodesWereInserted(generations, nodeRangeToUpdate);

    // Expand Parent after first child node is displayed
    if (generationNumber == 1) tree.expandRow(0);

    ++generationNumber;
  }
 private void rulesChanged() {
   ApplicationManager.getApplication().assertIsDispatchThread();
   final ArrayList<UsageState> states = new ArrayList<UsageState>();
   captureUsagesExpandState(new TreePath(myTree.getModel().getRoot()), states);
   final List<Usage> allUsages = new ArrayList<Usage>(myUsageNodes.keySet());
   Collections.sort(allUsages, USAGE_COMPARATOR);
   final Set<Usage> excludedUsages = getExcludedUsages();
   reset();
   myBuilder.setGroupingRules(getActiveGroupingRules(myProject));
   myBuilder.setFilteringRules(getActiveFilteringRules(myProject));
   ApplicationManager.getApplication()
       .runReadAction(
           new Runnable() {
             @Override
             public void run() {
               for (Usage usage : allUsages) {
                 if (!usage.isValid()) {
                   continue;
                 }
                 if (usage instanceof MergeableUsage) {
                   ((MergeableUsage) usage).reset();
                 }
                 appendUsage(usage);
               }
             }
           });
   excludeUsages(excludedUsages.toArray(new Usage[excludedUsages.size()]));
   if (myCentralPanel != null) {
     setupCentralPanel();
   }
   SwingUtilities.invokeLater(
       new Runnable() {
         @Override
         public void run() {
           if (isDisposed) return;
           restoreUsageExpandState(states);
           updateImmediately();
         }
       });
 }
Exemplo n.º 21
0
 public static void collapseAll(final JTree tree, final int keepSelectionLevel) {
   final TreePath leadSelectionPath = tree.getLeadSelectionPath();
   // Collapse all
   int row = tree.getRowCount() - 1;
   while (row >= 0) {
     tree.collapseRow(row);
     row--;
   }
   final DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot();
   tree.expandPath(new TreePath(root));
   if (leadSelectionPath != null) {
     final Object[] path = leadSelectionPath.getPath();
     final Object[] pathToSelect =
         new Object
             [path.length > keepSelectionLevel && keepSelectionLevel >= 0
                 ? keepSelectionLevel
                 : path.length];
     System.arraycopy(path, 0, pathToSelect, 0, pathToSelect.length);
     if (pathToSelect.length == 0) return;
     selectPath(tree, new TreePath(pathToSelect));
   }
 }
Exemplo n.º 22
0
  private static boolean collectExpandedPathsImpl(
      final JTree tree, final Collection<TreePath> paths, final TreePath path) {
    final TreeModel model = tree.getModel();
    final Object lastPathComponent = path.getLastPathComponent();
    if (model.isLeaf(lastPathComponent)) {
      return false;
    }

    boolean hasExpandedChildren = false;

    for (int i = model.getChildCount(lastPathComponent) - 1; i >= 0; i--) {
      hasExpandedChildren |=
          collectExpandedPathsImpl(
              tree, paths, path.pathByAddingChild(model.getChild(lastPathComponent, i)));
    }

    if (!hasExpandedChildren) {
      paths.add(path);
      return true;
    } else {
      return false;
    }
  }
Exemplo n.º 23
0
  @Nullable
  public static Range<Integer> getExpandControlRange(final JTree aTree, final TreePath path) {
    TreeModel treeModel = aTree.getModel();

    final BasicTreeUI basicTreeUI = (BasicTreeUI) aTree.getUI();
    Icon expandedIcon = basicTreeUI.getExpandedIcon();

    Range<Integer> box = null;
    if (path != null && !treeModel.isLeaf(path.getLastPathComponent())) {
      int boxWidth;
      Insets i = aTree.getInsets();

      if (expandedIcon != null) {
        boxWidth = expandedIcon.getIconWidth();
      } else {
        boxWidth = 8;
      }

      int boxLeftX = i != null ? i.left : 0;

      boolean leftToRight = aTree.getComponentOrientation().isLeftToRight();
      int depthOffset = getDepthOffset(aTree);
      int totalChildIndent = basicTreeUI.getLeftChildIndent() + basicTreeUI.getRightChildIndent();

      if (leftToRight) {
        boxLeftX +=
            ((path.getPathCount() + depthOffset - 2) * totalChildIndent
                    + basicTreeUI.getLeftChildIndent())
                - boxWidth / 2;
      }
      int boxRightX = boxLeftX + boxWidth;

      box = new Range<Integer>(boxLeftX, boxRightX);
    }
    return box;
  }
 protected void doOKAction() {
   final ActionManager actionManager = ActionManager.getInstance();
   TreeUtil.traverseDepth(
       (TreeNode) myTree.getModel().getRoot(),
       new TreeUtil.Traverse() {
         public boolean accept(Object node) {
           if (node instanceof DefaultMutableTreeNode) {
             final DefaultMutableTreeNode mutableNode = (DefaultMutableTreeNode) node;
             final Object userObject = mutableNode.getUserObject();
             if (userObject instanceof Pair) {
               String actionId = (String) ((Pair) userObject).first;
               final AnAction action = actionManager.getAction(actionId);
               Icon icon = (Icon) ((Pair) userObject).second;
               action.getTemplatePresentation().setIcon(icon);
               action.setDefaultIcon(icon == null);
               editToolbarIcon(actionId, mutableNode);
             }
           }
           return true;
         }
       });
   super.doOKAction();
   setCustomizationSchemaForCurrentProjects();
 }
 public DefaultMutableTreeNode getModelRoot() {
   return (DefaultMutableTreeNode) myTree.getModel().getRoot();
 }
Exemplo n.º 26
0
  public void init() {
    guangdong.add(foshan);
    guangdong.add(shantou);
    guangxi.add(guilin);
    guangxi.add(nanning);
    root.add(guangdong);
    root.add(guangxi);

    jf = new JFrame("树");
    tree = new JTree(root);
    // 获取JTree对应的TreeModel对象
    model = (DefaultTreeModel) tree.getModel();
    // 设置JTree可编辑
    tree.setEditable(true);
    MouseListener ml =
        new MouseAdapter() {
          // 按下鼠标时候获得被拖动的节点
          public void mousePressed(MouseEvent e) {
            // 如果需要唯一确定某个节点,必须通过TreePath来获取。
            TreePath tp = tree.getPathForLocation(e.getX(), e.getY());
            if (tp != null) {
              movePath = tp;
            }
          }
          // 鼠标松开时获得需要拖到哪个父节点
          public void mouseReleased(MouseEvent e) {
            // 根据鼠标松开时的TreePath来获取TreePath
            TreePath tp = tree.getPathForLocation(e.getX(), e.getY());

            if (tp != null && movePath != null) {
              // 阻止向子节点拖动
              if (movePath.isDescendant(tp) && movePath != tp) {
                JOptionPane.showMessageDialog(
                    jf, "目标节点是被移动节点的子节点,无法移动!", "非法操作", JOptionPane.ERROR_MESSAGE);
                return;
              }
              // 既不是向子节点移动,而且鼠标按下、松开的不是同一个节点
              else if (movePath != tp) {
                System.out.println(tp.getLastPathComponent());
                // add方法可以先将原节点从原父节点删除,再添加到新父节点中
                ((DefaultMutableTreeNode) tp.getLastPathComponent())
                    .add((DefaultMutableTreeNode) movePath.getLastPathComponent());
                movePath = null;
                tree.updateUI();
              }
            }
          }
        };
    tree.addMouseListener(ml);

    JPanel panel = new JPanel();

    addSiblingButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            // 获取选中节点
            DefaultMutableTreeNode selectedNode =
                (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
            // 如果节点为空,直接返回
            if (selectedNode == null) return;
            // 获取该选中节点的父节点
            DefaultMutableTreeNode parent = (DefaultMutableTreeNode) selectedNode.getParent();
            // 如果父节点为空,直接返回
            if (parent == null) return;
            // 创建一个新节点
            DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新节点");
            // 获取选中节点的选中索引
            int selectedIndex = parent.getIndex(selectedNode);
            // 在选中位置插入新节点
            model.insertNodeInto(newNode, parent, selectedIndex + 1);
            // --------下面代码实现显示新节点(自动展开父节点)-------
            // 获取从根节点到新节点的所有节点
            TreeNode[] nodes = model.getPathToRoot(newNode);
            // 使用指定的节点数组来创建TreePath
            TreePath path = new TreePath(nodes);
            // 显示指定TreePath
            tree.scrollPathToVisible(path);
          }
        });
    panel.add(addSiblingButton);

    addChildButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            // 获取选中节点
            DefaultMutableTreeNode selectedNode =
                (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
            // 如果节点为空,直接返回
            if (selectedNode == null) return;
            // 创建一个新节点
            DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新节点");
            // 直接通过model来添加新节点,则无需通过调用JTree的updateUI方法
            // model.insertNodeInto(newNode, selectedNode, selectedNode.getChildCount());
            // 直接通过节点添加新节点,则需要调用tree的updateUI方法
            selectedNode.add(newNode);
            // --------下面代码实现显示新节点(自动展开父节点)-------
            TreeNode[] nodes = model.getPathToRoot(newNode);
            TreePath path = new TreePath(nodes);
            tree.scrollPathToVisible(path);
            tree.updateUI();
          }
        });
    panel.add(addChildButton);

    deleteButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            DefaultMutableTreeNode selectedNode =
                (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
            if (selectedNode != null && selectedNode.getParent() != null) {
              // 删除指定节点
              model.removeNodeFromParent(selectedNode);
            }
          }
        });
    panel.add(deleteButton);

    editButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            TreePath selectedPath = tree.getSelectionPath();
            if (selectedPath != null) {
              // 编辑选中节点
              tree.startEditingAtPath(selectedPath);
            }
          }
        });
    panel.add(editButton);

    jf.add(new JScrollPane(tree));
    jf.add(panel, BorderLayout.SOUTH);
    jf.pack();
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.setVisible(true);
  }
Exemplo n.º 27
0
 /**
  * Removes last component in the current selection path.
  *
  * @param tree to remove selected node from.
  */
 public static void removeSelected(@NotNull final JTree tree) {
   final TreePath selectionPath = tree.getSelectionPath();
   if (selectionPath == null) return;
   removeLastPathComponent((DefaultTreeModel) tree.getModel(), selectionPath)
       .restoreSelection(tree);
 }
Exemplo n.º 28
0
 public static void removeLastPathComponent(
     @NotNull final JTree tree, @NotNull final TreePath pathToBeRemoved) {
   removeLastPathComponent((DefaultTreeModel) tree.getModel(), pathToBeRemoved)
       .restoreSelection(tree);
 }
Exemplo n.º 29
0
 /**
  * Expands n levels of the tree counting from the root
  *
  * @param tree to expand nodes of
  * @param levels depths of the expantion
  */
 public static void expand(JTree tree, int levels) {
   expand(tree, new TreePath(tree.getModel().getRoot()), levels);
 }
  /**
   * Constructs a X509 certificate panel.
   *
   * @param certificates <tt>X509Certificate</tt> objects
   */
  public X509CertificatePanel(Certificate[] certificates) {
    setLayout(new BorderLayout(5, 5));

    // Certificate chain list
    TransparentPanel topPanel = new TransparentPanel(new BorderLayout());
    topPanel.add(
        new JLabel(
            "<html><body><b>"
                + R.getI18NString("service.gui.CERT_INFO_CHAIN")
                + "</b></body></html>"),
        BorderLayout.NORTH);

    DefaultMutableTreeNode top = new DefaultMutableTreeNode();
    DefaultMutableTreeNode previous = top;
    for (int i = certificates.length - 1; i >= 0; i--) {
      Certificate cert = certificates[i];
      DefaultMutableTreeNode next = new DefaultMutableTreeNode(cert);
      previous.add(next);
      previous = next;
    }
    JTree tree = new JTree(top);
    tree.setBorder(new BevelBorder(BevelBorder.LOWERED));
    tree.setRootVisible(false);
    tree.setExpandsSelectedPaths(true);
    tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    tree.setCellRenderer(
        new DefaultTreeCellRenderer() {

          @Override
          public Component getTreeCellRendererComponent(
              JTree tree,
              Object value,
              boolean sel,
              boolean expanded,
              boolean leaf,
              int row,
              boolean hasFocus) {
            JLabel component =
                (JLabel)
                    super.getTreeCellRendererComponent(
                        tree, value, sel, expanded, leaf, row, hasFocus);
            if (value instanceof DefaultMutableTreeNode) {
              Object o = ((DefaultMutableTreeNode) value).getUserObject();
              if (o instanceof X509Certificate) {
                component.setText(getSimplifiedName((X509Certificate) o));
              } else {
                // We don't know how to represent this certificate type,
                // let's use the first 20 characters
                String text = o.toString();
                if (text.length() > 20) {
                  text = text.substring(0, 20);
                }
                component.setText(text);
              }
            }
            return component;
          }
        });
    tree.getSelectionModel()
        .addTreeSelectionListener(
            new TreeSelectionListener() {

              @Override
              public void valueChanged(TreeSelectionEvent e) {
                valueChangedPerformed(e);
              }
            });
    tree.setSelectionPath(
        new TreePath((((DefaultTreeModel) tree.getModel()).getPathToRoot(previous))));
    topPanel.add(tree, BorderLayout.CENTER);

    add(topPanel, BorderLayout.NORTH);

    // Certificate details pane
    Caret caret = infoTextPane.getCaret();
    if (caret instanceof DefaultCaret) {
      ((DefaultCaret) caret).setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
    }

    /*
     * Make JEditorPane respect our default font because we will be using it
     * to just display text.
     */
    infoTextPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, true);

    infoTextPane.setOpaque(false);
    infoTextPane.setEditable(false);
    infoTextPane.setContentType("text/html");
    infoTextPane.setText(toString(certificates[0]));

    final JScrollPane certScroll = new JScrollPane(infoTextPane);
    certScroll.setPreferredSize(new Dimension(300, 500));
    add(certScroll, BorderLayout.CENTER);
  }