001 /* JAPI - (Yet another (hopefully) useful) Java API 002 * 003 * Copyright (C) 2004-2006 Christian Hujer 004 * 005 * This program is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU General Public License as 007 * published by the Free Software Foundation; either version 2 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, but 011 * WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program; if not, write to the Free Software 017 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 * 02111-1307, USA. 019 */ 020 021 package net.sf.japi.swing.treetable; 022 023 import java.awt.Component; 024 import java.awt.Dimension; 025 import java.awt.Graphics; 026 import javax.swing.AbstractCellEditor; 027 import javax.swing.JTable; 028 import javax.swing.JTree; 029 import javax.swing.table.TableCellEditor; 030 import javax.swing.table.TableCellRenderer; 031 import javax.swing.tree.DefaultTreeSelectionModel; 032 import javax.swing.tree.TreeModel; 033 034 /** This example shows how to create a simple JTreeTable component, 035 * by using a JTree as a renderer (and editor) for the cells in a 036 * particular column in the JTable. 037 * @warning DO NOT RELY ON THE INHERITANCE! 038 */ 039 public class JTreeTable<R, T> extends JTable { 040 041 /** TreeTableCellRenderer. */ 042 private TreeTableCellRenderer tree; 043 044 /** The TreeTableModel for this JTreeTable. */ 045 private TreeTableModel<R, T> treeTableModel; 046 047 /** Create a JTreeTable. */ 048 public JTreeTable(final TreeTableModel<R, T> treeTableModel) { 049 this.treeTableModel = treeTableModel; 050 tree = new TreeTableCellRenderer(new TreeTableModelTreeModelAdapter<R, T>(treeTableModel)); 051 super.setModel(new TreeTableModelTableModelAdapter(treeTableModel, tree)); 052 053 // Force the JTable and JTree to share their row selection models. 054 tree.setSelectionModel(new DefaultTreeSelectionModel() { 055 { 056 setSelectionModel(listSelectionModel); 057 } 058 }); 059 // Make the tree and table row heights the same. 060 tree.setRowHeight(getRowHeight()); 061 062 // Install the tree editor renderer and editor. 063 setDefaultRenderer(TreeTableModel.class, tree); 064 setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor()); 065 066 setShowGrid(false); 067 setIntercellSpacing(new Dimension(0, 0)); 068 } 069 070 /** Returns the TreeTableModel for this JTreeTable. 071 * @return the TreeTableModel for this JTreeTable. 072 */ 073 public TreeTableModel<R, T> getTreeTableModel() { 074 return treeTableModel; 075 } 076 077 /* Workaround for BasicTableUI anomaly. Make sure the UI never tries to 078 * paint the editor. The UI currently uses different techniques to 079 * paint the renderers and editors and overriding setBounds() below 080 * is not the right thing to do for an editor. Returning -1 for the 081 * editing row in this case, ensures the editor is never painted. 082 */ 083 @Override public int getEditingRow() { 084 return getColumnClass(editingColumn) == TreeTableModel.class ? -1 : editingRow; 085 } 086 087 /** Sets the TreeTableModel for this JTreeTable. 088 * @param treeTableModel the TreeTableModel for this JTreeTable. 089 */ 090 public void setTreeTableModel(final TreeTableModel<R, T> treeTableModel) { 091 this.treeTableModel = treeTableModel; 092 super.setModel(new TreeTableModelTableModelAdapter(treeTableModel, tree)); 093 } 094 095 /** Renderer for TreeTableCells. */ 096 public class TreeTableCellRenderer extends JTree implements TableCellRenderer { 097 098 private int visibleRow; 099 100 public TreeTableCellRenderer(final TreeModel model) { 101 super(model); 102 } 103 104 @Override public void setBounds(final int x, final int y, final int width, final int height) { 105 super.setBounds(x, 0, width, JTreeTable.this.getHeight()); 106 } 107 108 @Override public void paint(final Graphics g) { 109 g.translate(0, -visibleRow * getRowHeight()); 110 super.paint(g); 111 } 112 113 public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) { 114 if (isSelected) { 115 setBackground(table.getSelectionBackground()); 116 } else { 117 setBackground(table.getBackground()); 118 } 119 120 visibleRow = row; 121 return this; 122 } 123 124 } // class TreeTableCellRenderer 125 126 /** Editor for TreeTableCells. */ 127 public class TreeTableCellEditor extends AbstractCellEditor implements TableCellEditor { 128 129 /** {@inheritDoc} */ 130 public Component getTableCellEditorComponent(final JTable table, final Object value, final boolean isSelected, final int row, final int column) { 131 return tree; 132 } 133 134 /** {@inheritDoc} */ 135 public Object getCellEditorValue() { 136 return ""; //TODO 137 } 138 139 } // class TreeTableCellEditor 140 141 } // class JTreeTable