1 17 18 package org.sape.carbon.services.swing.treetable; 19 20 33 34 import java.awt.Component ; 35 import java.awt.Dimension ; 36 import java.awt.Graphics ; 37 import java.awt.event.MouseEvent ; 38 import java.util.EventObject ; 39 40 import javax.swing.JTable ; 41 import javax.swing.JTree ; 42 import javax.swing.ListSelectionModel ; 43 import javax.swing.LookAndFeel ; 44 import javax.swing.UIManager ; 45 import javax.swing.event.ListSelectionEvent ; 46 import javax.swing.event.ListSelectionListener ; 47 import javax.swing.table.TableCellEditor ; 48 import javax.swing.table.TableCellRenderer ; 49 import javax.swing.tree.DefaultTreeCellRenderer ; 50 import javax.swing.tree.DefaultTreeSelectionModel ; 51 import javax.swing.tree.TreeCellRenderer ; 52 import javax.swing.tree.TreeModel ; 53 import javax.swing.tree.TreePath ; 54 55 65 public class JTreeTable extends JTable { 66 67 protected TreeTableCellRenderer tree; 68 69 public JTreeTable(TreeTableModel treeTableModel) { 70 super(); 71 72 tree = new TreeTableCellRenderer(treeTableModel); 74 75 super.setModel(new TreeTableModelAdapter(treeTableModel, tree)); 77 78 ListToTreeSelectionModelWrapper selectionWrapper = new 80 ListToTreeSelectionModelWrapper(); 81 tree.setSelectionModel(selectionWrapper); 82 setSelectionModel(selectionWrapper.getListSelectionModel()); 83 84 setDefaultRenderer(TreeTableModel.class, tree); 86 setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor()); 87 88 setShowGrid(false); 90 91 setIntercellSpacing(new Dimension (0, 0)); 93 94 if (tree.getRowHeight() < 1) { 97 setRowHeight(18); 99 } 100 } 101 102 107 public void updateUI() { 108 super.updateUI(); 109 if(tree != null) { 110 tree.updateUI(); 111 } 112 LookAndFeel.installColorsAndFont(this, "Tree.background", 115 "Tree.foreground", "Tree.font"); 116 } 117 118 124 public int getEditingRow() { 125 return (getColumnClass(editingColumn) == TreeTableModel.class) ? -1 : 126 editingRow; 127 } 128 129 132 public void setRowHeight(int rowHeight) { 133 super.setRowHeight(rowHeight); 134 if (tree != null && tree.getRowHeight() != rowHeight) { 135 tree.setRowHeight(getRowHeight()); 136 } 137 } 138 139 142 public JTree getTree() { 143 return tree; 144 } 145 146 149 public class TreeTableCellRenderer extends JTree implements 150 TableCellRenderer { 151 152 protected int visibleRow; 153 154 public TreeTableCellRenderer(TreeModel model) { 155 super(model); 156 } 157 158 162 public void updateUI() { 163 super.updateUI(); 164 TreeCellRenderer tcr = getCellRenderer(); 167 if (tcr instanceof DefaultTreeCellRenderer ) { 168 DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer )tcr); 169 dtcr.setTextSelectionColor(UIManager.getColor 174 ("Table.selectionForeground")); 175 dtcr.setBackgroundSelectionColor(UIManager.getColor 176 ("Table.selectionBackground")); 177 } 178 } 179 180 184 public void setRowHeight(int rowHeight) { 185 if (rowHeight > 0) { 186 super.setRowHeight(rowHeight); 187 if (JTreeTable.this != null && 188 JTreeTable.this.getRowHeight() != rowHeight) { 189 JTreeTable.this.setRowHeight(getRowHeight()); 190 } 191 } 192 } 193 194 197 public void setBounds(int x, int y, int w, int h) { 198 super.setBounds(x, 0, w, JTreeTable.this.getHeight()); 199 } 200 201 205 public void paint(Graphics g) { 206 g.translate(0, -visibleRow * getRowHeight()); 207 super.paint(g); 208 } 209 210 213 public Component getTableCellRendererComponent(JTable table, 214 Object value, 215 boolean isSelected, 216 boolean hasFocus, 217 int row, int column) { 218 if(isSelected) 219 setBackground(table.getSelectionBackground()); 220 else 221 setBackground(table.getBackground()); 222 223 visibleRow = row; 224 return this; 225 } 226 } 227 228 229 233 public class TreeTableCellEditor extends AbstractCellEditor implements 234 TableCellEditor { 235 public Component getTableCellEditorComponent(JTable table, 236 Object value, 237 boolean isSelected, 238 int r, int c) { 239 return tree; 240 } 241 242 260 public boolean isCellEditable(EventObject e) { 261 if (e instanceof MouseEvent ) { 262 for (int counter = getColumnCount() - 1; counter >= 0; 263 counter--) { 264 if (getColumnClass(counter) == TreeTableModel.class) { 265 MouseEvent me = (MouseEvent )e; 266 MouseEvent newME = new MouseEvent (tree, me.getID(), 267 me.getWhen(), me.getModifiers(), 268 me.getX() - getCellRect(0, counter, true).x, 269 me.getY(), me.getClickCount(), 270 me.isPopupTrigger()); 271 tree.dispatchEvent(newME); 272 break; 273 } 274 } 275 } 276 return false; 277 } 278 } 279 280 281 287 class ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel { 288 289 protected boolean updatingListSelectionModel; 290 291 public ListToTreeSelectionModelWrapper() { 292 super(); 293 getListSelectionModel().addListSelectionListener 294 (createListSelectionListener()); 295 } 296 297 302 ListSelectionModel getListSelectionModel() { 303 return listSelectionModel; 304 } 305 306 311 public void resetRowSelection() { 312 if(!updatingListSelectionModel) { 313 updatingListSelectionModel = true; 314 try { 315 super.resetRowSelection(); 316 } 317 finally { 318 updatingListSelectionModel = false; 319 } 320 } 321 } 327 328 331 protected ListSelectionListener createListSelectionListener() { 332 return new ListSelectionHandler(); 333 } 334 335 340 protected void updateSelectedPathsFromSelectedRows() { 341 if(!updatingListSelectionModel) { 342 updatingListSelectionModel = true; 343 try { 344 int min = listSelectionModel.getMinSelectionIndex(); 347 int max = listSelectionModel.getMaxSelectionIndex(); 348 349 clearSelection(); 350 if(min != -1 && max != -1) { 351 for(int counter = min; counter <= max; counter++) { 352 if(listSelectionModel.isSelectedIndex(counter)) { 353 TreePath selPath = tree.getPathForRow 354 (counter); 355 356 if(selPath != null) { 357 addSelectionPath(selPath); 358 } 359 } 360 } 361 } 362 } 363 finally { 364 updatingListSelectionModel = false; 365 } 366 } 367 } 368 369 373 class ListSelectionHandler implements ListSelectionListener { 374 public void valueChanged(ListSelectionEvent e) { 375 updateSelectedPathsFromSelectedRows(); 376 } 377 } 378 } 379 } 380 | Popular Tags |