1 20 33 34 package com.puppycrawl.tools.checkstyle.gui; 35 36 import java.awt.Component ; 37 import java.awt.Dimension ; 38 import java.awt.Graphics ; 39 import java.awt.event.ActionEvent ; 40 import java.awt.event.MouseEvent ; 41 import java.util.EventObject ; 42 import javax.swing.Action ; 43 import javax.swing.AbstractAction ; 44 import javax.swing.JTable ; 45 import javax.swing.JTree ; 46 import javax.swing.KeyStroke ; 47 import javax.swing.ListSelectionModel ; 48 import javax.swing.LookAndFeel ; 49 import javax.swing.UIManager ; 50 import javax.swing.event.ListSelectionEvent ; 51 import javax.swing.event.ListSelectionListener ; 52 import javax.swing.table.TableCellEditor ; 53 import javax.swing.table.TableCellRenderer ; 54 import javax.swing.tree.DefaultTreeCellRenderer ; 55 import javax.swing.tree.DefaultTreeSelectionModel ; 56 import javax.swing.tree.TreeCellRenderer ; 57 import javax.swing.tree.TreeModel ; 58 import javax.swing.tree.TreePath ; 59 60 71 public class JTreeTable extends JTable 72 { 73 74 protected TreeTableCellRenderer tree; 75 76 public JTreeTable(TreeTableModel treeTableModel) 77 { 78 super(); 79 80 tree = new TreeTableCellRenderer(treeTableModel); 82 83 super.setModel(new TreeTableModelAdapter(treeTableModel, tree)); 85 86 final ListToTreeSelectionModelWrapper selectionWrapper = new 88 ListToTreeSelectionModelWrapper(); 89 tree.setSelectionModel(selectionWrapper); 90 setSelectionModel(selectionWrapper.getListSelectionModel()); 91 92 setDefaultRenderer(TreeTableModel.class, tree); 94 setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor()); 95 96 setShowGrid(false); 98 99 setIntercellSpacing(new Dimension (0, 0)); 101 102 if (tree.getRowHeight() < 1) { 105 setRowHeight(getRowHeight()); 107 } 108 109 final Action expand = new AbstractAction () { 110 public void actionPerformed(ActionEvent e) { 111 TreePath selected = tree.getSelectionPath(); 112 if (tree.isExpanded(selected)) { 113 tree.collapsePath(selected); 114 } 115 else { 116 tree.expandPath(selected); 117 } 118 tree.setSelectionPath(selected); 119 } 120 }; 121 final KeyStroke stroke = KeyStroke.getKeyStroke("ENTER"); 122 final String command = "expand/collapse"; 123 getInputMap().put(stroke, command); 124 getActionMap().put(command, expand); 125 } 126 127 132 public void updateUI() 133 { 134 super.updateUI(); 135 if (tree != null) { 136 tree.updateUI(); 137 } 138 LookAndFeel.installColorsAndFont(this, "Tree.background", 141 "Tree.foreground", "Tree.font"); 142 } 143 144 150 public int getEditingRow() 151 { 152 final Class editingClass = getColumnClass(editingColumn); 153 return (editingClass == TreeTableModel.class) ? -1 : editingRow; 154 } 155 156 159 public void setRowHeight(int newRowHeight) 160 { 161 super.setRowHeight(newRowHeight); 162 if ((tree != null) && (tree.getRowHeight() != newRowHeight)) { 163 tree.setRowHeight(getRowHeight()); 164 } 165 } 166 167 170 public JTree getTree() 171 { 172 return tree; 173 } 174 175 178 class TreeTableCellRenderer extends JTree implements 179 TableCellRenderer 180 { 181 182 protected int visibleRow; 183 184 185 public TreeTableCellRenderer(TreeModel model) 186 { 187 super(model); 188 } 189 190 194 public void updateUI() 195 { 196 super.updateUI(); 197 final TreeCellRenderer tcr = getCellRenderer(); 200 if (tcr instanceof DefaultTreeCellRenderer ) { 201 final DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer ) tcr); 202 dtcr.setTextSelectionColor(UIManager.getColor 207 ("Table.selectionForeground")); 208 dtcr.setBackgroundSelectionColor(UIManager.getColor 209 ("Table.selectionBackground")); 210 } 211 } 212 213 217 public void setRowHeight(int newRowHeight) 218 { 219 if (newRowHeight > 0) { 220 super.setRowHeight(newRowHeight); 221 if ((JTreeTable.this != null) && 222 (JTreeTable.this.getRowHeight() != newRowHeight)) 223 { 224 JTreeTable.this.setRowHeight(getRowHeight()); 225 } 226 } 227 } 228 229 232 public void setBounds(int x, int y, int w, int h) 233 { 234 super.setBounds(x, 0, w, JTreeTable.this.getHeight()); 235 } 236 237 241 public void paint(Graphics g) 242 { 243 g.translate(0, -visibleRow * getRowHeight()); 244 super.paint(g); 245 } 246 247 251 public Component getTableCellRendererComponent(JTable table, 252 Object value, 253 boolean isSelected, 254 boolean hasFocus, 255 int row, int column) 256 { 257 if (isSelected) { 258 setBackground(table.getSelectionBackground()); 259 } else { 260 setBackground(table.getBackground()); 261 } 262 263 visibleRow = row; 264 return this; 265 } 266 } 267 268 269 273 public class TreeTableCellEditor extends AbstractCellEditor implements 274 TableCellEditor 275 { 276 public Component getTableCellEditorComponent(JTable table, 277 Object value, 278 boolean isSelected, 279 int r, int c) 280 { 281 return tree; 282 } 283 284 304 public boolean isCellEditable(EventObject e) 305 { 306 if (e instanceof MouseEvent ) { 307 for (int counter = getColumnCount() - 1; counter >= 0; 308 counter--) { 309 if (getColumnClass(counter) == TreeTableModel.class) { 310 final MouseEvent me = (MouseEvent ) e; 311 final MouseEvent newME = new MouseEvent (tree, me.getID(), 312 me.getWhen(), me.getModifiers(), 313 me.getX() - getCellRect(0, counter, true).x, 314 me.getY(), me.getClickCount(), 315 me.isPopupTrigger()); 316 tree.dispatchEvent(newME); 317 break; 318 } 319 } 320 } 321 322 return false; 323 } 324 } 325 326 327 333 class ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel 334 { 335 336 protected boolean updatingListSelectionModel; 337 338 public ListToTreeSelectionModelWrapper() 339 { 340 super(); 341 getListSelectionModel().addListSelectionListener 342 (createListSelectionListener()); 343 } 344 345 352 ListSelectionModel getListSelectionModel() 353 { 354 return listSelectionModel; 355 } 356 357 362 public void resetRowSelection() 363 { 364 if (!updatingListSelectionModel) { 365 updatingListSelectionModel = true; 366 try { 367 super.resetRowSelection(); 368 } finally { 369 updatingListSelectionModel = false; 370 } 371 } 372 } 378 379 382 private ListSelectionListener createListSelectionListener() 383 { 384 return new ListSelectionHandler(); 385 } 386 387 392 protected void updateSelectedPathsFromSelectedRows() 393 { 394 if (!updatingListSelectionModel) { 395 updatingListSelectionModel = true; 396 try { 397 final int min = listSelectionModel.getMinSelectionIndex(); 400 final int max = listSelectionModel.getMaxSelectionIndex(); 401 402 clearSelection(); 403 if ((min != -1) && (max != -1)) { 404 for (int counter = min; counter <= max; counter++) { 405 if (listSelectionModel.isSelectedIndex(counter)) { 406 final TreePath selPath = tree.getPathForRow 407 (counter); 408 409 if (selPath != null) { 410 addSelectionPath(selPath); 411 } 412 } 413 } 414 } 415 } finally { 416 updatingListSelectionModel = false; 417 } 418 } 419 } 420 421 425 class ListSelectionHandler implements ListSelectionListener 426 { 427 public void valueChanged(ListSelectionEvent e) 428 { 429 updateSelectedPathsFromSelectedRows(); 430 } 431 } 432 } 433 } 434 | Popular Tags |