JTree () { DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(); String groupName = ""; DefaultMutableTreeNode groupNode = null; List<BooleanOptionKey> result = sortOptions(orderByGroup(myKeys)); for (BooleanOptionKey key : result) { String newGroupName = key.groupName; if (!newGroupName.equals(groupName) || groupNode == null) { groupName = newGroupName; groupNode = new DefaultMutableTreeNode(newGroupName); rootNode.add(groupNode); } if (isOptionVisible(key)) { groupNode.add(new MyToggleTreeNode(key, key.title)); } } DefaultTreeModel model = new DefaultTreeModel(rootNode); final Tree optionsTree = new Tree(model); TreeSpeedSearch speedSearch = TreeSpeedSearch.installOn( optionsTree, true, path -> { final Object lastPathComponent = path.getLastPathComponent(); return lastPathComponent instanceof MyToggleTreeNode ? ((MyToggleTreeNode)lastPathComponent).getText() : lastPathComponent.toString(); }); mySearchHelper = new SpeedSearchHelper(speedSearch); speedSearch.setComparator(new SpeedSearchComparator(false)); TreeUtil.installActions(optionsTree); optionsTree.setRootVisible(false); optionsTree.setShowsRootHandles(true); optionsTree.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (!optionsTree.isEnabled()) return; if (e.getKeyCode() == KeyEvent.VK_SPACE) { TreePath treePath = optionsTree.getLeadSelectionPath(); selectCheckbox(treePath); e.consume(); } } }); new ClickListener() { @Override public boolean onClick(@NotNull MouseEvent e, int clickCount) { if (!optionsTree.isEnabled()) return false; TreePath treePath = optionsTree.getPathForLocation(e.getX(), e.getY()); selectCheckbox(treePath); return true; } }.installOn(optionsTree); int row = 0; while (row < optionsTree.getRowCount()) { optionsTree.expandRow(row); row++; } optionsTree.setCellRenderer(new MyTreeCellRenderer(mySearchHelper)); optionsTree.setBackground(UIUtil.getPanelBackground()); optionsTree.setBorder(JBUI.Borders.emptyRight(10)); return optionsTree; }