1 21 22 package org.armedbear.j; 23 24 import java.awt.Color ; 25 import java.awt.Component ; 26 import java.awt.Cursor ; 27 import java.awt.Point ; 28 import java.awt.Rectangle ; 29 import java.awt.datatransfer.DataFlavor ; 30 import java.awt.datatransfer.Transferable ; 31 import java.awt.dnd.DnDConstants ; 32 import java.awt.dnd.DragGestureEvent ; 33 import java.awt.dnd.DragGestureListener ; 34 import java.awt.dnd.DragGestureRecognizer ; 35 import java.awt.dnd.DragSource ; 36 import java.awt.dnd.DragSourceContext ; 37 import java.awt.dnd.DragSourceDragEvent ; 38 import java.awt.dnd.DragSourceDropEvent ; 39 import java.awt.dnd.DragSourceEvent ; 40 import java.awt.dnd.DragSourceListener ; 41 import java.awt.dnd.DropTarget ; 42 import java.awt.dnd.DropTargetDragEvent ; 43 import java.awt.dnd.DropTargetDropEvent ; 44 import java.awt.dnd.DropTargetEvent ; 45 import java.awt.dnd.DropTargetListener ; 46 import java.awt.event.ActionEvent ; 47 import java.awt.event.ActionListener ; 48 import java.awt.event.InputEvent ; 49 import java.awt.event.KeyEvent ; 50 import java.awt.event.KeyListener ; 51 import java.awt.event.MouseEvent ; 52 import java.awt.event.MouseListener ; 53 import java.awt.event.MouseMotionListener ; 54 import java.util.ArrayList ; 55 import java.util.Enumeration ; 56 import java.util.Iterator ; 57 import java.util.List ; 58 import javax.swing.JComponent ; 59 import javax.swing.JLabel ; 60 import javax.swing.JMenuItem ; 61 import javax.swing.JPopupMenu ; 62 import javax.swing.JTree ; 63 import javax.swing.JViewport ; 64 import javax.swing.SwingUtilities ; 65 import javax.swing.ToolTipManager ; 66 import javax.swing.UIManager ; 67 import javax.swing.border.Border ; 68 import javax.swing.border.CompoundBorder ; 69 import javax.swing.border.EmptyBorder ; 70 import javax.swing.tree.DefaultMutableTreeNode ; 71 import javax.swing.tree.DefaultTreeModel ; 72 import javax.swing.tree.TreeCellRenderer ; 73 import javax.swing.tree.TreeNode ; 74 import javax.swing.tree.TreePath ; 75 76 public final class SidebarBufferTree extends SidebarTree implements Constants, 80 NavigationComponent, ActionListener , KeyListener , MouseListener , 81 MouseMotionListener , PreferencesChangeListener, DragGestureListener , 82 DragSourceListener , DropTargetListener 83 { 84 private JPopupMenu popup; 85 private int updateFlag; 86 private DefaultMutableTreeNode rootNode; 87 private Sidebar sidebar; 88 89 private DragSource dragSource; 91 private static DragSourceContext dragSourceContext; 92 private Buffer draggedBuffer = null; 93 private int draggedBufferRow = -1; 94 private int scrollY = 0; 96 private Runnable scroller = null; 97 private static final long[] WAIT_TIMES = new long[] { 100 200, 175, 150, 125, 100, 75, 50, 37, 25, 15, 10, 5 101 }; 102 103 private boolean alpha = false; 105 private boolean reorder = false; 107 108 public SidebarBufferTree(Sidebar sidebar) 109 { 110 super(null); 111 this.sidebar = sidebar; 112 setCellRenderer(new SidebarTreeCellRenderer(sidebar)); 113 setFocusTraversalKeysEnabled(false); 114 addKeyListener(this); 115 addMouseListener(this); 116 addMouseMotionListener(this); 117 setToolTipText(""); 118 setRootVisible(false); 119 120 dragSource = DragSource.getDefaultDragSource() ; 121 DragGestureRecognizer dgr = 122 dragSource.createDefaultDragGestureRecognizer(this, 123 DnDConstants.ACTION_COPY_OR_MOVE, 124 this); 125 dgr.setSourceActions(dgr.getSourceActions() & ~InputEvent.BUTTON3_MASK); 126 new DropTarget (this, this); 127 128 Preferences p = Editor.preferences(); 129 if (p != null) { 130 updatePreferences(p); 131 p.addPreferencesChangeListener(this); 132 } else 133 Debug.bug(); 134 } 135 136 private void initializeTreeStructure() 141 { 142 final ArrayList arrayList = new ArrayList (); 143 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 144 Buffer buf = it.nextBuffer(); 145 if (buf.isPrimary()) { 146 arrayList.add(buf); 147 Buffer secondary = buf.getSecondary(); 150 if (secondary != null) 151 arrayList.add(secondary); 152 } 153 } 154 rootNode = new DefaultMutableTreeNode (""); 156 buildTreeFromList(rootNode, arrayList); 157 setModel(new DefaultTreeModel (rootNode)); 158 } 159 160 private void updatePreferences(Preferences p) 161 { 162 alpha = p.getBooleanProperty(Property.SORT_BUFFER_LIST); 163 if (alpha) 164 reorder = false; 165 else 166 reorder = p.getIntegerProperty(Property.REORDER_BUFFERS) > 1; 167 } 168 169 private void buildTreeFromList(DefaultMutableTreeNode node, List buffers) 170 { 171 Iterator iter = buffers.iterator(); 172 while (iter.hasNext()) { 173 Object next = iter.next(); 174 if (next instanceof Buffer) { 175 Buffer buffer = (Buffer) next; 176 node.add(new DefaultMutableTreeNode (buffer)); 177 } 178 } 179 } 180 181 public synchronized void setUpdateFlag(int mask) 182 { 183 updateFlag |= mask; 184 } 185 186 public synchronized void updateBufferList() 187 { 188 if (!SwingUtilities.isEventDispatchThread()) 189 Debug.bug(); 190 if ((updateFlag & SIDEBAR_BUFFER_LIST_CHANGED) != 0) { 191 refresh(); 192 updateFlag |= SIDEBAR_REPAINT_BUFFER_LIST; 193 } 194 if ((updateFlag & SIDEBAR_MODIFIED_BUFFER_COUNT) != 0) { 195 updateFlag |= SIDEBAR_REPAINT_BUFFER_LIST; 198 updateLabel(); 199 } 200 Buffer buffer = sidebar.getEditor().getBuffer(); 202 if (buffer != getSelectedBuffer()) 203 setSelectedBuffer(buffer); 204 else 205 scrollPathToVisible(getSelectionPath()); 206 boolean repaint = (updateFlag & SIDEBAR_REPAINT_BUFFER_LIST) != 0; 207 updateFlag = 0; 208 if (repaint) { 209 repaint(); 211 } 212 } 213 214 public Buffer getSelectedBuffer() 215 { 216 if (getSelectionCount() > 0) 217 return getBufferFromPath(getSelectionPath()); 218 else 219 return null; 220 } 221 222 public Buffer[] getSelectedBuffers() 223 { 224 int numSelected = getSelectionCount(); 225 if (numSelected <= 0) 227 return new Buffer[0]; 228 Buffer[] buffers = new Buffer[numSelected]; 229 TreePath [] paths = getSelectionPaths(); 231 for (int i = 0; i < paths.length; i++) 232 buffers[i] = getBufferFromPath(paths[i]); 233 return buffers; 234 } 235 236 public int[] getSelectionRows() 238 { 239 int[] rows = super.getSelectionRows(); 240 if (rows == null) 241 rows = new int[0]; 242 return rows; 243 } 244 245 public int getSelectionRow() 248 { 249 int rows[] = getSelectionRows(); 250 if (rows.length > 0) 251 return rows[0]; 252 return -1; 253 } 254 255 private Buffer getBufferFromPath(TreePath path) 256 { 257 TreeNode endNode = (TreeNode )path.getLastPathComponent(); 258 if (endNode instanceof DefaultMutableTreeNode ) { 259 Object obj = ((DefaultMutableTreeNode )endNode).getUserObject(); 260 if (obj instanceof Buffer) 261 return (Buffer) obj; 262 } 263 return null; 264 } 265 266 public void setSelectedBuffer(Buffer buffer) 267 { 268 DefaultMutableTreeNode node = findNodeForObject(buffer); 269 if (node != null) { 270 TreePath path = new TreePath (node.getPath()); 271 setSelectionPath(path); 272 scrollPathToVisible(path); 273 } 274 } 275 276 public void scrollPathToVisible(TreePath path) 277 { 278 if (path != null) { 279 makeVisible(path); 280 Rectangle bounds = getPathBounds(path); 281 if (bounds != null) { 282 bounds.y = Math.max(bounds.y - 17, 0); 283 bounds.height = bounds.height + 34; 284 scrollRectToVisible(bounds); 285 if (accessibleContext != null) 286 ((AccessibleJTree)accessibleContext).fireVisibleDataPropertyChange(); 287 } 288 } 289 } 290 291 public String getLabelText() 292 { 293 int total = 0; 294 int modified = 0; 295 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 296 ++total; 297 if (it.nextBuffer().isModified()) 298 ++modified; 299 } 300 FastStringBuffer sb = new FastStringBuffer("Buffers"); 301 sb.append(" ("); 302 sb.append(total); 303 if (modified > 0) { 304 sb.append("; "); 305 sb.append(modified); 306 sb.append(" modified"); 307 } 308 sb.append(')'); 309 return sb.toString(); 310 } 311 312 private synchronized void updateLabel() 313 { 314 sidebar.setBufferListLabelText(getLabelText()); 315 updateFlag &= ~SIDEBAR_MODIFIED_BUFFER_COUNT; 316 } 317 318 private final Runnable refreshRunnable = new Runnable () { 319 public void run() 320 { 321 if ((updateFlag & SIDEBAR_MODIFIED_BUFFER_COUNT) != 0) 322 updateLabel(); 323 initializeTreeStructure(); 324 } 325 }; 326 327 public void refresh() 328 { 329 if (SwingUtilities.isEventDispatchThread()) 330 refreshRunnable.run(); 331 else 332 SwingUtilities.invokeLater(refreshRunnable); 333 } 334 335 public void updatePosition() 336 { 337 } 338 339 private void switchToBuffer() 340 { 341 Buffer buffer = getSelectedBuffer(); 342 if (buffer != null) { 343 Editor editor = sidebar.getEditor(); 344 if (Editor.preferences().getIntegerProperty(Property.REORDER_BUFFERS) > 1) 345 editor.makeNext(buffer); 346 editor.switchToBuffer(buffer); 347 Editor.currentEditor().setFocusToDisplay(); 348 editor.updateDisplay(); 349 } 350 } 351 352 private void closeBuffers(Buffer[] array) 353 { 354 Editor editor = sidebar.getEditor(); 355 for (int i = 0; i < array.length; i++) 356 editor.maybeKillBuffer(array[i]); 357 EditorIterator iter = new EditorIterator(); 358 while (iter.hasNext()) 359 iter.nextEditor().updateDisplay(); 360 for (int i = 0; i < Editor.getFrameCount(); i++) { 361 Frame frame = Editor.getFrame(i); 362 Sidebar sidebar = frame.getSidebar(); 363 if (sidebar != null) { 364 sidebar.setUpdateFlag(SIDEBAR_BUFFER_LIST_ALL); 365 SidebarBufferTree sidebarBufferTree = sidebar.getBufferTree(); 366 if (sidebarBufferTree != null) 367 sidebarBufferTree.updateBufferList(); 368 } 369 } 370 } 371 372 private void closeSelectedBuffers() { 373 int index = -1; 374 int[] rows = getSelectionRows(); 375 if (rows.length > 0) 376 index = rows[0]; 377 Buffer[] array = getSelectedBuffers(); 378 closeBuffers(array); 379 if (index >= 0) { 380 if (index > getRowCount() - 1) 384 index = getRowCount() - 1; 385 setSelectionRow(index); 386 scrollRowToVisible(index); 387 } 388 } 389 390 private void saveSelectedBuffers() 391 { 392 Editor editor = sidebar.getEditor(); 393 Buffer[] array = getSelectedBuffers(); 394 for (int i = 0; i < array.length; i++) 395 editor.save(array[i]); 396 Sidebar.repaintBufferListInAllFrames(); 397 } 398 399 public void actionPerformed(ActionEvent e) 400 { 401 String command = e.getActionCommand(); 402 if (command.equals("close")) 403 closeSelectedBuffers(); 404 else if (command.equals("save")) 405 saveSelectedBuffers(); 406 } 407 408 private void showPopup(Component c, int x, int y) 409 { 410 popup = new JPopupMenu (); 411 TreePath path = getPathForLocation(x, y); 412 String bufferName = null; 413 if (path != null) { 414 Object last = path.getLastPathComponent(); 415 Object value = ((DefaultMutableTreeNode )last).getUserObject(); 416 if (value instanceof Buffer) { 417 bufferName = last.toString(); 418 } 419 } 420 JMenuItem menuItem = new JMenuItem ("Save"); 421 menuItem.setActionCommand("save"); 422 menuItem.addActionListener(this); 423 popup.add(menuItem); 424 menuItem = new JMenuItem ("Close"); 425 menuItem.setActionCommand("close"); 426 menuItem.addActionListener(this); 427 popup.add(menuItem); 428 popup.pack(); 429 popup.show(c, x, y); 430 } 431 432 public String getToolTipText(MouseEvent e) 433 { 434 String text = null; 435 Point p = e.getPoint(); 436 int index = getRowForLocation(p.x, p.y); 437 if (index >= 0 && index < getRowCount()) { 438 TreePath path = getPathForRow(index); 439 Buffer buffer = getBufferFromPath(path); 440 if (buffer == null) 441 return null; 442 File file = buffer.getFile(); 443 if (file != null) 444 text = file.isRemote() ? file.netPath() : file.canonicalPath(); 445 else 446 text = buffer.getTitle(); 447 } 448 return text; 449 } 450 451 public synchronized void preferencesChanged() 452 { 453 Preferences p = Editor.preferences(); 454 if (p != null) { 455 updatePreferences(p); 456 } 457 else { 458 Debug.bug(); 459 } 460 } 461 462 private DefaultMutableTreeNode findNodeForObject(Object userObj) 463 { 464 if (rootNode != null) { 465 Enumeration enumeration = rootNode.breadthFirstEnumeration(); 466 while (enumeration.hasMoreElements()) { 467 Object next = enumeration.nextElement(); 468 if (next instanceof DefaultMutableTreeNode ) { 469 Object obj = ((DefaultMutableTreeNode )next).getUserObject(); 470 if (userObj.equals(obj)) 471 return (DefaultMutableTreeNode ) next; 472 } 473 } 474 } 475 return null; 476 } 477 478 public void keyPressed(KeyEvent e) 479 { 480 final int keyCode = e.getKeyCode(); 481 final int modifiers = e.getModifiers() & 0x0f; 483 final Editor editor = sidebar.getEditor(); 484 switch (keyCode) { 485 case KeyEvent.VK_SHIFT: 487 case KeyEvent.VK_CONTROL: 488 case KeyEvent.VK_ALT: 489 case KeyEvent.VK_META: 490 return; 491 case KeyEvent.VK_ENTER: 492 e.consume(); 493 switchToBuffer(); 494 if (modifiers == KeyEvent.ALT_MASK) 495 editor.toggleSidebar(); 496 return; 497 case KeyEvent.VK_TAB: 498 e.consume(); 499 if (modifiers == 0) { 500 if (sidebar.getBottomComponent() != null) { 501 sidebar.setBuffer(); 502 editor.setFocus((JComponent )sidebar.getBottomComponent()); 503 } 504 } 505 return; 506 case KeyEvent.VK_ESCAPE: 507 e.consume(); 508 if (popup != null && popup.isVisible()) { 509 popup.setVisible(false); 510 popup = null; 511 } else { 512 sidebar.setBuffer(); 513 editor.setFocusToDisplay(); 514 } 515 return; 516 case KeyEvent.VK_DELETE: 517 e.consume(); 518 closeSelectedBuffers(); 519 return; 520 } 521 editor.getDispatcher().setEnabled(false); 522 } 523 524 public void keyReleased(KeyEvent e) 525 { 526 e.consume(); 527 sidebar.getEditor().getDispatcher().setEnabled(true); 528 } 529 530 public void keyTyped(KeyEvent e) 531 { 532 e.consume(); 533 } 534 535 public void mousePressed(MouseEvent e) 536 { 537 Editor editor = sidebar.getEditor(); 538 editor.ensureActive(); 539 int modifiers = e.getModifiers() & 0x1f; 541 Point p = e.getPoint(); 542 if (modifiers == InputEvent.BUTTON1_MASK || 543 modifiers == InputEvent.BUTTON2_MASK) 544 { 545 setSelectionRow(getRowForLocation(p.x, p.y)); 546 paintImmediately(0, 0, getWidth(), getHeight()); 547 switchToBuffer(); 548 } else if (modifiers == InputEvent.BUTTON3_MASK) { 549 setSelectionRow(getRowForLocation(p.x, p.y)); 551 sidebar.getFrame().setFocus(this); 552 paintImmediately(0, 0, getWidth(), getHeight()); 553 } else { 554 sidebar.getFrame().setFocus(this); 555 } 556 } 557 558 public void mouseReleased(MouseEvent e) 559 { 560 } 561 562 public void mouseClicked(MouseEvent e) 563 { 564 int modifiers = e.getModifiers() & 0x1f; 566 Point p = e.getPoint(); 567 if (modifiers == InputEvent.BUTTON1_MASK || 571 modifiers == InputEvent.BUTTON2_MASK) 572 { 573 setSelectionRow(getRowForLocation(p.x, p.y)); 574 paintImmediately(0, 0, getWidth(), getHeight()); 575 switchToBuffer(); 576 } else if (e.getModifiers() == InputEvent.BUTTON3_MASK) { 577 showPopup(e.getComponent(), e.getX(), e.getY()); 578 } 579 } 580 581 public void mouseMoved(MouseEvent e) 582 { 583 String text = getToolTipText(e); 584 if (text == null) 585 text = ""; 586 sidebar.getFrame().setStatusText(text); 587 } 588 589 public void mouseEntered(MouseEvent e) 590 { 591 setCursor(Cursor.getDefaultCursor()); 594 } 595 596 public void mouseExited(MouseEvent e) 597 { 598 final Frame frame = sidebar.getFrame(); 599 final StatusBar statusBar = frame.getStatusBar(); 600 if (statusBar != null) { 601 statusBar.setText(null); 602 statusBar.repaintNow(); 603 } 604 ToolTipManager.sharedInstance().setEnabled(false); 606 ToolTipManager.sharedInstance().setEnabled(true); 607 if (popup == null || !popup.isVisible()) { 608 if (frame.getFocusedComponent() == this) { 609 Editor editor = sidebar.getEditor(); 610 sidebar.setBuffer(); 611 editor.setFocusToDisplay(); 612 } 613 } 614 } 615 616 public void mouseDragged(MouseEvent e) 617 { 618 } 619 620 public void dragEnter(DropTargetDragEvent event) 622 { 623 if (alpha || reorder) 624 return; 625 stopScroll(); 626 if (Platform.isPlatformUnix() && dragSourceContext != null) { 627 Cursor c = Dispatcher.getCursorForAction(event.getDropAction()); 628 dragSourceContext.setCursor(c); 629 } 630 } 631 632 public void dragExit(DropTargetEvent e) 634 { 635 if (alpha || reorder) 636 return; 637 setSelectionRow(draggedBufferRow); 638 if (Platform.isPlatformUnix() && dragSourceContext != null) 639 dragSourceContext.setCursor(Dispatcher.getCursorForAction(-1)); 640 } 641 642 public void dragOver(DropTargetDragEvent event) 644 { 645 if (alpha || reorder) 646 return; 647 if (event.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { 648 Point pt = event.getLocation(); 649 int row = getRowForLocation(pt.x, pt.y); 650 if (row == -1) 651 setSelectionRow(draggedBufferRow); 652 else 653 setSelectionRow(row); 654 } 655 } 656 657 public void drop(DropTargetDropEvent event) 659 { 660 if (alpha || reorder) 661 return; 662 Transferable t = event.getTransferable(); 663 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor) && 664 draggedBuffer != null) 665 { 666 BufferList bufList = Editor.getBufferList(); 667 Buffer movedTo = getSelectedBuffer(); 668 if (movedTo.isSecondary()) { 670 setSelectionRow(draggedBufferRow); 671 event.rejectDrop(); 672 return; 673 } 674 int index = bufList.indexOf(movedTo); 675 if (index >= 0) { 676 bufList.move(draggedBuffer, index); 677 refresh(); 678 setSelectionRow(index); 680 } 681 } else 682 event.rejectDrop(); 683 } 684 685 686 public void dropActionChanged(DropTargetDragEvent event) {} 688 689 public void dragGestureRecognized(DragGestureEvent event) 691 { 692 if (alpha || reorder) 693 return; 694 Buffer buf = getSelectedBuffer(); 695 if (buf != null && !buf.isSecondary()) { 696 String name = buf.getFileNameForDisplay(); 697 Transferable transferable = 698 new BufferSelection(new java.io.File (name)); 699 draggedBuffer = buf; 700 draggedBufferRow = getSelectionRow(); 701 702 int action = event.getDragAction(); 703 Cursor cursor = null; 704 if (Platform.isPlatformUnix()) { 705 cursor = Dispatcher.getCursorForAction(action); 706 } 707 dragSource.startDrag(event, cursor, transferable, this); 708 dragSourceContext = null; 709 } 710 } 711 712 public void dragDropEnd(DragSourceDropEvent event) 714 { 715 draggedBuffer = null; 716 draggedBufferRow = -1; 717 stopScroll(); 718 if (alpha || reorder) 719 return; 720 int selectionRow = getSelectionRow(); 722 if (selectionRow >= 0) 723 scrollRowToVisible(selectionRow); 724 } 725 726 public void dragEnter(DragSourceDragEvent event) 728 { 729 if (alpha || reorder) 730 return; 731 stopScroll(); 732 if (Platform.isPlatformUnix()) { 733 DragSourceContext dsc = event.getDragSourceContext(); 734 dsc.setCursor(Dispatcher.getCursorForAction(event.getDropAction())); 735 } 736 } 737 738 public void dragOver(DragSourceDragEvent event) 740 { 741 if (alpha || reorder) 742 return; 743 if (Platform.isPlatformMacOSX()) { 747 Component parent = getParent(); 748 if (!(parent instanceof JViewport )) { 749 stopScroll(); 750 return; 751 } 752 JViewport viewport = (JViewport )parent; 753 Rectangle rect = viewport.getViewRect(); 754 755 Point frameLoc = Editor.getCurrentFrame().getLocationOnScreen(); 756 Point loc = viewport.getLocationOnScreen(); 757 int x = event.getX() - frameLoc.x + loc.x; 758 int y = event.getY() + frameLoc.y - loc.y; 759 if ((y < 0 || y > rect.height) && (x >= 0 && x <= rect.width)) { 760 x += loc.x; 764 y += loc.y; 765 DragSourceEvent dse = 766 new DragSourceEvent (event.getDragSourceContext(), x, y); 767 dragExit(dse); 768 } else 769 stopScroll(); 770 } 771 } 772 773 public void dropActionChanged(DragSourceDragEvent event) {} 775 776 public void dragExit(DragSourceEvent event) 778 { 779 if (alpha || reorder) 780 return; 781 DragSourceContext dsc = event.getDragSourceContext(); 782 if (Platform.isPlatformUnix()) 783 dsc.setCursor(Dispatcher.getCursorForAction(-1)); 784 dragSourceContext = dsc; 785 Component parent = getParent(); 786 if (!(parent instanceof JViewport )) { 787 stopScroll(); 788 return; 789 } 790 JViewport viewport = (JViewport )parent; 791 Rectangle rect = viewport.getViewRect(); 792 int x = event.getX(); 793 int y = event.getY(); 794 Point p = getLocationOnScreen(); 795 x -= p.x + rect.x; 796 y -= p.y + rect.y; 797 int rowFudge = (getRowBounds(0).height + 1) / 2; 800 int yDiff = getSize().height - rect.height - rect.y; 801 if (x < 0 || x >= rect.width || (y < 0 && rect.y < rowFudge) || 803 (y > 0 && yDiff < rowFudge)) 804 { 805 stopScroll(); 806 return; 807 } 808 if (y < 0) { 811 scrollY = (y - 1) / 2; 812 } else { 813 y -= rect.height; 814 scrollY = (y + 2) / 2; 815 } 816 startScroll(); 817 } 818 819 private synchronized void startScroll() { 821 if (scroller == null) { 822 scroller = new TreeScroller(); 823 Thread scroll = new Thread (scroller, "SidebarBufferTree scroller"); 824 scroll.setDaemon(true); 825 scroll.setPriority(Thread.MIN_PRIORITY); 826 scroll.start(); 827 } 828 } 829 830 private synchronized void stopScroll() { 832 scrollY = 0; 833 scroller = null; 834 } 835 836 private class TreeScroller implements Runnable { 837 public void run() 838 { 839 Component parent = getParent(); 840 if (!(parent instanceof JViewport )) { 841 return; 842 } 843 final JViewport viewport = (JViewport )parent; 844 while (scrollY != 0) { 845 if (viewport == null) 846 break; 847 Rectangle bounds = getRowBounds(0); 848 if (bounds == null) 849 break; 850 int scrollInc = bounds.height; 851 int diffY; 852 final Rectangle rect = viewport.getViewRect(); 853 final Point pos = viewport.getViewPosition(); 854 if (scrollY < 0) { 855 pos.y = Math.max(pos.y - scrollInc, 0); 856 if (pos.y == 0) 857 scrollY = 0; 858 } else { 859 int h = getSize().height; 860 int yMax = h - rect.height; 861 pos.y = Math.min(pos.y + scrollInc, yMax); 862 if (pos.y == yMax) 863 scrollY = 0; 864 } 865 Runnable r = new Runnable () { 866 public void run() 867 { 868 if (viewport != null && pos != null) { 869 viewport.setViewPosition(pos); 870 repaint(); 871 } 872 } 873 }; 874 SwingUtilities.invokeLater(r); 875 int absY = Math.abs(scrollY); 876 int waitIndex = Math.min(absY, WAIT_TIMES.length-1); 877 try { 878 Thread.sleep(WAIT_TIMES[waitIndex]); 879 } 880 catch (InterruptedException ex) {} 881 } 882 } 883 } 884 885 private static class SidebarTreeCellRenderer extends JLabel 886 implements TreeCellRenderer 887 { 888 private static final Color textForeground = 889 UIManager.getColor("Tree.textForeground"); 890 private static final Color textBackground = 891 UIManager.getColor("Tree.textBackground"); 892 private static final Color selectionForeground = 893 UIManager.getColor("Tree.selectionForeground"); 894 private static final Color selectionBackground = 895 UIManager.getColor("Tree.selectionBackground"); 896 private static final Color noFocusSelectionBackground = 897 new Color (208, 208, 208); 898 private static final Border noFocusBorder = 899 new EmptyBorder (1, 1, 1, 1); 900 901 private final Sidebar sidebar; 902 903 public SidebarTreeCellRenderer(Sidebar sidebar) 904 { 905 super(); 906 this.sidebar = sidebar; 907 setOpaque(true); 908 } 909 910 public Component getTreeCellRendererComponent(JTree tree, Object value, 911 boolean selected, 912 boolean expanded, 913 boolean leaf, int row, 914 boolean hasFocus) 915 { 916 Object userObject = null; 917 if (value instanceof DefaultMutableTreeNode ) 918 userObject = ((DefaultMutableTreeNode )value).getUserObject(); 919 Border innerBorder = null; 920 if (userObject instanceof Buffer) { 921 setText(userObject.toString()); 922 Buffer buffer = (Buffer) userObject; 923 setIcon(buffer.getIcon()); 924 if (buffer.isSecondary()) 925 innerBorder = new EmptyBorder (0, 10, 0, 0); 926 } else 927 setIcon(null); 928 Frame frame = sidebar.getFrame(); 929 if (selected) { 930 if (frame.isActive() && tree.hasFocus()) 931 setBackground(selectionBackground); 932 else 933 setBackground(noFocusSelectionBackground); 934 setForeground(selectionForeground); 935 } else { 936 setBackground(textBackground); 937 setForeground(textForeground); 938 } 939 setEnabled(tree.isEnabled()); 940 setFont(tree.getFont()); 941 Border outerBorder; 942 if (hasFocus) 943 outerBorder = UIManager.getBorder("List.focusCellHighlightBorder"); 944 else 945 outerBorder = noFocusBorder; 946 setBorder(new CompoundBorder (outerBorder, innerBorder)); 947 return this; 948 } 949 } 950 951 private class BufferSelection implements Transferable 952 { 953 private List fileList = null; 954 private final DataFlavor [] flavors = new DataFlavor [] { 955 DataFlavor.javaFileListFlavor 956 }; 957 958 public BufferSelection(java.io.File file) 959 { 960 fileList = new ArrayList (1); 961 fileList.add(file); 962 } 963 964 public Object getTransferData(DataFlavor flavor) 965 { 966 List retList = new ArrayList (1); 967 if (flavor == DataFlavor.javaFileListFlavor) 968 retList.add(fileList.get(0)); 969 return retList; 970 } 971 972 public DataFlavor [] getTransferDataFlavors() 973 { 974 return flavors; 975 } 976 977 public boolean isDataFlavorSupported(DataFlavor flavor) 978 { 979 for (int i = 0; i < flavors.length; i++) { 980 if (flavor == flavors[i]) 981 return true; 982 } 983 return false; 984 } 985 } 986 } 987 | Popular Tags |