void (TreeTableModel treeTableModel) {// Create the tree. It will be used as a renderer and editor. if (myTree != null) { myTree.removePropertyChangeListener(JTree.ROW_HEIGHT_PROPERTY, myTreeRowHeightPropertyListener); } myTree = new TreeTableTree(treeTableModel, this); setRowHeight(myTree.getRowHeight()); myTreeRowHeightPropertyListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { int treeRowHeight = myTree.getRowHeight(); if (treeRowHeight == getRowHeight()) return; setRowHeight(treeRowHeight); } }; myTree.addPropertyChangeListener(JTree.ROW_HEIGHT_PROPERTY, myTreeRowHeightPropertyListener); // Install a tableModel representing the visible rows in the tree. setTableModel(treeTableModel); // Force the JTable and JTree to share their row selection models. ListToTreeSelectionModelWrapper selectionWrapper = new ListToTreeSelectionModelWrapper(); myTree.setSelectionModel(selectionWrapper); setSelectionModel(selectionWrapper.getListSelectionModel()); // Install the tree editor renderer and editor. TreeTableCellRenderer treeTableCellRenderer = createTableRenderer(treeTableModel); setDefaultRenderer(TreeTableModel.class, treeTableCellRenderer); setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor(treeTableCellRenderer)); // No grid. setShowGrid(false); // No intercell spacing setIntercellSpacing(new Dimension(0, 0)); // And update the height of the trees row to match that of the table. if (myTree.getRowHeight() < 1) { setRowHeight(JBUIScale.scale(18)); // Metal looks better like this. } else { setRowHeight(getRowHeight()); } }