Source Code Cross Referenced for ListView.java in  » IDE-Netbeans » openide » org » openide » explorer » view » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » openide » org.openide.explorer.view 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.openide.explorer.view;
0043:
0044:        import java.awt.Dimension;
0045:        import java.awt.Insets;
0046:        import java.awt.Point;
0047:        import java.awt.Rectangle;
0048:        import java.awt.Toolkit;
0049:        import java.awt.dnd.Autoscroll;
0050:        import java.awt.dnd.DnDConstants;
0051:        import java.awt.event.ActionEvent;
0052:        import java.awt.event.ActionListener;
0053:        import java.awt.event.FocusEvent;
0054:        import java.awt.event.FocusListener;
0055:        import java.awt.event.InputEvent;
0056:        import java.awt.event.KeyAdapter;
0057:        import java.awt.event.KeyEvent;
0058:        import java.awt.event.KeyListener;
0059:        import java.awt.event.MouseEvent;
0060:        import java.beans.PropertyChangeEvent;
0061:        import java.beans.PropertyChangeListener;
0062:        import java.beans.PropertyVetoException;
0063:        import java.beans.VetoableChangeListener;
0064:        import java.io.Externalizable;
0065:        import java.io.IOException;
0066:        import java.io.ObjectInput;
0067:        import java.io.ObjectOutput;
0068:        import java.util.ArrayList;
0069:        import java.util.List;
0070:        import javax.accessibility.AccessibleContext;
0071:        import javax.swing.AbstractAction;
0072:        import javax.swing.Action;
0073:        import javax.swing.BorderFactory;
0074:        import javax.swing.BoxLayout;
0075:        import javax.swing.JComponent;
0076:        import javax.swing.JLabel;
0077:        import javax.swing.JList;
0078:        import javax.swing.JPanel;
0079:        import javax.swing.JPopupMenu;
0080:        import javax.swing.JScrollPane;
0081:        import javax.swing.JTextField;
0082:        import javax.swing.JViewport;
0083:        import javax.swing.KeyStroke;
0084:        import javax.swing.ListSelectionModel;
0085:        import javax.swing.SwingUtilities;
0086:        import javax.swing.ToolTipManager;
0087:        import javax.swing.event.DocumentEvent;
0088:        import javax.swing.event.DocumentListener;
0089:        import javax.swing.event.ListDataEvent;
0090:        import javax.swing.event.ListDataListener;
0091:        import javax.swing.event.ListSelectionEvent;
0092:        import javax.swing.event.ListSelectionListener;
0093:        import javax.swing.text.Position;
0094:        import org.openide.awt.MouseUtils;
0095:        import org.openide.explorer.ExplorerManager;
0096:        import org.openide.explorer.ExplorerManager.Provider;
0097:        import org.openide.nodes.Node;
0098:        import org.openide.nodes.Node.Property;
0099:        import org.openide.nodes.NodeOp;
0100:        import org.openide.util.ContextAwareAction;
0101:        import org.openide.util.NbBundle;
0102:        import org.openide.util.Utilities;
0103:        import org.openide.util.WeakListeners;
0104:        import org.openide.util.actions.CallbackSystemAction;
0105:
0106:        /** Explorer view to display items in a list.
0107:         * <p>
0108:         * This class is a <q>view</q>
0109:         * to use it properly you need to add it into a component which implements
0110:         * {@link Provider}. Good examples of that can be found 
0111:         * in {@link org.openide.explorer.ExplorerUtils}. Then just use 
0112:         * {@link Provider#getExplorerManager} call to get the {@link ExplorerManager}
0113:         * and control its state.
0114:         * </p>
0115:         * <p>
0116:         * There can be multiple <q>views</q> under one container implementing {@link Provider}. Select from
0117:         * range of predefined ones or write your own:
0118:         * </p>
0119:         * <ul>
0120:         *      <li>{@link org.openide.explorer.view.BeanTreeView} - shows a tree of nodes</li>
0121:         *      <li>{@link org.openide.explorer.view.ContextTreeView} - shows a tree of nodes without leaf nodes</li>
0122:         *      <li>{@link org.openide.explorer.view.ListView} - shows a list of nodes</li>
0123:         *      <li>{@link org.openide.explorer.view.IconView} - shows a rows of nodes with bigger icons</li>
0124:         *      <li>{@link org.openide.explorer.view.ChoiceView} - creates a combo box based on the explored nodes</li>
0125:         *      <li>{@link org.openide.explorer.view.TreeTableView} - shows tree of nodes together with a set of their {@link Property}</li>
0126:         *      <li>{@link org.openide.explorer.view.MenuView} - can create a {@link javax.swing.JMenu} structure based on structure of {@link Node}s</li>
0127:         * </ul>
0128:         * <p>
0129:         * All of these views use {@link ExplorerManager#find} to walk up the AWT hierarchy and locate the
0130:         * {@link ExplorerManager} to use as a controler. They attach as listeners to
0131:         * it and also call its setter methods to update the shared state based on the
0132:         * user action. Not all views make sence together, but for example
0133:         * {@link org.openide.explorer.view.ContextTreeView} and {@link org.openide.explorer.view.ListView} were designed to complement
0134:         * themselves and behaves like windows explorer. The {@link org.openide.explorer.propertysheet.PropertySheetView}
0135:         * for example should be able to work with any other view.
0136:         * </p>
0137:         * @author   Ian Formanek, Jan Jancura, Jaroslav Tulach
0138:         */
0139:        public class ListView extends JScrollPane implements  Externalizable {
0140:            /** generated Serialized Version UID */
0141:            static final long serialVersionUID = -7540940974042262975L;
0142:
0143:            /** Explorer manager to work with. Is not null only if the component is showing
0144:             * in components hierarchy
0145:             */
0146:            private transient ExplorerManager manager;
0147:
0148:            /** The actual JList list */
0149:            transient protected JList list;
0150:
0151:            /** model to use */
0152:            transient protected NodeListModel model;
0153:
0154:            //
0155:            // listeners
0156:            //
0157:
0158:            /** Listener to nearly everything */
0159:            transient Listener managerListener;
0160:
0161:            /** weak variation of the listener for property change on the explorer manager */
0162:            transient PropertyChangeListener wlpc;
0163:
0164:            /** weak variation of the listener for vetoable change on the explorer manager */
0165:            transient VetoableChangeListener wlvc;
0166:
0167:            /** popup */
0168:            transient PopupSupport popupSupport;
0169:
0170:            //
0171:            // properties
0172:            //
0173:
0174:            /** if true, the icon view displays a popup on right mouse click, if false, the popup is not displayed */
0175:            private boolean popupAllowed = true;
0176:
0177:            /** if true, the hierarchy traversal is allowed, if false, it is disabled */
0178:            private boolean traversalAllowed = true;
0179:
0180:            /** action preformer */
0181:            private ActionListener defaultProcessor;
0182:
0183:            //
0184:            // Dnd
0185:            //
0186:
0187:            /** true if drag support is active */
0188:            transient boolean dragActive = false;
0189:
0190:            /** true if drop support is active */
0191:            transient boolean dropActive = false;
0192:
0193:            /** Drag support */
0194:            transient ListViewDragSupport dragSupport;
0195:
0196:            /** Drop support */
0197:            transient ListViewDropSupport dropSupport;
0198:
0199:            // default DnD actions
0200:            transient private int allowedDragActions = DnDConstants.ACTION_COPY_OR_MOVE
0201:                    | DnDConstants.ACTION_REFERENCE;
0202:            transient private int allowedDropActions = DnDConstants.ACTION_COPY_OR_MOVE
0203:                    | DnDConstants.ACTION_REFERENCE;
0204:
0205:            /** True, if the selection listener is attached. */
0206:            transient boolean listenerActive;
0207:
0208:            // init .................................................................................
0209:
0210:            /** Default constructor.
0211:             */
0212:            public ListView() {
0213:                initializeList();
0214:
0215:                // activation of drop target
0216:                setDropTarget(DragDropUtilities.dragAndDropEnabled);
0217:
0218:                // no border, window system manages outer border itself
0219:                setBorder(BorderFactory.createEmptyBorder());
0220:                setViewportBorder(BorderFactory.createEmptyBorder());
0221:            }
0222:
0223:            /** Initializes the tree & model.
0224:             */
0225:            private void initializeList() {
0226:                // initilizes the JTree
0227:                model = createModel();
0228:                list = createList();
0229:                list.setModel(model);
0230:
0231:                setViewportView(list);
0232:
0233:                {
0234:                    AbstractAction action = new GoUpAction();
0235:                    KeyStroke key = KeyStroke.getKeyStroke(
0236:                            KeyEvent.VK_BACK_SPACE, 0);
0237:                    list.registerKeyboardAction(action, key,
0238:                            JComponent.WHEN_FOCUSED);
0239:                }
0240:
0241:                {
0242:                    AbstractAction action = new EnterAction();
0243:                    KeyStroke key = KeyStroke
0244:                            .getKeyStroke(KeyEvent.VK_ENTER, 0);
0245:                    list.registerKeyboardAction(action, key,
0246:                            JComponent.WHEN_FOCUSED);
0247:                }
0248:
0249:                managerListener = new Listener();
0250:                popupSupport = new PopupSupport();
0251:                list.getActionMap().put("org.openide.actions.PopupAction",
0252:                        popupSupport); // NOI18N
0253:
0254:                list.getSelectionModel().setSelectionMode(
0255:                        ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
0256:
0257:                ToolTipManager.sharedInstance().registerComponent(list);
0258:            }
0259:
0260:            /*
0261:             * Write view's state to output stream.
0262:             */
0263:            public void writeExternal(ObjectOutput out) throws IOException {
0264:                out.writeObject(popupAllowed ? Boolean.TRUE : Boolean.FALSE);
0265:                out
0266:                        .writeObject(traversalAllowed ? Boolean.TRUE
0267:                                : Boolean.FALSE);
0268:                out.writeObject(new Integer(getSelectionMode()));
0269:            }
0270:
0271:            /*
0272:             * Reads view's state form output stream.
0273:             */
0274:            public void readExternal(ObjectInput in) throws IOException,
0275:                    ClassNotFoundException {
0276:                popupAllowed = ((Boolean) in.readObject()).booleanValue();
0277:                traversalAllowed = ((Boolean) in.readObject()).booleanValue();
0278:                setSelectionMode(((Integer) in.readObject()).intValue());
0279:            }
0280:
0281:            // properties ...........................................................................
0282:
0283:            /** Test whether display of a popup menu is enabled.
0284:             * @return <code>true</code> if so */
0285:            public boolean isPopupAllowed() {
0286:                return popupAllowed;
0287:            }
0288:
0289:            /** Enable/disable displaying popup menus on list view items. Default is enabled.
0290:             * @param value <code>true</code> to enable
0291:             */
0292:            public void setPopupAllowed(boolean value) {
0293:                popupAllowed = value;
0294:            }
0295:
0296:            /** Test whether hierarchy traversal shortcuts are permitted.
0297:             * @return <code>true</code> if so */
0298:            public boolean isTraversalAllowed() {
0299:                return traversalAllowed;
0300:            }
0301:
0302:            /** Enable/disable hierarchy traversal using <code>CTRL+click</code> (down) and <code>Backspace</code> (up), default is enabled.
0303:             * @param value <code>true</code> to enable
0304:             */
0305:            public void setTraversalAllowed(boolean value) {
0306:                traversalAllowed = value;
0307:            }
0308:
0309:            /** Get the current processor for default actions.
0310:             * If not <code>null</code>, double-clicks or pressing Enter on
0311:             * items in the view will not perform the default action on the selected node; rather the processor
0312:             * will be notified about the event.
0313:             * @return the current default-action processor, or <code>null</code>
0314:             */
0315:            public ActionListener getDefaultProcessor() {
0316:                return defaultProcessor;
0317:            }
0318:
0319:            /** Set a new processor for default actions.
0320:             * @param value the new default-action processor, or <code>null</code> to restore use of the selected node's declared default action
0321:             * @see #getDefaultProcessor
0322:             */
0323:            public void setDefaultProcessor(ActionListener value) {
0324:                defaultProcessor = value;
0325:            }
0326:
0327:            /**
0328:             * Set whether single-item or multiple-item
0329:             * selections are allowed.
0330:             * @param selectionMode one of {@link ListSelectionModel#SINGLE_SELECTION}, {@link ListSelectionModel#SINGLE_INTERVAL_SELECTION}, or  {@link ListSelectionModel#MULTIPLE_INTERVAL_SELECTION}
0331:             * @see ListSelectionModel#setSelectionMode
0332:             */
0333:            public void setSelectionMode(int selectionMode) {
0334:                list.setSelectionMode(selectionMode);
0335:            }
0336:
0337:            /** Get the selection mode.
0338:             * @return the mode
0339:             * @see #setSelectionMode
0340:             */
0341:            public int getSelectionMode() {
0342:                return list.getSelectionMode();
0343:            }
0344:
0345:            /********** Support for the Drag & Drop operations *********/
0346:            /** @return true if dragging from the view is enabled, false
0347:             * otherwise.<br>
0348:             * Drag support is disabled by default.
0349:             */
0350:            public boolean isDragSource() {
0351:                return dragActive;
0352:            }
0353:
0354:            /** Enables/disables dragging support.
0355:             * @param state true enables dragging support, false disables it.
0356:             */
0357:            public void setDragSource(boolean state) {
0358:                if (state == dragActive) {
0359:                    return;
0360:                }
0361:
0362:                dragActive = state;
0363:
0364:                // create drag support if needed
0365:                if (dragActive && (dragSupport == null)) {
0366:                    dragSupport = new ListViewDragSupport(this , list);
0367:                }
0368:
0369:                // activate / deactivate support according to the state
0370:                dragSupport.activate(dragActive);
0371:            }
0372:
0373:            /** @return true if dropping to the view is enabled, false
0374:             * otherwise<br>
0375:             * Drop support is disabled by default.
0376:             */
0377:            public boolean isDropTarget() {
0378:                return dropActive;
0379:            }
0380:
0381:            /** Enables/disables dropping support.
0382:             * @param state true means drops into view are allowed,
0383:             * false forbids any drops into this view.
0384:             */
0385:            public void setDropTarget(boolean state) {
0386:                if (state == dropActive) {
0387:                    return;
0388:                }
0389:
0390:                dropActive = state;
0391:
0392:                // create drop support if needed
0393:                if (dropActive && (dropSupport == null)) {
0394:                    dropSupport = new ListViewDropSupport(this , list);
0395:                }
0396:
0397:                // activate / deactivate support according to the state
0398:                dropSupport.activate(dropActive);
0399:            }
0400:
0401:            /** Actions constants comes from {@link java.awt.dnd.DnDConstants}.
0402:             * All actions (copy, move, link) are allowed by default.
0403:             * @return int representing set of actions which are allowed when dragging from
0404:             * asociated component.
0405:             */
0406:            public int getAllowedDragActions() {
0407:                return allowedDragActions;
0408:            }
0409:
0410:            /** Sets allowed actions for dragging
0411:             * @param actions new drag actions, using {@link java.awt.dnd.DnDConstants}
0412:             */
0413:            public void setAllowedDragActions(int actions) {
0414:                // PENDING check parameters
0415:                allowedDragActions = actions;
0416:            }
0417:
0418:            /** Actions constants comes from {@link java.awt.dnd.DnDConstants}.
0419:             * All actions are allowed by default.
0420:             * @return int representing set of actions which are allowed when dropping
0421:             * into the asociated component.
0422:             */
0423:            public int getAllowedDropActions() {
0424:                return allowedDropActions;
0425:            }
0426:
0427:            /** Sets allowed actions for dropping.
0428:             * @param actions new allowed drop actions, using {@link java.awt.dnd.DnDConstants}
0429:             */
0430:            public void setAllowedDropActions(int actions) {
0431:                // PENDING check parameters
0432:                allowedDropActions = actions;
0433:            }
0434:
0435:            //
0436:            // Methods to override
0437:            //
0438:
0439:            /** Creates the list that will display the data.
0440:             */
0441:            protected JList createList() {
0442:                JList list = new NbList();
0443:                list.setCellRenderer(new NodeRenderer());
0444:
0445:                return list;
0446:            }
0447:
0448:            /** Allows subclasses to change the default model used for
0449:             * the list.
0450:             */
0451:            protected NodeListModel createModel() {
0452:                return new NodeListModel();
0453:            }
0454:
0455:            /** Called when the list changed selection and the explorer manager
0456:             * should be updated.
0457:             * @param nodes list of nodes that should be selected
0458:             * @param em explorer manager
0459:             * @exception PropertyVetoException if the manager does not allow the
0460:             *   selection
0461:             */
0462:            protected void selectionChanged(Node[] nodes, ExplorerManager em)
0463:                    throws PropertyVetoException {
0464:                em.setSelectedNodes(nodes);
0465:            }
0466:
0467:            /** Called when explorer manager is about to change the current selection.
0468:             * The view can forbid the change if it is not able to display such
0469:             * selection.
0470:             *
0471:             * @param nodes the nodes to select
0472:             * @return false if the view is not able to change the selection
0473:             */
0474:            protected boolean selectionAccept(Node[] nodes) {
0475:                // if the selection is just the root context, confirm the selection
0476:                if ((nodes.length == 1)
0477:                        && manager.getRootContext().equals(nodes[0])) {
0478:                    // XXX shouldn't this be exploredContext?
0479:                    return true;
0480:                }
0481:
0482:                // we do not allow selection in other than the exploredContext
0483:                for (int i = 0; i < nodes.length; i++) {
0484:                    VisualizerNode v = VisualizerNode.getVisualizer(null,
0485:                            nodes[i]);
0486:
0487:                    if (model.getIndex(v) == -1) {
0488:                        return false;
0489:                    }
0490:                }
0491:
0492:                return true;
0493:            }
0494:
0495:            /** Shows selection.
0496:             * @param indexes indexes of objects to select
0497:             */
0498:            protected void showSelection(int[] indexes) {
0499:                list.setSelectedIndices(indexes);
0500:            }
0501:
0502:            //
0503:            // Working methods
0504:            //
0505:
0506:            /* Initilizes the view.
0507:             */
0508:            public void addNotify() {
0509:                super .addNotify();
0510:
0511:                // run under mutex
0512:                ExplorerManager em = ExplorerManager.find(this );
0513:
0514:                if (em != manager) {
0515:                    if (manager != null) {
0516:                        manager.removeVetoableChangeListener(wlvc);
0517:                        manager.removePropertyChangeListener(wlpc);
0518:                    }
0519:
0520:                    manager = em;
0521:
0522:                    manager.addVetoableChangeListener(wlvc = WeakListeners
0523:                            .vetoableChange(managerListener, manager));
0524:                    manager.addPropertyChangeListener(wlpc = WeakListeners
0525:                            .propertyChange(managerListener, manager));
0526:
0527:                    model.setNode(manager.getExploredContext());
0528:
0529:                    updateSelection();
0530:                } else {
0531:                    // bugfix #23509, the listener were removed --> add it again
0532:                    if (!listenerActive && (manager != null)) {
0533:                        manager.addVetoableChangeListener(wlvc = WeakListeners
0534:                                .vetoableChange(managerListener, manager));
0535:                        manager.addPropertyChangeListener(wlpc = WeakListeners
0536:                                .propertyChange(managerListener, manager));
0537:                    }
0538:                }
0539:
0540:                if (!listenerActive) {
0541:                    listenerActive = true;
0542:                    list.getSelectionModel().addListSelectionListener(
0543:                            managerListener);
0544:                    model.addListDataListener(managerListener);
0545:
0546:                    // bugfix #23974, model doesn't reflect an explorer context change
0547:                    // because any listener was not active
0548:                    model.setNode(manager.getExploredContext());
0549:                    list.addMouseListener(popupSupport);
0550:                }
0551:            }
0552:
0553:            /** Removes listeners.
0554:             */
0555:            public void removeNotify() {
0556:                super .removeNotify();
0557:                listenerActive = false;
0558:                list.getSelectionModel().removeListSelectionListener(
0559:                        managerListener);
0560:
0561:                // bugfix #23509, remove useless listeners
0562:                if (manager != null) {
0563:                    manager.removeVetoableChangeListener(wlvc);
0564:                    manager.removePropertyChangeListener(wlpc);
0565:                }
0566:
0567:                model.removeListDataListener(managerListener);
0568:                list.removeMouseListener(popupSupport);
0569:
0570:                // #112536: [dafe] I wasn't able to find out real reason for #112536
0571:                // Following delaying works, but is hacky a bit and we have to check
0572:                // if ListView is reused - addNotify called again, which we check through isDisplayable
0573:                SwingUtilities.invokeLater(new Runnable() {
0574:                    public void run() {
0575:                        if (!isDisplayable()) {
0576:                            // #109123: clear the model, as it may become invalid, because we stopped 
0577:                            // tracking ExplorerManager changes through listeners
0578:                            model.setNode(Node.EMPTY);
0579:                        }
0580:                    }
0581:                });
0582:            }
0583:
0584:            /* Requests focus for the list component. Overrides superclass method. */
0585:            public void requestFocus() {
0586:                list.requestFocus();
0587:            }
0588:
0589:            /* Requests focus for the list component. Overrides superclass method. */
0590:            public boolean requestFocusInWindow() {
0591:                return list.requestFocusInWindow();
0592:            }
0593:
0594:            /** This method is called when user double-clicks on some object or
0595:             * presses Enter key.
0596:             * @param index Index of object in current explored context
0597:             */
0598:            final void performObjectAt(int index, int modifiers) {
0599:                if ((index < 0) || (index >= model.getSize())) {
0600:                    return;
0601:                }
0602:
0603:                VisualizerNode v = (VisualizerNode) model.getElementAt(index);
0604:                Node node = v.node;
0605:
0606:                // if DefaultProcessor is set, the default action is notified to it overriding the default action on nodes
0607:                if (defaultProcessor != null) {
0608:                    defaultProcessor.actionPerformed(new ActionEvent(node, 0,
0609:                            null, modifiers));
0610:
0611:                    return;
0612:                }
0613:
0614:                // on double click - invoke default action, if there is any
0615:                // (unless user holds CTRL key what means that we should always dive into the context)
0616:                Action a = node.getPreferredAction();
0617:
0618:                if ((a != null) && ((modifiers & InputEvent.CTRL_MASK) == 0)) {
0619:                    if (a instanceof  ContextAwareAction) {
0620:                        a = ((ContextAwareAction) a)
0621:                                .createContextAwareInstance(node.getLookup());
0622:                    }
0623:
0624:                    if (a.isEnabled()) {
0625:                        a.actionPerformed(new ActionEvent(node,
0626:                                ActionEvent.ACTION_PERFORMED, "")); // NOI18N
0627:                    } else {
0628:                        Toolkit.getDefaultToolkit().beep();
0629:                    }
0630:                }
0631:                // otherwise dive into the context
0632:                else if (traversalAllowed && (!node.isLeaf())) {
0633:                    manager
0634:                            .setExploredContext(node, manager
0635:                                    .getSelectedNodes());
0636:                }
0637:            }
0638:
0639:            /** Called when selection has been changed. Make selection visible (at least partly).
0640:             */
0641:            private void updateSelection() {
0642:                Node[] sel = manager.getSelectedNodes();
0643:                int[] indices = new int[sel.length];
0644:
0645:                // bugfix #27094, make sure a selection is visible
0646:                int firstVisible = list.getFirstVisibleIndex();
0647:                int lastVisible = list.getLastVisibleIndex();
0648:                boolean ensureVisible = indices.length > 0;
0649:
0650:                for (int i = 0; i < sel.length; i++) {
0651:                    VisualizerNode v = VisualizerNode.getVisualizer(null,
0652:                            sel[i]);
0653:                    indices[i] = model.getIndex(v);
0654:                    ensureVisible = ensureVisible
0655:                            && ((indices[i] < firstVisible) || (indices[i] > lastVisible));
0656:                }
0657:
0658:                // going to change list because of E.M.'s order -- temp disable the
0659:                // listener
0660:                if (listenerActive) {
0661:                    list.getSelectionModel().removeListSelectionListener(
0662:                            managerListener);
0663:                }
0664:
0665:                try {
0666:                    showSelection(indices);
0667:
0668:                    if (ensureVisible) {
0669:                        list.ensureIndexIsVisible(indices[0]);
0670:                    }
0671:                } finally {
0672:                    if (listenerActive) {
0673:                        list.getSelectionModel().addListSelectionListener(
0674:                                managerListener);
0675:                    }
0676:                }
0677:            }
0678:
0679:            void createPopup(int xpos, int ypos, boolean contextMenu) {
0680:                if (manager == null) {
0681:                    return;
0682:                }
0683:
0684:                if (!popupAllowed) {
0685:                    return;
0686:                }
0687:
0688:                JPopupMenu popup;
0689:
0690:                if (contextMenu) {
0691:                    popup = Utilities.actionsToPopup(manager
0692:                            .getExploredContext().getActions(true), this );
0693:                } else {
0694:                    Action[] actions = NodeOp.findActions(manager
0695:                            .getSelectedNodes());
0696:                    popup = Utilities.actionsToPopup(actions, this );
0697:                }
0698:
0699:                if ((popup != null) && (popup.getSubElements().length > 0)) {
0700:                    Point p = getViewport().getViewPosition();
0701:                    p.x = xpos - p.x;
0702:                    p.y = ypos - p.y;
0703:
0704:                    SwingUtilities.convertPointToScreen(p, ListView.this );
0705:
0706:                    Dimension popupSize = popup.getPreferredSize();
0707:                    Rectangle screenBounds = Utilities
0708:                            .getUsableScreenBounds(getGraphicsConfiguration());
0709:
0710:                    if ((p.x + popupSize.width) > (screenBounds.x + screenBounds.width)) {
0711:                        p.x = (screenBounds.x + screenBounds.width)
0712:                                - popupSize.width;
0713:                    }
0714:
0715:                    if ((p.y + popupSize.height) > (screenBounds.y + screenBounds.height)) {
0716:                        p.y = (screenBounds.y + screenBounds.height)
0717:                                - popupSize.height;
0718:                    }
0719:
0720:                    SwingUtilities.convertPointFromScreen(p, ListView.this );
0721:                    popup.show(this , p.x, p.y);
0722:                }
0723:            }
0724:
0725:            // innerclasses .........................................................................
0726:
0727:            /**
0728:             * Enhancement of standard JList.
0729:             * Provides access to the Node's ToolTips, Accessibility and Autoscrolling.
0730:             */
0731:            final class NbList extends JList implements  Autoscroll {
0732:                static final long serialVersionUID = -7571829536335024077L;
0733:
0734:                /** The worker for the scrolling */
0735:                AutoscrollSupport support;
0736:
0737:                // navigator
0738:                int SEARCH_FIELD_PREFERRED_SIZE = 160;
0739:                int SEARCH_FIELD_SPACE = 3;
0740:                private String maxPrefix;
0741:
0742:                // searchTextField manages focus because it handles VK_TAB key
0743:                private JTextField searchTextField = new JTextField() {
0744:                    public boolean isManagingFocus() {
0745:                        return true;
0746:                    }
0747:
0748:                    public void processKeyEvent(KeyEvent ke) {
0749:                        //override the default handling so that
0750:                        //the parent will never receive the escape key and
0751:                        //close a modal dialog
0752:                        if (ke.getKeyCode() == ke.VK_ESCAPE) {
0753:                            removeSearchField();
0754:                            ke.consume(); // #44394
0755:
0756:                            // bugfix #32909, reqest focus when search field is removed
0757:                            NbList.this .requestFocus();
0758:                        } else {
0759:                            super .processKeyEvent(ke);
0760:                        }
0761:                    }
0762:                };
0763:
0764:                final private int heightOfTextField = searchTextField
0765:                        .getPreferredSize().height;
0766:                private int originalScrollMode;
0767:                private JPanel searchpanel = null;
0768:
0769:                NbList() {
0770:                    super ();
0771:
0772:                    // fix for #18292
0773:                    // default action map for JList defines these shortcuts
0774:                    // but we use our own mechanism for handling them
0775:                    // following lines disable default L&F handling (if it is
0776:                    // defined on Ctrl-c, Ctrl-v and Ctrl-x)
0777:                    getInputMap().put(KeyStroke.getKeyStroke("control C"),
0778:                            "none"); // NOI18N
0779:                    getInputMap().put(KeyStroke.getKeyStroke("control V"),
0780:                            "none"); // NOI18N
0781:                    getInputMap().put(KeyStroke.getKeyStroke("control X"),
0782:                            "none"); // NOI18N
0783:                    setupSearch();
0784:                }
0785:
0786:                public void addNotify() {
0787:                    super .addNotify();
0788:                    ViewTooltips.register(this );
0789:                }
0790:
0791:                public void removeNotify() {
0792:                    super .removeNotify();
0793:                    ViewTooltips.unregister(this );
0794:                }
0795:
0796:                protected void processFocusEvent(FocusEvent fe) {
0797:                    super .processFocusEvent(fe);
0798:                    repaintSelection();
0799:                }
0800:
0801:                private void repaintSelection() {
0802:                    int[] idx = getSelectedIndices();
0803:
0804:                    if (idx.length == 0) {
0805:                        return;
0806:                    }
0807:
0808:                    for (int i = 0; i < idx.length; i++) {
0809:                        Rectangle r = getCellBounds(idx[i], idx[i]);
0810:                        repaint(r.x, r.y, r.width, r.height);
0811:                    }
0812:                }
0813:
0814:                // ToolTips:
0815:
0816:                /**
0817:                 * Overrides JComponent's getToolTipText method in order to allow
0818:                 * Node's tips to be used if they are useful.
0819:                 *
0820:                 * @param event the MouseEvent that initiated the ToolTip display
0821:                 */
0822:                public String getToolTipText(MouseEvent event) {
0823:                    if (event != null) {
0824:                        Point p = event.getPoint();
0825:                        int row = locationToIndex(p);
0826:
0827:                        if (row >= 0) {
0828:                            VisualizerNode v = (VisualizerNode) model
0829:                                    .getElementAt(row);
0830:                            String tooltip = v.getShortDescription();
0831:                            String displayName = v.getDisplayName();
0832:
0833:                            if ((tooltip != null)
0834:                                    && !tooltip.equals(displayName)) {
0835:                                return tooltip;
0836:                            }
0837:                        }
0838:                    }
0839:
0840:                    return null;
0841:                }
0842:
0843:                // Autoscroll:
0844:
0845:                /** notify the Component to autoscroll */
0846:                public void autoscroll(Point cursorLoc) {
0847:                    getSupport().autoscroll(cursorLoc);
0848:                }
0849:
0850:                /** @return the Insets describing the autoscrolling region or border
0851:                 * relative to the geometry of the implementing Component.
0852:                 */
0853:                public Insets getAutoscrollInsets() {
0854:                    return getSupport().getAutoscrollInsets();
0855:                }
0856:
0857:                /** Safe getter for autoscroll support. */
0858:                AutoscrollSupport getSupport() {
0859:                    if (support == null) {
0860:                        support = new AutoscrollSupport(this , new Insets(15,
0861:                                10, 15, 10));
0862:                    }
0863:
0864:                    return support;
0865:                }
0866:
0867:                // Accessibility:
0868:                public AccessibleContext getAccessibleContext() {
0869:                    if (accessibleContext == null) {
0870:                        accessibleContext = new AccessibleExplorerList();
0871:                    }
0872:
0873:                    return accessibleContext;
0874:                }
0875:
0876:                private void setupSearch() {
0877:                    // Remove the default key listeners
0878:                    KeyListener[] keyListeners = (KeyListener[]) (getListeners(KeyListener.class));
0879:
0880:                    for (int i = 0; i < keyListeners.length; i++) {
0881:                        removeKeyListener(keyListeners[i]);
0882:                    }
0883:
0884:                    // Add new key listeners
0885:                    addKeyListener(new KeyAdapter() {
0886:                        public void keyPressed(KeyEvent e) {
0887:                            int modifiers = e.getModifiers();
0888:                            int keyCode = e.getKeyCode();
0889:
0890:                            if (((modifiers > 0) && (modifiers != KeyEvent.SHIFT_MASK))
0891:                                    || e.isActionKey()) {
0892:                                return;
0893:                            }
0894:
0895:                            char c = e.getKeyChar();
0896:
0897:                            if (!Character.isISOControl(c)
0898:                                    && (keyCode != KeyEvent.VK_SHIFT)) {
0899:                                searchTextField.setText(String.valueOf(c));
0900:                                displaySearchField();
0901:                            }
0902:                        }
0903:                    });
0904:
0905:                    // Create a the "multi-event" listener for the text field. Instead of
0906:                    // adding separate instances of each needed listener, we're using a
0907:                    // class which implements them all. This approach is used in order
0908:                    // to avoid the creation of 4 instances which takes some time
0909:                    SearchFieldListener searchFieldListener = new SearchFieldListener();
0910:                    searchTextField.addKeyListener(searchFieldListener);
0911:                    searchTextField.addFocusListener(searchFieldListener);
0912:                    searchTextField.getDocument().addDocumentListener(
0913:                            searchFieldListener);
0914:                }
0915:
0916:                private List<Integer> doSearch(String prefix) {
0917:                    List<Integer> results = new ArrayList<Integer>();
0918:
0919:                    // do search forward the selected index
0920:                    int startIndex = (getSelectedIndex() == -1) ? 0
0921:                            : getSelectedIndex();
0922:                    int size = getModel().getSize();
0923:                    if (size == 0)
0924:                        return results; // nothing to search
0925:
0926:                    while (true) {
0927:                        startIndex = startIndex % size;
0928:                        startIndex = getNextMatch(prefix, startIndex,
0929:                                Position.Bias.Forward);
0930:
0931:                        if ((startIndex != -1)
0932:                                && !results.contains(new Integer(startIndex))) {
0933:                            results.add(Integer.valueOf(startIndex));
0934:
0935:                            String elementName = getModel().getElementAt(
0936:                                    startIndex).toString();
0937:
0938:                            // initialize prefix
0939:                            if (maxPrefix == null) {
0940:                                maxPrefix = elementName;
0941:                            }
0942:
0943:                            maxPrefix = findMaxPrefix(maxPrefix, elementName);
0944:
0945:                            // try next element
0946:                            startIndex++;
0947:                        } else {
0948:                            break;
0949:                        }
0950:                    }
0951:
0952:                    return results;
0953:                }
0954:
0955:                private String findMaxPrefix(String str1, String str2) {
0956:                    String res = null;
0957:
0958:                    for (int i = 0; str1.regionMatches(true, 0, str2, 0, i); i++) {
0959:                        res = str1.substring(0, i);
0960:                    }
0961:
0962:                    return res;
0963:                }
0964:
0965:                private void prepareSearchPanel() {
0966:                    if (searchpanel == null) {
0967:                        searchpanel = new JPanel();
0968:
0969:                        JLabel lbl = new JLabel(NbBundle.getMessage(
0970:                                TreeView.class, "LBL_QUICKSEARCH")); //NOI18N
0971:                        searchpanel.setLayout(new BoxLayout(searchpanel,
0972:                                BoxLayout.X_AXIS));
0973:                        searchpanel.add(lbl);
0974:                        searchpanel.add(searchTextField);
0975:                        lbl.setLabelFor(searchTextField);
0976:                        searchpanel.setBorder(BorderFactory
0977:                                .createRaisedBevelBorder());
0978:                        lbl.setBorder(BorderFactory.createEmptyBorder(0, 0, 0,
0979:                                5));
0980:                    }
0981:                }
0982:
0983:                /**
0984:                 * Adds the search field to the tree.
0985:                 */
0986:                private void displaySearchField() {
0987:                    if ((getModel().getSize() > 0)
0988:                            && !searchTextField.isDisplayable()) {
0989:                        JViewport viewport = ListView.this .getViewport();
0990:                        originalScrollMode = viewport.getScrollMode();
0991:                        viewport.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
0992:
0993:                        //Rectangle visibleTreeRect = getVisibleRect();
0994:                        prepareSearchPanel();
0995:                        add(searchpanel);
0996:                        revalidate();
0997:                        repaint();
0998:
0999:                        // bugfix #28501, avoid the chars duplicated on jdk1.3
1000:                        SwingUtilities.invokeLater(new Runnable() {
1001:                            public void run() {
1002:                                searchTextField.requestFocus();
1003:                            }
1004:                        });
1005:                    }
1006:                }
1007:
1008:                public void doLayout() {
1009:                    super .doLayout();
1010:
1011:                    if ((searchpanel != null) && searchpanel.isDisplayable()) {
1012:                        Rectangle visibleRect = getVisibleRect();
1013:                        int width = Math.min(visibleRect.width
1014:                                - (SEARCH_FIELD_SPACE * 2),
1015:                                SEARCH_FIELD_PREFERRED_SIZE
1016:                                        - SEARCH_FIELD_SPACE);
1017:
1018:                        searchpanel
1019:                                .setBounds(Math.max(SEARCH_FIELD_SPACE,
1020:                                        (visibleRect.x + visibleRect.width)
1021:                                                - width), visibleRect.y
1022:                                        + SEARCH_FIELD_SPACE, Math.min(
1023:                                        visibleRect.width, width)
1024:                                        - SEARCH_FIELD_SPACE, heightOfTextField);
1025:                        //System.err.println("Laid out search field: " + searchpanel.getBounds());
1026:                    }
1027:                }
1028:
1029:                /**
1030:                 * Removes the search field from the tree.
1031:                 */
1032:                private void removeSearchField() {
1033:                    if ((searchpanel != null) && searchpanel.isDisplayable()) {
1034:                        remove(searchpanel);
1035:                        ListView.this .getViewport().setScrollMode(
1036:                                originalScrollMode);
1037:                        this .repaint(searchpanel.getBounds());
1038:                        requestFocus();
1039:                    }
1040:                }
1041:
1042:                private class AccessibleExplorerList extends AccessibleJList {
1043:                    AccessibleExplorerList() {
1044:                    }
1045:
1046:                    public String getAccessibleName() {
1047:                        return ListView.this .getAccessibleContext()
1048:                                .getAccessibleName();
1049:                    }
1050:
1051:                    public String getAccessibleDescription() {
1052:                        return ListView.this .getAccessibleContext()
1053:                                .getAccessibleDescription();
1054:                    }
1055:                }
1056:
1057:                private class SearchFieldListener extends KeyAdapter implements 
1058:                        DocumentListener, FocusListener {
1059:                    /** The last search results */
1060:                    private List results = new ArrayList();
1061:
1062:                    /** The last selected index from the search results. */
1063:                    private int currentSelectionIndex;
1064:
1065:                    SearchFieldListener() {
1066:                    }
1067:
1068:                    public void changedUpdate(DocumentEvent e) {
1069:                        searchForNode();
1070:                    }
1071:
1072:                    public void insertUpdate(DocumentEvent e) {
1073:                        searchForNode();
1074:                    }
1075:
1076:                    public void removeUpdate(DocumentEvent e) {
1077:                        searchForNode();
1078:                    }
1079:
1080:                    public void keyPressed(KeyEvent e) {
1081:                        int keyCode = e.getKeyCode();
1082:
1083:                        if (keyCode == KeyEvent.VK_ESCAPE) {
1084:                            removeSearchField();
1085:                            NbList.this .requestFocus();
1086:                        } else if (keyCode == KeyEvent.VK_UP) {
1087:                            currentSelectionIndex--;
1088:                            displaySearchResult();
1089:
1090:                            // Stop processing the event here. Otherwise it's dispatched
1091:                            // to the tree too (which scrolls)
1092:                            e.consume();
1093:                        } else if (keyCode == KeyEvent.VK_DOWN) {
1094:                            currentSelectionIndex++;
1095:                            displaySearchResult();
1096:
1097:                            // Stop processing the event here. Otherwise it's dispatched
1098:                            // to the tree too (which scrolls)
1099:                            e.consume();
1100:                        } else if (keyCode == KeyEvent.VK_TAB) {
1101:                            if (maxPrefix != null) {
1102:                                searchTextField.setText(maxPrefix);
1103:                            }
1104:
1105:                            e.consume();
1106:                        } else if (keyCode == KeyEvent.VK_ENTER) {
1107:                            removeSearchField();
1108:                            NbList.this .requestFocus();
1109:                            NbList.this .dispatchEvent(e);
1110:                        }
1111:                    }
1112:
1113:                    /** Searches for a node in the tree. */
1114:                    private void searchForNode() {
1115:                        currentSelectionIndex = 0;
1116:                        results.clear();
1117:                        maxPrefix = null;
1118:
1119:                        String text = searchTextField.getText();
1120:
1121:                        if (text.length() > 0) {
1122:                            results = doSearch(text);
1123:                            displaySearchResult();
1124:                        }
1125:                    }
1126:
1127:                    private void displaySearchResult() {
1128:                        int sz = results.size();
1129:
1130:                        if (sz > 0) {
1131:                            if (currentSelectionIndex < 0) {
1132:                                currentSelectionIndex = sz - 1;
1133:                            } else if (currentSelectionIndex >= sz) {
1134:                                currentSelectionIndex = 0;
1135:                            }
1136:
1137:                            Integer index = (Integer) results
1138:                                    .get(currentSelectionIndex);
1139:                            list.setSelectedIndex(index.intValue());
1140:                            list.ensureIndexIsVisible(index.intValue());
1141:                        } else {
1142:                            list.clearSelection();
1143:                        }
1144:                    }
1145:
1146:                    public void focusGained(FocusEvent e) {
1147:                        // Do nothing
1148:                    }
1149:
1150:                    public void focusLost(FocusEvent e) {
1151:                        removeSearchField();
1152:                    }
1153:                }
1154:
1155:                // end of navigator
1156:            }
1157:
1158:            private final class PopupSupport extends
1159:                    MouseUtils.PopupMouseAdapter implements  Action, Runnable {
1160:
1161:                CallbackSystemAction csa;
1162:
1163:                public PopupSupport() {
1164:                }
1165:
1166:                public void mouseClicked(MouseEvent e) {
1167:                    if (MouseUtils.isDoubleClick(e)) {
1168:                        int index = list.locationToIndex(e.getPoint());
1169:                        performObjectAt(index, e.getModifiers());
1170:                    }
1171:                }
1172:
1173:                protected void showPopup(MouseEvent e) {
1174:                    Point p = new Point(e.getX(), e.getY());
1175:                    int i = list.locationToIndex(p);
1176:
1177:                    if (!list.isSelectedIndex(i)) {
1178:                        list.setSelectedIndex(i);
1179:                    }
1180:
1181:                    // the area of selected 
1182:                    Rectangle r = list.getCellBounds(i, i);
1183:                    boolean contextMenu = (r == null) || !r.contains(p);
1184:
1185:                    createPopup(e.getX(), e.getY(), contextMenu);
1186:                }
1187:
1188:                public void actionPerformed(ActionEvent e) {
1189:                    // XXX why later?
1190:                    SwingUtilities.invokeLater(this );
1191:                }
1192:
1193:                public void run() {
1194:                    boolean multisel = (list.getSelectionMode() != ListSelectionModel.SINGLE_SELECTION);
1195:                    int i = (multisel ? list.getLeadSelectionIndex() : list
1196:                            .getSelectedIndex());
1197:
1198:                    if (i < 0) {
1199:                        return;
1200:                    }
1201:
1202:                    Point p = list.indexToLocation(i);
1203:
1204:                    if (p == null) {
1205:                        return;
1206:                    }
1207:
1208:                    createPopup(p.x, p.y, false);
1209:                }
1210:
1211:                public Object getValue(String key) {
1212:                    return null;
1213:                }
1214:
1215:                public void putValue(String key, Object value) {
1216:                }
1217:
1218:                public void setEnabled(boolean b) {
1219:                }
1220:
1221:                public boolean isEnabled() {
1222:                    // XXX should maybe use logic in {@link #run}?
1223:                    return true;
1224:                }
1225:
1226:                public void addPropertyChangeListener(
1227:                        PropertyChangeListener listener) {
1228:                }
1229:
1230:                public void removePropertyChangeListener(
1231:                        PropertyChangeListener listener) {
1232:                }
1233:
1234:            }
1235:
1236:            private final class Listener implements  ListDataListener,
1237:                    ListSelectionListener, PropertyChangeListener,
1238:                    VetoableChangeListener {
1239:                Listener() {
1240:                }
1241:
1242:                /** Implements <code>ListDataListener</code> interface. */
1243:                public void intervalAdded(ListDataEvent evt) {
1244:                    updateSelection();
1245:                }
1246:
1247:                /** Implements <code>ListDataListener</code>. */
1248:                public void intervalRemoved(ListDataEvent evt) {
1249:                    updateSelection();
1250:                }
1251:
1252:                /** Implemetns <code>ListDataListener</code>. */
1253:                public void contentsChanged(ListDataEvent evt) {
1254:                    updateSelection();
1255:                }
1256:
1257:                public void vetoableChange(PropertyChangeEvent evt)
1258:                        throws PropertyVetoException {
1259:                    if (manager.PROP_SELECTED_NODES.equals(evt
1260:                            .getPropertyName())) {
1261:                        Node[] newNodes = (Node[]) evt.getNewValue();
1262:
1263:                        if (!selectionAccept(newNodes)) {
1264:                            throw new PropertyVetoException("", evt); // NOI18N
1265:                        }
1266:                    }
1267:                }
1268:
1269:                public void propertyChange(PropertyChangeEvent evt) {
1270:                    if (manager.PROP_SELECTED_NODES.equals(evt
1271:                            .getPropertyName())) {
1272:                        updateSelection();
1273:
1274:                        return;
1275:                    }
1276:
1277:                    if (ExplorerManager.PROP_EXPLORED_CONTEXT.equals(evt
1278:                            .getPropertyName())) {
1279:                        model.setNode(manager.getExploredContext());
1280:
1281:                        //System.out.println("Children: " + java.util.Arrays.asList (list.getValues ())); // NOI18N
1282:                        return;
1283:                    }
1284:                }
1285:
1286:                public void valueChanged(ListSelectionEvent e) {
1287:                    int curSize = model.getSize();
1288:                    int[] indices = list.getSelectedIndices();
1289:
1290:                    // bugfix #24193, check if the nodes in selection are in the view's root context
1291:                    List<Node> ll = new ArrayList<Node>(indices.length);
1292:
1293:                    for (int i = 0; i < indices.length; i++) {
1294:                        if (indices[i] < curSize) {
1295:                            Node n = Visualizer.findNode(model
1296:                                    .getElementAt(indices[i]));
1297:
1298:                            if ((n == manager.getRootContext())
1299:                                    || (n.getParentNode() != null)) {
1300:                                ll.add(n);
1301:                            }
1302:                        } else {
1303:                            // something went wrong?
1304:                            updateSelection();
1305:
1306:                            return;
1307:                        }
1308:                    }
1309:
1310:                    Node[] nodes = ll.toArray(new Node[ll.size()]);
1311:
1312:                    // forwarding TO E.M., so we won't listen to its cries for a while
1313:                    manager.removePropertyChangeListener(wlpc);
1314:                    manager.removeVetoableChangeListener(wlvc);
1315:
1316:                    try {
1317:                        selectionChanged(nodes, manager);
1318:                    } catch (PropertyVetoException ex) {
1319:                        // selection vetoed - restore previous selection
1320:                        updateSelection();
1321:                    } finally {
1322:                        manager.addPropertyChangeListener(wlpc);
1323:                        manager.addVetoableChangeListener(wlvc);
1324:                    }
1325:                }
1326:            }
1327:
1328:            // Backspace jumps to parent folder of explored context
1329:            private final class GoUpAction extends AbstractAction {
1330:                static final long serialVersionUID = 1599999335583246715L;
1331:
1332:                public GoUpAction() {
1333:                    super ("GoUpAction"); // NOI18N
1334:                }
1335:
1336:                public void actionPerformed(ActionEvent e) {
1337:                    if (traversalAllowed) {
1338:                        Node pan = manager.getExploredContext();
1339:                        pan = pan.getParentNode();
1340:
1341:                        if (pan != null) {
1342:                            manager.setExploredContext(pan, manager
1343:                                    .getSelectedNodes());
1344:                        }
1345:                    }
1346:                }
1347:
1348:                public boolean isEnabled() {
1349:                    return true;
1350:                }
1351:            }
1352:
1353:            //Enter key performObjectAt selected index.
1354:            private final class EnterAction extends AbstractAction {
1355:                static final long serialVersionUID = -239805141416294016L;
1356:
1357:                public EnterAction() {
1358:                    super ("Enter"); // NOI18N
1359:                }
1360:
1361:                public void actionPerformed(ActionEvent e) {
1362:                    int index = list.getSelectedIndex();
1363:                    performObjectAt(index, e.getModifiers());
1364:                }
1365:
1366:                public boolean isEnabled() {
1367:                    return true;
1368:                }
1369:            }
1370:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.