alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
package org.netbeans.modules.java.ui;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import org.openide.explorer.ExplorerManager;
import org.openide.nodes.Node;
import org.openide.nodes.Children;

/**
 * Binds a keyboard navigation to an ExplorerManager instance.
 *
 * @author  sdedic
 * @version 
 */
class NameNavigator extends KeyAdapter {
    private static final long KEY_TRESHOLD = 500;
    
    ExplorerManager manager;
    
    /**
     * Node name being completed from the keyboard.
     */
    private String nodeName = null;

    /**
     * Timestamp of the last keyboard event received.
     */
    private long lastEvent = 0;

    public NameNavigator(ExplorerManager manager) {
        this.manager = manager;
    }

    /**
     * Handles keyboard event. If the event comes after the time threshold elapsed,
     * it the current buffer will be cleared.
     */
    public void keyTyped( KeyEvent ke ) {
        long eventWhen = ke.getWhen();
        
        if (lastEvent > 0 && (eventWhen - lastEvent) > KEY_TRESHOLD) {
            resetNameBuffer();
        }
        lastEvent = eventWhen;
        navigateBy(ke.getKeyChar());
    }
    
    protected void checkTimeout() {
        if (System.currentTimeMillis() - lastEvent > KEY_TRESHOLD) 
            resetNameBuffer();
    }
    
    /**
     * Resets the internal name buffer.
     */
    protected void resetNameBuffer() {
        nodeName = null;
    }
    
    public String getPartialName() {
        return nodeName != null ? nodeName : "";
    }
    
    public void navigateBy(char ch) {
        Node[] selNodes = manager.getSelectedNodes();
        Node currentContext;
        
        if (selNodes == null || selNodes.length == 0)
            currentContext = null;
        else
            currentContext = selNodes[selNodes.length - 1];
        navigate(currentContext, ch);
    }
    
    /**
     * Navigates using one single character. Tries to look up node matching
     * the character and selects it in the explorer manager.
     */
    public Node navigate(Node context, char ch) {
        // Find whether we have to create new Node name or add
        // the character to the current. Based on event time
        // treshold.
        boolean start = nodeName == null;
        
        if (start) {
            nodeName = new String( new char[] { ch } );
        } else {
            // PENDING: some characters may terminate the selection
            // without having to wait the specified timeout interval.
            nodeName = nodeName + ch;
        }

        Node found = findNode(start, context, nodeName);

        return found;
    }

    /**
     * Implements the logic of finding a node.
     */
    protected Node findNode(boolean start, Node context, String namePrefix) {
        Node found = null;
        
        if (context != null) {
            if (!start) {
                // 1st: try to search at the same level:
                found = findSibling(context, nodeName);
            }            
            // 2nd: search children:
            if (found == null) {
                findChild(context, namePrefix, null);
            }
        }

        if (found == null) {
            Node exclude = context;

            // 3rd: search upper nodes.
            if (context != null) 
                context = context.getParentNode();
            if (context == null)
                context = manager.getExploredContext();
            found = findChild(context, nodeName, exclude);
        }
        return found;
    }

    /**
     * Searches for a node under the given parent, returning a node whose 
     * name begins with the specified prefix.
     */
    protected Node findNodeStartingWith(Node parent, Node exclude, 
        String prefix) {
        // Get children of the node
        Children children = parent.getChildren();
        if ( children == null || children == Children.LEAF ) {
            return null;
        }

        // Get array of the childNodes
        Node childNodes[] = children.getNodes();
        if ( childNodes == null ) {
            return null;
        }
        if ( childNodes.length == 0 ) {
            return null;
        }

        // Try to find node with name starting with the nodeName string
        for ( int i = 0; i < childNodes.length; i++ ) {
            if ( getNodeName(childNodes[i]).startsWith( nodeName ) &&
                 childNodes[i] != exclude) {
                return childNodes[i];
            }
        }

        return null;
    }
    
    protected String getNodeName(Node n) {
        return n.getName();
    }
    
    private Node findChild(Node parent, String prefix, Node exclude) {
        return findNodeStartingWith(parent, exclude, prefix);
    }
    
    private Node findSibling(Node ref, String namePrefix) {
        return findNodeStartingWith(ref.getParentNode(), null, namePrefix);
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.