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