1 19 20 package org.openide.explorer.view; 21 22 import java.awt.Dimension ; 23 import java.awt.Insets ; 24 import java.awt.Point ; 25 import java.awt.Rectangle ; 26 import java.awt.Toolkit ; 27 import java.awt.dnd.Autoscroll ; 28 import java.awt.dnd.DnDConstants ; 29 import java.awt.event.ActionEvent ; 30 import java.awt.event.ActionListener ; 31 import java.awt.event.FocusEvent ; 32 import java.awt.event.FocusListener ; 33 import java.awt.event.InputEvent ; 34 import java.awt.event.KeyAdapter ; 35 import java.awt.event.KeyEvent ; 36 import java.awt.event.KeyListener ; 37 import java.awt.event.MouseEvent ; 38 import java.beans.PropertyChangeEvent ; 39 import java.beans.PropertyChangeListener ; 40 import java.beans.PropertyVetoException ; 41 import java.beans.VetoableChangeListener ; 42 import java.io.Externalizable ; 43 import java.io.IOException ; 44 import java.io.ObjectInput ; 45 import java.io.ObjectOutput ; 46 import java.util.ArrayList ; 47 import java.util.List ; 48 import javax.accessibility.AccessibleContext ; 49 import javax.swing.AbstractAction ; 50 import javax.swing.Action ; 51 import javax.swing.BorderFactory ; 52 import javax.swing.BoxLayout ; 53 import javax.swing.JComponent ; 54 import javax.swing.JLabel ; 55 import javax.swing.JList ; 56 import javax.swing.JPanel ; 57 import javax.swing.JPopupMenu ; 58 import javax.swing.JScrollPane ; 59 import javax.swing.JTextField ; 60 import javax.swing.JViewport ; 61 import javax.swing.KeyStroke ; 62 import javax.swing.ListSelectionModel ; 63 import javax.swing.SwingUtilities ; 64 import javax.swing.ToolTipManager ; 65 import javax.swing.event.DocumentEvent ; 66 import javax.swing.event.DocumentListener ; 67 import javax.swing.event.ListDataEvent ; 68 import javax.swing.event.ListDataListener ; 69 import javax.swing.event.ListSelectionEvent ; 70 import javax.swing.event.ListSelectionListener ; 71 import javax.swing.text.Position ; 72 import org.openide.awt.MouseUtils; 73 import org.openide.explorer.ExplorerManager; 74 import org.openide.explorer.ExplorerManager.Provider; 75 import org.openide.nodes.Node; 76 import org.openide.nodes.Node.Property; 77 import org.openide.nodes.NodeOp; 78 import org.openide.util.ContextAwareAction; 79 import org.openide.util.NbBundle; 80 import org.openide.util.Utilities; 81 import org.openide.util.WeakListeners; 82 import org.openide.util.actions.CallbackSystemAction; 83 84 117 public class ListView extends JScrollPane implements Externalizable { 118 119 static final long serialVersionUID = -7540940974042262975L; 120 121 124 private transient ExplorerManager manager; 125 126 127 transient protected JList list; 128 129 130 transient protected NodeListModel model; 131 132 136 137 transient Listener managerListener; 138 139 140 transient PropertyChangeListener wlpc; 141 142 143 transient VetoableChangeListener wlvc; 144 145 146 transient PopupSupport popupSupport; 147 148 152 153 private boolean popupAllowed = true; 154 155 156 private boolean traversalAllowed = true; 157 158 159 private ActionListener defaultProcessor; 160 161 165 166 transient boolean dragActive = false; 167 168 169 transient boolean dropActive = false; 170 171 172 transient ListViewDragSupport dragSupport; 173 174 175 transient ListViewDropSupport dropSupport; 176 177 transient private int allowedDragActions = DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_REFERENCE; 179 transient private int allowedDropActions = DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_REFERENCE; 180 181 182 transient boolean listenerActive; 183 184 186 188 public ListView() { 189 initializeList(); 190 191 setDropTarget( DragDropUtilities.dragAndDropEnabled ); 193 194 setBorder(BorderFactory.createEmptyBorder()); 196 setViewportBorder(BorderFactory.createEmptyBorder()); 197 } 198 199 201 private void initializeList() { 202 model = createModel(); 204 list = createList(); 205 list.setModel(model); 206 207 setViewportView(list); 208 209 { 210 AbstractAction action = new GoUpAction(); 211 KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0); 212 list.registerKeyboardAction(action, key, JComponent.WHEN_FOCUSED); 213 } 214 215 { 216 AbstractAction action = new EnterAction(); 217 KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); 218 list.registerKeyboardAction(action, key, JComponent.WHEN_FOCUSED); 219 } 220 221 managerListener = new Listener (); 222 popupSupport = new PopupSupport(); 223 list.getActionMap().put("org.openide.actions.PopupAction", popupSupport); 225 list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 226 227 ToolTipManager.sharedInstance().registerComponent(list); 228 } 229 230 233 public void writeExternal(ObjectOutput out) throws IOException { 234 out.writeObject(popupAllowed ? Boolean.TRUE : Boolean.FALSE); 235 out.writeObject(traversalAllowed ? Boolean.TRUE : Boolean.FALSE); 236 out.writeObject(new Integer (getSelectionMode())); 237 } 238 239 242 public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException { 243 popupAllowed = ((Boolean ) in.readObject()).booleanValue(); 244 traversalAllowed = ((Boolean ) in.readObject()).booleanValue(); 245 setSelectionMode(((Integer ) in.readObject()).intValue()); 246 } 247 248 250 252 public boolean isPopupAllowed() { 253 return popupAllowed; 254 } 255 256 259 public void setPopupAllowed(boolean value) { 260 popupAllowed = value; 261 } 262 263 265 public boolean isTraversalAllowed() { 266 return traversalAllowed; 267 } 268 269 272 public void setTraversalAllowed(boolean value) { 273 traversalAllowed = value; 274 } 275 276 282 public ActionListener getDefaultProcessor() { 283 return defaultProcessor; 284 } 285 286 290 public void setDefaultProcessor(ActionListener value) { 291 defaultProcessor = value; 292 } 293 294 300 public void setSelectionMode(int selectionMode) { 301 list.setSelectionMode(selectionMode); 302 } 303 304 308 public int getSelectionMode() { 309 return list.getSelectionMode(); 310 } 311 312 313 317 public boolean isDragSource() { 318 return dragActive; 319 } 320 321 324 public void setDragSource(boolean state) { 325 if (state == dragActive) { 326 return; 327 } 328 329 dragActive = state; 330 331 if (dragActive && (dragSupport == null)) { 333 dragSupport = new ListViewDragSupport(this, list); 334 } 335 336 dragSupport.activate(dragActive); 338 } 339 340 344 public boolean isDropTarget() { 345 return dropActive; 346 } 347 348 352 public void setDropTarget(boolean state) { 353 if (state == dropActive) { 354 return; 355 } 356 357 dropActive = state; 358 359 if (dropActive && (dropSupport == null)) { 361 dropSupport = new ListViewDropSupport(this, list); 362 } 363 364 dropSupport.activate(dropActive); 366 } 367 368 373 public int getAllowedDragActions() { 374 return allowedDragActions; 375 } 376 377 380 public void setAllowedDragActions(int actions) { 381 allowedDragActions = actions; 383 } 384 385 390 public int getAllowedDropActions() { 391 return allowedDropActions; 392 } 393 394 397 public void setAllowedDropActions(int actions) { 398 allowedDropActions = actions; 400 } 401 402 406 408 protected JList createList() { 409 JList list = new NbList(); 410 list.setCellRenderer(new NodeRenderer()); 411 412 return list; 413 } 414 415 418 protected NodeListModel createModel() { 419 return new NodeListModel(); 420 } 421 422 429 protected void selectionChanged(Node[] nodes, ExplorerManager em) 430 throws PropertyVetoException { 431 em.setSelectedNodes(nodes); 432 } 433 434 441 protected boolean selectionAccept(Node[] nodes) { 442 if ((nodes.length == 1) && manager.getRootContext().equals(nodes[0])) { 444 return true; 446 } 447 448 for (int i = 0; i < nodes.length; i++) { 450 VisualizerNode v = VisualizerNode.getVisualizer(null, nodes[i]); 451 452 if (model.getIndex(v) == -1) { 453 return false; 454 } 455 } 456 457 return true; 458 } 459 460 463 protected void showSelection(int[] indexes) { 464 list.setSelectedIndices(indexes); 465 } 466 467 471 473 public void addNotify() { 474 super.addNotify(); 475 476 ExplorerManager em = ExplorerManager.find(this); 478 479 if (em != manager) { 480 if (manager != null) { 481 manager.removeVetoableChangeListener(wlvc); 482 manager.removePropertyChangeListener(wlpc); 483 } 484 485 manager = em; 486 487 manager.addVetoableChangeListener(wlvc = WeakListeners.vetoableChange(managerListener, manager)); 488 manager.addPropertyChangeListener(wlpc = WeakListeners.propertyChange(managerListener, manager)); 489 490 model.setNode(manager.getExploredContext()); 491 492 updateSelection(); 493 } else { 494 if (!listenerActive && (manager != null)) { 496 manager.addVetoableChangeListener(wlvc = WeakListeners.vetoableChange(managerListener, manager)); 497 manager.addPropertyChangeListener(wlpc = WeakListeners.propertyChange(managerListener, manager)); 498 } 499 } 500 501 if (!listenerActive) { 502 listenerActive = true; 503 list.getSelectionModel().addListSelectionListener(managerListener); 504 model.addListDataListener(managerListener); 505 506 model.setNode(manager.getExploredContext()); 509 list.addMouseListener(popupSupport); 510 } 511 } 512 513 515 public void removeNotify() { 516 super.removeNotify(); 517 listenerActive = false; 518 list.getSelectionModel().removeListSelectionListener(managerListener); 519 520 if (manager != null) { 522 manager.removeVetoableChangeListener(wlvc); 523 manager.removePropertyChangeListener(wlpc); 524 } 525 526 model.removeListDataListener(managerListener); 527 list.removeMouseListener(popupSupport); 528 } 529 530 531 public void requestFocus() { 532 list.requestFocus(); 533 } 534 535 536 public boolean requestFocusInWindow() { 537 return list.requestFocusInWindow(); 538 } 539 540 544 final void performObjectAt(int index, int modifiers) { 545 if ((index < 0) || (index >= model.getSize())) { 546 return; 547 } 548 549 VisualizerNode v = (VisualizerNode) model.getElementAt(index); 550 Node node = v.node; 551 552 if (defaultProcessor != null) { 554 defaultProcessor.actionPerformed(new ActionEvent (node, 0, null, modifiers)); 555 556 return; 557 } 558 559 Action a = node.getPreferredAction(); 562 563 if ((a != null) && ((modifiers & InputEvent.CTRL_MASK) == 0)) { 564 if (a instanceof ContextAwareAction) { 565 a = ((ContextAwareAction) a).createContextAwareInstance(node.getLookup()); 566 } 567 568 if (a.isEnabled()) { 569 a.actionPerformed(new ActionEvent (node, ActionEvent.ACTION_PERFORMED, "")); } else { 571 Toolkit.getDefaultToolkit().beep(); 572 } 573 } 574 else if (traversalAllowed && (!node.isLeaf())) { 576 manager.setExploredContext(node, manager.getSelectedNodes()); 577 } 578 } 579 580 582 private void updateSelection() { 583 Node[] sel = manager.getSelectedNodes(); 584 int[] indices = new int[sel.length]; 585 586 int firstVisible = list.getFirstVisibleIndex(); 588 int lastVisible = list.getLastVisibleIndex(); 589 boolean ensureVisible = indices.length > 0; 590 591 for (int i = 0; i < sel.length; i++) { 592 VisualizerNode v = VisualizerNode.getVisualizer(null, sel[i]); 593 indices[i] = model.getIndex(v); 594 ensureVisible = ensureVisible && ((indices[i] < firstVisible) || (indices[i] > lastVisible)); 595 } 596 597 if (listenerActive) { 600 list.getSelectionModel().removeListSelectionListener(managerListener); 601 } 602 603 try { 604 showSelection(indices); 605 606 if (ensureVisible) { 607 list.ensureIndexIsVisible(indices[0]); 608 } 609 } finally { 610 if (listenerActive) { 611 list.getSelectionModel().addListSelectionListener(managerListener); 612 } 613 } 614 } 615 616 void createPopup(int xpos, int ypos, boolean contextMenu) { 617 if (manager == null) { 618 return; 619 } 620 621 if (!popupAllowed) { 622 return; 623 } 624 625 JPopupMenu popup; 626 627 if (contextMenu) { 628 popup = Utilities.actionsToPopup(manager.getExploredContext().getActions(true), this); 629 } else { 630 Action [] actions = NodeOp.findActions(manager.getSelectedNodes()); 631 popup = Utilities.actionsToPopup(actions, this); 632 } 633 634 if ((popup != null) && (popup.getSubElements().length > 0)) { 635 Point p = getViewport().getViewPosition(); 636 p.x = xpos - p.x; 637 p.y = ypos - p.y; 638 639 SwingUtilities.convertPointToScreen(p, ListView.this); 640 641 Dimension popupSize = popup.getPreferredSize(); 642 Rectangle screenBounds = Utilities.getUsableScreenBounds(getGraphicsConfiguration()); 643 644 if ((p.x + popupSize.width) > (screenBounds.x + screenBounds.width)) { 645 p.x = (screenBounds.x + screenBounds.width) - popupSize.width; 646 } 647 648 if ((p.y + popupSize.height) > (screenBounds.y + screenBounds.height)) { 649 p.y = (screenBounds.y + screenBounds.height) - popupSize.height; 650 } 651 652 SwingUtilities.convertPointFromScreen(p, ListView.this); 653 popup.show(this, p.x, p.y); 654 } 655 } 656 657 659 663 final class NbList extends JList implements Autoscroll { 664 static final long serialVersionUID = -7571829536335024077L; 665 666 667 AutoscrollSupport support; 668 669 int SEARCH_FIELD_PREFERRED_SIZE = 160; 671 int SEARCH_FIELD_SPACE = 3; 672 private String maxPrefix; 673 674 private JTextField searchTextField = new JTextField () { 676 public boolean isManagingFocus() { 677 return true; 678 } 679 680 public void processKeyEvent(KeyEvent ke) { 681 if (ke.getKeyCode() == ke.VK_ESCAPE) { 685 removeSearchField(); 686 ke.consume(); 688 NbList.this.requestFocus(); 690 } else { 691 super.processKeyEvent(ke); 692 } 693 } 694 }; 695 696 final private int heightOfTextField = searchTextField.getPreferredSize().height; 697 private int originalScrollMode; 698 private JPanel searchpanel = null; 699 700 NbList() { 701 super(); 702 703 getInputMap().put(KeyStroke.getKeyStroke("control C"), "none"); getInputMap().put(KeyStroke.getKeyStroke("control V"), "none"); getInputMap().put(KeyStroke.getKeyStroke("control X"), "none"); setupSearch(); 712 } 713 714 public void addNotify() { 715 super.addNotify(); 716 ViewTooltips.register(this); 717 } 718 719 public void removeNotify() { 720 super.removeNotify(); 721 ViewTooltips.unregister(this); 722 } 723 724 protected void processFocusEvent(FocusEvent fe) { 725 super.processFocusEvent(fe); 726 repaintSelection(); 727 } 728 729 private void repaintSelection() { 730 int[] idx = getSelectedIndices(); 731 732 if (idx.length == 0) { 733 return; 734 } 735 736 for (int i = 0; i < idx.length; i++) { 737 Rectangle r = getCellBounds(idx[i], idx[i]); 738 repaint(r.x, r.y, r.width, r.height); 739 } 740 } 741 742 744 750 public String getToolTipText(MouseEvent event) { 751 if (event != null) { 752 Point p = event.getPoint(); 753 int row = locationToIndex(p); 754 755 if (row >= 0) { 756 VisualizerNode v = (VisualizerNode) model.getElementAt(row); 757 String tooltip = v.getShortDescription(); 758 String displayName = v.getDisplayName(); 759 760 if ((tooltip != null) && !tooltip.equals(displayName)) { 761 return tooltip; 762 } 763 } 764 } 765 766 return null; 767 } 768 769 771 772 public void autoscroll(Point cursorLoc) { 773 getSupport().autoscroll(cursorLoc); 774 } 775 776 779 public Insets getAutoscrollInsets() { 780 return getSupport().getAutoscrollInsets(); 781 } 782 783 784 AutoscrollSupport getSupport() { 785 if (support == null) { 786 support = new AutoscrollSupport(this, new Insets (15, 10, 15, 10)); 787 } 788 789 return support; 790 } 791 792 public AccessibleContext getAccessibleContext() { 794 if (accessibleContext == null) { 795 accessibleContext = new AccessibleExplorerList(); 796 } 797 798 return accessibleContext; 799 } 800 801 private void setupSearch() { 802 KeyListener [] keyListeners = (KeyListener []) (getListeners(KeyListener .class)); 804 805 for (int i = 0; i < keyListeners.length; i++) { 806 removeKeyListener(keyListeners[i]); 807 } 808 809 addKeyListener( 811 new KeyAdapter () { 812 public void keyPressed(KeyEvent e) { 813 int modifiers = e.getModifiers(); 814 int keyCode = e.getKeyCode(); 815 816 if (((modifiers > 0) && (modifiers != KeyEvent.SHIFT_MASK)) || e.isActionKey()) { 817 return; 818 } 819 820 char c = e.getKeyChar(); 821 822 if (!Character.isISOControl(c) && (keyCode != KeyEvent.VK_SHIFT)) { 823 searchTextField.setText(String.valueOf(c)); 824 displaySearchField(); 825 } 826 } 827 } 828 ); 829 830 SearchFieldListener searchFieldListener = new SearchFieldListener(); 835 searchTextField.addKeyListener(searchFieldListener); 836 searchTextField.addFocusListener(searchFieldListener); 837 searchTextField.getDocument().addDocumentListener(searchFieldListener); 838 } 839 840 private List <Integer > doSearch(String prefix) { 841 List <Integer > results = new ArrayList <Integer >(); 842 843 int startIndex = (getSelectedIndex() == -1) ? 0 : getSelectedIndex(); 845 int size = getModel().getSize(); 846 if (size == 0) return results; 848 while (true) { 849 startIndex = startIndex % size; 850 startIndex = getNextMatch(prefix, startIndex, Position.Bias.Forward); 851 852 if ((startIndex != -1) && !results.contains(new Integer (startIndex))) { 853 results.add(Integer.valueOf(startIndex)); 854 855 String elementName = getModel().getElementAt(startIndex).toString(); 856 857 if (maxPrefix == null) { 859 maxPrefix = elementName; 860 } 861 862 maxPrefix = findMaxPrefix(maxPrefix, elementName); 863 864 startIndex++; 866 } else { 867 break; 868 } 869 } 870 871 return results; 872 } 873 874 private String findMaxPrefix(String str1, String str2) { 875 String res = null; 876 877 for (int i = 0; str1.regionMatches(true, 0, str2, 0, i); i++) { 878 res = str1.substring(0, i); 879 } 880 881 return res; 882 } 883 884 private void prepareSearchPanel() { 885 if (searchpanel == null) { 886 searchpanel = new JPanel (); 887 888 JLabel lbl = new JLabel (NbBundle.getMessage(TreeView.class, "LBL_QUICKSEARCH")); searchpanel.setLayout(new BoxLayout (searchpanel, BoxLayout.X_AXIS)); 890 searchpanel.add(lbl); 891 searchpanel.add(searchTextField); 892 lbl.setLabelFor(searchTextField); 893 searchpanel.setBorder(BorderFactory.createRaisedBevelBorder()); 894 lbl.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); 895 } 896 } 897 898 901 private void displaySearchField() { 902 if ((getModel().getSize() > 0) && !searchTextField.isDisplayable()) { 903 JViewport viewport = ListView.this.getViewport(); 904 originalScrollMode = viewport.getScrollMode(); 905 viewport.setScrollMode(JViewport.SIMPLE_SCROLL_MODE); 906 907 prepareSearchPanel(); 909 add(searchpanel); 910 revalidate(); 911 repaint(); 912 913 SwingUtilities.invokeLater( 915 new Runnable () { 916 public void run() { 917 searchTextField.requestFocus(); 918 } 919 } 920 ); 921 } 922 } 923 924 public void doLayout() { 925 super.doLayout(); 926 927 if ((searchpanel != null) && searchpanel.isDisplayable()) { 928 Rectangle visibleRect = getVisibleRect(); 929 int width = Math.min( 930 visibleRect.width - (SEARCH_FIELD_SPACE * 2), 931 SEARCH_FIELD_PREFERRED_SIZE - SEARCH_FIELD_SPACE 932 ); 933 934 searchpanel.setBounds( 935 Math.max(SEARCH_FIELD_SPACE, (visibleRect.x + visibleRect.width) - width), 936 visibleRect.y + SEARCH_FIELD_SPACE, Math.min(visibleRect.width, width) - SEARCH_FIELD_SPACE, 937 heightOfTextField 938 ); 939 } 941 } 942 943 946 private void removeSearchField() { 947 if ((searchpanel != null) && searchpanel.isDisplayable()) { 948 remove(searchpanel); 949 ListView.this.getViewport().setScrollMode(originalScrollMode); 950 this.repaint(searchpanel.getBounds()); 951 requestFocus(); 952 } 953 } 954 955 private class AccessibleExplorerList extends AccessibleJList { 956 AccessibleExplorerList() { 957 } 958 959 public String getAccessibleName() { 960 return ListView.this.getAccessibleContext().getAccessibleName(); 961 } 962 963 public String getAccessibleDescription() { 964 return ListView.this.getAccessibleContext().getAccessibleDescription(); 965 } 966 } 967 968 private class SearchFieldListener extends KeyAdapter implements DocumentListener , FocusListener { 969 970 private List results = new ArrayList (); 971 972 973 private int currentSelectionIndex; 974 975 SearchFieldListener() { 976 } 977 978 public void changedUpdate(DocumentEvent e) { 979 searchForNode(); 980 } 981 982 public void insertUpdate(DocumentEvent e) { 983 searchForNode(); 984 } 985 986 public void removeUpdate(DocumentEvent e) { 987 searchForNode(); 988 } 989 990 public void keyPressed(KeyEvent e) { 991 int keyCode = e.getKeyCode(); 992 993 if (keyCode == KeyEvent.VK_ESCAPE) { 994 removeSearchField(); 995 NbList.this.requestFocus(); 996 } else if (keyCode == KeyEvent.VK_UP) { 997 currentSelectionIndex--; 998 displaySearchResult(); 999 1000 e.consume(); 1003 } else if (keyCode == KeyEvent.VK_DOWN) { 1004 currentSelectionIndex++; 1005 displaySearchResult(); 1006 1007 e.consume(); 1010 } else if (keyCode == KeyEvent.VK_TAB) { 1011 if (maxPrefix != null) { 1012 searchTextField.setText(maxPrefix); 1013 } 1014 1015 e.consume(); 1016 } else if (keyCode == KeyEvent.VK_ENTER) { 1017 removeSearchField(); 1018 NbList.this.requestFocus(); 1019 NbList.this.dispatchEvent(e); 1020 } 1021 } 1022 1023 1024 private void searchForNode() { 1025 currentSelectionIndex = 0; 1026 results.clear(); 1027 maxPrefix = null; 1028 1029 String text = searchTextField.getText(); 1030 1031 if (text.length() > 0) { 1032 results = doSearch(text); 1033 displaySearchResult(); 1034 } 1035 } 1036 1037 private void displaySearchResult() { 1038 int sz = results.size(); 1039 1040 if (sz > 0) { 1041 if (currentSelectionIndex < 0) { 1042 currentSelectionIndex = sz - 1; 1043 } else if (currentSelectionIndex >= sz) { 1044 currentSelectionIndex = 0; 1045 } 1046 1047 Integer index = (Integer ) results.get(currentSelectionIndex); 1048 list.setSelectedIndex(index.intValue()); 1049 list.ensureIndexIsVisible(index.intValue()); 1050 } else { 1051 list.clearSelection(); 1052 } 1053 } 1054 1055 public void focusGained(FocusEvent e) { 1056 } 1058 1059 public void focusLost(FocusEvent e) { 1060 removeSearchField(); 1061 } 1062 } 1063 1064 } 1066 1067 private final class PopupSupport extends MouseUtils.PopupMouseAdapter implements Action , Runnable { 1068 1069 CallbackSystemAction csa; 1070 1071 public PopupSupport() {} 1072 1073 public void mouseClicked(MouseEvent e) { 1074 if (MouseUtils.isDoubleClick(e)) { 1075 int index = list.locationToIndex(e.getPoint()); 1076 performObjectAt(index, e.getModifiers()); 1077 } 1078 } 1079 1080 protected void showPopup(MouseEvent e) { 1081 Point p = new Point (e.getX(), e.getY()); 1082 int i = list.locationToIndex(p); 1083 1084 if (!list.isSelectedIndex(i)) { 1085 list.setSelectedIndex(i); 1086 } 1087 1088 Rectangle r = list.getCellBounds(i, i); 1090 boolean contextMenu = (r == null) || !r.contains(p); 1091 1092 createPopup(e.getX(), e.getY(), contextMenu); 1093 } 1094 1095 public void actionPerformed(ActionEvent e) { 1096 SwingUtilities.invokeLater(this); 1098 } 1099 1100 public void run() { 1101 boolean multisel = (list.getSelectionMode() != ListSelectionModel.SINGLE_SELECTION); 1102 int i = (multisel ? list.getLeadSelectionIndex() : list.getSelectedIndex()); 1103 1104 if (i < 0) { 1105 return; 1106 } 1107 1108 Point p = list.indexToLocation(i); 1109 1110 if (p == null) { 1111 return; 1112 } 1113 1114 createPopup(p.x, p.y, false); 1115 } 1116 1117 public Object getValue(String key) { 1118 return null; 1119 } 1120 1121 public void putValue(String key, Object value) {} 1122 1123 public void setEnabled(boolean b) {} 1124 1125 public boolean isEnabled() { 1126 return true; 1128 } 1129 1130 public void addPropertyChangeListener(PropertyChangeListener listener) {} 1131 1132 public void removePropertyChangeListener(PropertyChangeListener listener) {} 1133 1134 } 1135 1136 private final class Listener implements ListDataListener , ListSelectionListener , PropertyChangeListener , 1137 VetoableChangeListener { 1138 Listener() { 1139 } 1140 1141 1142 public void intervalAdded(ListDataEvent evt) { 1143 updateSelection(); 1144 } 1145 1146 1147 public void intervalRemoved(ListDataEvent evt) { 1148 updateSelection(); 1149 } 1150 1151 1152 public void contentsChanged(ListDataEvent evt) { 1153 updateSelection(); 1154 } 1155 1156 public void vetoableChange(PropertyChangeEvent evt) 1157 throws PropertyVetoException { 1158 if (manager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) { 1159 Node[] newNodes = (Node[]) evt.getNewValue(); 1160 1161 if (!selectionAccept(newNodes)) { 1162 throw new PropertyVetoException ("", evt); } 1164 } 1165 } 1166 1167 public void propertyChange(PropertyChangeEvent evt) { 1168 if (manager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) { 1169 updateSelection(); 1170 1171 return; 1172 } 1173 1174 if (ExplorerManager.PROP_EXPLORED_CONTEXT.equals(evt.getPropertyName())) { 1175 model.setNode(manager.getExploredContext()); 1176 1177 return; 1179 } 1180 } 1181 1182 public void valueChanged(ListSelectionEvent e) { 1183 int curSize = model.getSize(); 1184 int[] indices = list.getSelectedIndices(); 1185 1186 List <Node> ll = new ArrayList <Node>(indices.length); 1188 1189 for (int i = 0; i < indices.length; i++) { 1190 if (indices[i] < curSize) { 1191 Node n = Visualizer.findNode(model.getElementAt(indices[i])); 1192 1193 if ((n == manager.getRootContext()) || (n.getParentNode() != null)) { 1194 ll.add(n); 1195 } 1196 } else { 1197 updateSelection(); 1199 1200 return; 1201 } 1202 } 1203 1204 Node[] nodes = ll.toArray(new Node[ll.size()]); 1205 1206 manager.removePropertyChangeListener(wlpc); 1208 manager.removeVetoableChangeListener(wlvc); 1209 1210 try { 1211 selectionChanged(nodes, manager); 1212 } catch (PropertyVetoException ex) { 1213 updateSelection(); 1215 } finally { 1216 manager.addPropertyChangeListener(wlpc); 1217 manager.addVetoableChangeListener(wlvc); 1218 } 1219 } 1220 } 1221 1222 private final class GoUpAction extends AbstractAction { 1224 static final long serialVersionUID = 1599999335583246715L; 1225 1226 public GoUpAction() { 1227 super("GoUpAction"); } 1229 1230 public void actionPerformed(ActionEvent e) { 1231 if (traversalAllowed) { 1232 Node pan = manager.getExploredContext(); 1233 pan = pan.getParentNode(); 1234 1235 if (pan != null) { 1236 manager.setExploredContext(pan, manager.getSelectedNodes()); 1237 } 1238 } 1239 } 1240 1241 public boolean isEnabled() { 1242 return true; 1243 } 1244 } 1245 1246 private final class EnterAction extends AbstractAction { 1248 static final long serialVersionUID = -239805141416294016L; 1249 1250 public EnterAction() { 1251 super("Enter"); } 1253 1254 public void actionPerformed(ActionEvent e) { 1255 int index = list.getSelectedIndex(); 1256 performObjectAt(index, e.getModifiers()); 1257 } 1258 1259 public boolean isEnabled() { 1260 return true; 1261 } 1262 } 1263} 1264 | Popular Tags |