3

I have created a custom JTree. That tree could be filtered to show only those nodes that contains given criteria (string). Now, is there any way to bold only that part of DefaulMutableTreeNode that contains searched string?

If a tree node has label = "StackOverflow" and user is searching for nodes that contains "Stack", "StackOverflow" node would be rendered with "Stack" part bolded.

How to achieve that?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
guest86
  • 2,894
  • 8
  • 49
  • 72
  • Do you have a decent solution for that tree filtering ? I still have an [open SO question](http://stackoverflow.com/questions/9234297/filtering-on-a-jtree) on tree filtering, and wondering which approach you used – Robin Jun 11 '12 at 08:49
  • I answered your question. Code is a little complicated so i just explained the principle i used... – guest86 Jun 11 '12 at 13:01

1 Answers1

8

You need to set your own TreeCellRenderer.

Example:

The code below produces this screenshot:

screenshot

final JTextField field = new JTextField();
final JTree tree = new JTree(new String[] {"Hello World", "StackOverflow"});
tree.setCellRenderer(new DefaultTreeCellRenderer() {
    @Override
    public Component getTreeCellRendererComponent(JTree tree,
            Object value, boolean sel, boolean expanded, boolean leaf,
            int row, boolean hasFocus) {

        String search = field.getText();
        String text = value.toString();

        StringBuffer html = new StringBuffer("<html>");
        Matcher m = Pattern.compile(Pattern.quote(search)).matcher(text);
        while (m.find())
            m.appendReplacement(html, "<b>" + m.group() + "</b>");
        m.appendTail(html).append("</html>");

        return super.getTreeCellRendererComponent(
                tree, html.toString(), sel, expanded, leaf, row, hasFocus);
    }
});
field.addKeyListener(new KeyAdapter() {
    @Override public void keyReleased(KeyEvent e) { update(); }
    private void update() { 
        DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
        model.nodeStructureChanged((TreeNode) model.getRoot());
    }
});
JFrame frame = new JFrame("Test");
frame.add(field, BorderLayout.NORTH);
frame.add(tree, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);

dacwe
  • 43,066
  • 12
  • 116
  • 140
  • 1
    As mentioned, the key is to implement TreeCellRenderer to provide custom rendering of the tree nodes and use HTML in the cell text in order to easily apply style to text, like bold, italic, foreground color... – David Oliván Jun 11 '12 at 08:38