void (final SimpleTree tree, final CheckboxHandler handler) { final JCheckBox checkbox = new JCheckBox(); final JPanel panel = new JPanel(new BorderLayout()); panel.add(checkbox, BorderLayout.WEST); final TreeCellRenderer baseRenderer = tree.getCellRenderer(); tree.setCellRenderer(new TreeCellRenderer() { @Override public Component getTreeCellRendererComponent(final JTree tree, final Object value, final boolean selected, final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) { final Component baseComponent = baseRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); final Object userObject = ((DefaultMutableTreeNode)value).getUserObject(); if (!handler.isVisible(userObject)) { return baseComponent; } Color foreground = UIUtil.getTreeForeground(selected, hasFocus); Color background = UIUtil.getTreeBackground(selected, hasFocus); panel.add(baseComponent, BorderLayout.CENTER); panel.setBackground(background); panel.setForeground(foreground); CheckBoxState state = handler.getState(userObject); checkbox.setSelected(state != CheckBoxState.UNCHECKED); checkbox.setEnabled(state != CheckBoxState.PARTIAL); checkbox.setBackground(background); checkbox.setForeground(foreground); return panel; } }); tree.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { int row = tree.getRowForLocation(e.getX(), e.getY()); if (row >= 0) { TreePath path = tree.getPathForRow(row); if (!isCheckboxEnabledFor(path, handler)) return; Rectangle checkBounds = checkbox.getBounds(); checkBounds.setLocation(tree.getRowBounds(row).getLocation()); if (checkBounds.contains(e.getPoint())) { tree.setSelectionRow(row); handler.toggle(path, e); e.consume(); } } } }); tree.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_SPACE) { TreePath[] treePaths = tree.getSelectionPaths(); if (treePaths != null) { for (TreePath treePath : treePaths) { if (!isCheckboxEnabledFor(treePath, handler)) continue; handler.toggle(treePath, e); } e.consume(); } } } }); }