1 7 8 package javax.swing.tree; 9 10 import javax.swing.*; 11 import javax.swing.border.*; 12 import javax.swing.event.*; 13 import javax.swing.plaf.FontUIResource ; 14 import java.awt.*; 15 import java.awt.event.*; 16 import java.beans.*; 17 import java.io.*; 18 import java.util.EventObject ; 19 import java.util.Vector ; 20 21 46 public class DefaultTreeCellEditor implements ActionListener, TreeCellEditor , 47 TreeSelectionListener { 48 49 protected TreeCellEditor realEditor; 50 51 52 protected DefaultTreeCellRenderer renderer; 53 54 55 protected Container editingContainer; 56 57 61 transient protected Component editingComponent; 62 63 68 protected boolean canEdit; 69 70 74 protected transient int offset; 75 76 77 protected transient JTree tree; 78 79 80 protected transient TreePath lastPath; 81 82 83 protected transient Timer timer; 84 85 89 protected transient int lastRow; 90 91 92 protected Color borderSelectionColor; 93 94 95 protected transient Icon editingIcon; 96 97 101 protected Font font; 102 103 104 112 public DefaultTreeCellEditor(JTree tree, 113 DefaultTreeCellRenderer renderer) { 114 this(tree, renderer, null); 115 } 116 117 127 public DefaultTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer, 128 TreeCellEditor editor) { 129 this.renderer = renderer; 130 realEditor = editor; 131 if(realEditor == null) 132 realEditor = createTreeCellEditor(); 133 editingContainer = createContainer(); 134 setTree(tree); 135 setBorderSelectionColor(UIManager.getColor 136 ("Tree.editorBorderSelectionColor")); 137 } 138 139 143 public void setBorderSelectionColor(Color newColor) { 144 borderSelectionColor = newColor; 145 } 146 147 151 public Color getBorderSelectionColor() { 152 return borderSelectionColor; 153 } 154 155 166 public void setFont(Font font) { 167 this.font = font; 168 } 169 170 176 public Font getFont() { 177 return font; 178 } 179 180 184 187 public Component getTreeCellEditorComponent(JTree tree, Object value, 188 boolean isSelected, 189 boolean expanded, 190 boolean leaf, int row) { 191 setTree(tree); 192 lastRow = row; 193 determineOffset(tree, value, isSelected, expanded, leaf, row); 194 195 if (editingComponent != null) { 196 editingContainer.remove(editingComponent); 197 } 198 editingComponent = realEditor.getTreeCellEditorComponent(tree, value, 199 isSelected, expanded,leaf, row); 200 201 202 TreePath newPath = tree.getPathForRow(row); 205 206 canEdit = (lastPath != null && newPath != null && 207 lastPath.equals(newPath)); 208 209 Font font = getFont(); 210 211 if(font == null) { 212 if(renderer != null) 213 font = renderer.getFont(); 214 if(font == null) 215 font = tree.getFont(); 216 } 217 editingContainer.setFont(font); 218 prepareForEditing(); 219 return editingContainer; 220 } 221 222 226 public Object getCellEditorValue() { 227 return realEditor.getCellEditorValue(); 228 } 229 230 235 public boolean isCellEditable(EventObject event) { 236 boolean retValue = false; 237 boolean editable = false; 238 239 if (event != null) { 240 if (event.getSource() instanceof JTree) { 241 setTree((JTree)event.getSource()); 242 if (event instanceof MouseEvent) { 243 TreePath path = tree.getPathForLocation( 244 ((MouseEvent)event).getX(), 245 ((MouseEvent)event).getY()); 246 editable = (lastPath != null && path != null && 247 lastPath.equals(path)); 248 if (path!=null) { 249 lastRow = tree.getRowForPath(path); 250 Object value = path.getLastPathComponent(); 251 boolean isSelected = tree.isRowSelected(lastRow); 252 boolean expanded = tree.isExpanded(path); 253 TreeModel treeModel = tree.getModel(); 254 boolean leaf = treeModel.isLeaf(value); 255 determineOffset(tree, value, isSelected, 256 expanded, leaf, lastRow); 257 } 258 } 259 } 260 } 261 if(!realEditor.isCellEditable(event)) 262 return false; 263 if(canEditImmediately(event)) 264 retValue = true; 265 else if(editable && shouldStartEditingTimer(event)) { 266 startEditingTimer(); 267 } 268 else if(timer != null && timer.isRunning()) 269 timer.stop(); 270 if(retValue) 271 prepareForEditing(); 272 return retValue; 273 } 274 275 278 public boolean shouldSelectCell(EventObject event) { 279 return realEditor.shouldSelectCell(event); 280 } 281 282 287 public boolean stopCellEditing() { 288 if(realEditor.stopCellEditing()) { 289 cleanupAfterEditing(); 290 return true; 291 } 292 return false; 293 } 294 295 299 public void cancelCellEditing() { 300 realEditor.cancelCellEditing(); 301 cleanupAfterEditing(); 302 } 303 304 308 public void addCellEditorListener(CellEditorListener l) { 309 realEditor.addCellEditorListener(l); 310 } 311 312 316 public void removeCellEditorListener(CellEditorListener l) { 317 realEditor.removeCellEditorListener(l); 318 } 319 320 328 public CellEditorListener[] getCellEditorListeners() { 329 return ((DefaultCellEditor)realEditor).getCellEditorListeners(); 330 } 331 332 336 339 public void valueChanged(TreeSelectionEvent e) { 340 if(tree != null) { 341 if(tree.getSelectionCount() == 1) 342 lastPath = tree.getSelectionPath(); 343 else 344 lastPath = null; 345 } 346 if(timer != null) { 347 timer.stop(); 348 } 349 } 350 351 355 359 public void actionPerformed(ActionEvent e) { 360 if(tree != null && lastPath != null) { 361 tree.startEditingAtPath(lastPath); 362 } 363 } 364 365 369 374 protected void setTree(JTree newTree) { 375 if(tree != newTree) { 376 if(tree != null) 377 tree.removeTreeSelectionListener(this); 378 tree = newTree; 379 if(tree != null) 380 tree.addTreeSelectionListener(this); 381 if(timer != null) { 382 timer.stop(); 383 } 384 } 385 } 386 387 392 protected boolean shouldStartEditingTimer(EventObject event) { 393 if((event instanceof MouseEvent) && 394 SwingUtilities.isLeftMouseButton((MouseEvent)event)) { 395 MouseEvent me = (MouseEvent)event; 396 397 return (me.getClickCount() == 1 && 398 inHitRegion(me.getX(), me.getY())); 399 } 400 return false; 401 } 402 403 406 protected void startEditingTimer() { 407 if(timer == null) { 408 timer = new Timer(1200, this); 409 timer.setRepeats(false); 410 } 411 timer.start(); 412 } 413 414 420 protected boolean canEditImmediately(EventObject event) { 421 if((event instanceof MouseEvent) && 422 SwingUtilities.isLeftMouseButton((MouseEvent)event)) { 423 MouseEvent me = (MouseEvent)event; 424 425 return ((me.getClickCount() > 2) && 426 inHitRegion(me.getX(), me.getY())); 427 } 428 return (event == null); 429 } 430 431 442 protected boolean inHitRegion(int x, int y) { 443 if(lastRow != -1 && tree != null) { 444 Rectangle bounds = tree.getRowBounds(lastRow); 445 ComponentOrientation treeOrientation = tree.getComponentOrientation(); 446 447 if ( treeOrientation.isLeftToRight() ) { 448 if (bounds != null && x <= (bounds.x + offset) && 449 offset < (bounds.width - 5)) { 450 return false; 451 } 452 } else if ( bounds != null && 453 ( x >= (bounds.x+bounds.width-offset+5) || 454 x <= (bounds.x + 5) ) && 455 offset < (bounds.width - 5) ) { 456 return false; 457 } 458 } 459 return true; 460 } 461 462 protected void determineOffset(JTree tree, Object value, 463 boolean isSelected, boolean expanded, 464 boolean leaf, int row) { 465 if(renderer != null) { 466 if(leaf) 467 editingIcon = renderer.getLeafIcon(); 468 else if(expanded) 469 editingIcon = renderer.getOpenIcon(); 470 else 471 editingIcon = renderer.getClosedIcon(); 472 if(editingIcon != null) 473 offset = renderer.getIconTextGap() + 474 editingIcon.getIconWidth(); 475 else 476 offset = renderer.getIconTextGap(); 477 } 478 else { 479 editingIcon = null; 480 offset = 0; 481 } 482 } 483 484 489 protected void prepareForEditing() { 490 if (editingComponent != null) { 491 editingContainer.add(editingComponent); 492 } 493 } 494 495 499 protected Container createContainer() { 500 return new EditorContainer(); 501 } 502 503 509 protected TreeCellEditor createTreeCellEditor() { 510 Border aBorder = UIManager.getBorder("Tree.editorBorder"); 511 DefaultCellEditor editor = new DefaultCellEditor 512 (new DefaultTextField(aBorder)) { 513 public boolean shouldSelectCell(EventObject event) { 514 boolean retValue = super.shouldSelectCell(event); 515 return retValue; 516 } 517 }; 518 519 editor.setClickCountToStart(1); 521 return editor; 522 } 523 524 528 private void cleanupAfterEditing() { 529 if (editingComponent != null) { 530 editingContainer.remove(editingComponent); 531 } 532 editingComponent = null; 533 } 534 535 private void writeObject(ObjectOutputStream s) throws IOException { 537 Vector values = new Vector (); 538 539 s.defaultWriteObject(); 540 if(realEditor != null && realEditor instanceof Serializable) { 542 values.addElement("realEditor"); 543 values.addElement(realEditor); 544 } 545 s.writeObject(values); 546 } 547 548 private void readObject(ObjectInputStream s) 549 throws IOException, ClassNotFoundException { 550 s.defaultReadObject(); 551 552 Vector values = (Vector )s.readObject(); 553 int indexCounter = 0; 554 int maxCounter = values.size(); 555 556 if(indexCounter < maxCounter && values.elementAt(indexCounter). 557 equals("realEditor")) { 558 realEditor = (TreeCellEditor )values.elementAt(++indexCounter); 559 indexCounter++; 560 } 561 } 562 563 564 571 public class DefaultTextField extends JTextField { 572 573 protected Border border; 574 575 581 public DefaultTextField(Border border) { 582 setBorder(border); 583 } 584 585 598 public void setBorder(Border border) { 599 super.setBorder(border); 600 this.border = border; 601 } 602 603 607 public Border getBorder() { 608 return border; 609 } 610 611 public Font getFont() { 613 Font font = super.getFont(); 614 615 if(font instanceof FontUIResource ) { 618 Container parent = getParent(); 619 620 if(parent != null && parent.getFont() != null) 621 font = parent.getFont(); 622 } 623 return font; 624 } 625 626 633 public Dimension getPreferredSize() { 634 Dimension size = super.getPreferredSize(); 635 636 if(renderer != null && 638 DefaultTreeCellEditor.this.getFont() == null) { 639 Dimension rSize = renderer.getPreferredSize(); 640 641 size.height = rSize.height; 642 } 643 return size; 644 } 645 } 646 647 648 651 public class EditorContainer extends Container { 652 655 public EditorContainer() { 656 setLayout(null); 657 } 658 659 public void EditorContainer() { 662 setLayout(null); 663 } 664 665 669 public void paint(Graphics g) { 670 Dimension size = getSize(); 671 672 if(editingIcon != null) { 674 int yLoc = Math.max(0, (getSize().height - 675 editingIcon.getIconHeight()) / 2); 676 677 editingIcon.paintIcon(this, g, 0, yLoc); 678 } 679 680 Color background = getBorderSelectionColor(); 682 if(background != null) { 683 g.setColor(background); 684 g.drawRect(0, 0, size.width - 1, size.height - 1); 685 } 686 super.paint(g); 687 } 688 689 694 public void doLayout() { 695 if(editingComponent != null) { 696 Dimension cSize = getSize(); 697 698 editingComponent.getPreferredSize(); 699 editingComponent.setLocation(offset, 0); 700 editingComponent.setBounds(offset, 0, 701 cSize.width - offset, 702 cSize.height); 703 } 704 } 705 706 715 public Dimension getPreferredSize() { 716 if(editingComponent != null) { 717 Dimension pSize = editingComponent.getPreferredSize(); 718 719 pSize.width += offset + 5; 720 721 Dimension rSize = (renderer != null) ? 722 renderer.getPreferredSize() : null; 723 724 if(rSize != null) 725 pSize.height = Math.max(pSize.height, rSize.height); 726 if(editingIcon != null) 727 pSize.height = Math.max(pSize.height, 728 editingIcon.getIconHeight()); 729 730 pSize.width = Math.max(pSize.width, 100); 732 return pSize; 733 } 734 return new Dimension(0, 0); 735 } 736 } 737 } 738 | Popular Tags |