⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smarttree.java

📁 JAVA开源LDAP浏览器jxplorer的源码!
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
package com.ca.directory.jxplorer.tree;

import com.ca.commons.cbutil.*;
import com.ca.commons.naming.*;
import com.ca.directory.jxplorer.*;
import com.ca.directory.jxplorer.event.JXplorerEvent;
import com.ca.directory.jxplorer.event.JXplorerEventGenerator;
import com.ca.directory.jxplorer.search.SearchGUI;
import com.ca.directory.jxplorer.viewer.AttributeDisplay;
import com.ca.directory.jxplorer.viewer.PluggableEditor;

import javax.naming.*;
import javax.naming.directory.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.*;
import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.event.*;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * SmartTree displays the directory, using configurable
 * icons.  The SmartTree uses an internal 'SmartNode' class
 * which stores information about a visible Entry.  The
 * display information is separate from the underlying
 * directory; if the class is modified or extended, care
 * must be taken to always keep the two in sych.
 */

// The drag and drop handling in this code owes a lot to the java world tutorial:
// http://www.javaworld.com/javaworld/javatips/jw-javatip97.html

public class SmartTree extends JTree
        implements TreeSelectionListener, DataListener,
        TreeExpansionListener, JXplorerEventGenerator,
        DragGestureListener, DropTargetListener, DragSourceListener

{
    boolean setup = false; // whether the delayed graphics constructor has been called.
    boolean activated = false; // whether the delayed action stuff has been called.


    public static String NODATA = CBIntText.get("cn=no entries");

    JXplorerEventGenerator eventPublisher; // if registered, this object is used to publish external events
    // (to programs that are using JXplorer as an embedded component)

    //final JTree           tree;            // the main JTree over which everything is built.

    Frame owner;           // used for Swing/graphics L&F continuity

    SmartNode root;            // the node representing the first RDN of the rootDN
    SmartNode rootDNBase;      // the node representing the lowest RDN of the rootDN (may = top if only 1 rdn in rootDN)

    DN rootDN;          // the full root DN

    SmartModel treeModel;       // the tree model used to track tree data

    DN currentDN;       // the currently selected DN

    SmartPopupTool popupTreeTool;   // the right-mouse-click tree tools menu

    DefaultTreeCellEditor treeEditor;      // widget that allows user to edit node names

    TreeCellEditor innerEditor;     // the custom widget that actually creates the editor component.

    SmartTreeCellRenderer treeRenderer;    // widget that display the nodes (text + icons)

    public boolean rootSet = false; // whether the root node is set.

    DataSource treeDataSource;               // where the tree obtains its data
    Vector treeDataSinks = new Vector(); // a list of objects interested in tree changes

    //int                   treeCapabilities; // a bit mask of DataQueries to respond to.

    public DXEntry entry; 			//TE: the current entry.

    String name;   // a unique name for the tree.

    AttributeDisplay pluggableEditorSource = null; // if initialised, this can find pluggable editors to set extended tree behaviour

    private SearchGUI searchGUI = null;
    static int treeNo = 0;


    public boolean dragging = false; // whether a drag 'n drop operation is in progress.

    /* Variables needed for DnD */
    private DragSource dragSource = null;
    //private DragSourceContext dragSourceContext = null;
    private Point cursorLocation = null;

    /**
     * A holder for the number of results returned by a search.
     * This is used in the status bar for user info.
     */
    public int numOfResults = 0;

    private static Logger log = Logger.getLogger(SmartTree.class.getName());


    /**
     * Constructor for SmartTree.  The Tree starts off disconnected, and
     * must be later linked to a data source (using @RegisterDataSource)
     * to become active.
     *
     * @param Owner          the owning awt component - used for look and feel updates
     * @param name           the 'name' of the tree - used for debugging,
     * @param resourceLoader - a resource Loader used to get extra tree icons.  May be null.
     */

    public SmartTree(Frame Owner, String name, CBResourceLoader resourceLoader)
    {
        treeNo++;
        owner = Owner;

        this.name = name;

        setRoot(NODATA);

        setup = true;  // one way or another, only do this once!

        SmartNode.init(resourceLoader);

        /*
         *    a custom renderer, shows mutli valued attributes and icons.
         */

        treeRenderer = new SmartTreeCellRenderer();
        setCellRenderer(treeRenderer);

        /*
         *    custom editor, allows editing of multi-valued rdn.
         */

        //treeEditor = new SmartTreeCellEditor(this, new DefaultTreeCellRenderer());  
        treeEditor = new SmartTreeCellEditor(this, treeRenderer);

        setCellEditor(treeEditor);

        treeModel = new SmartModel(root);
        setModel(treeModel);

        registerPopupTool(new SmartPopupTool(this));
        // disallow multiple selections...
        getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        addTreeSelectionListener(this);
        addTreeExpansionListener(this);

        // use the default editor, but nobble it to avoid editing when drag and drop
        // is operating, and stick special handling in for multi valued rdn editing...

        setTreeMouseListener();
        setTreeCellEditorListener();

        setEditable(true);                      // make sure the user can edit tree cells.

        setupDragAndDrop();
    }

    public String getName()
    {
        return name;
    }

    public String toString()
    {
        return name;
    }

    /**
     * Returns the currently selected Node.
     */
    protected SmartNode getSelectedNode()
    {
        if (getSelectionPath() == null) return null;
        return (SmartNode) getSelectionPath().getLastPathComponent();
    }

    /**
     * Set the popup tool that will be used by the tree.
     */

    public void registerPopupTool(SmartPopupTool tool)
    {
        popupTreeTool = tool;
    }

    /**
     * returns a vector of DNs being the all inclusive list of all DNs
     * in the subtree from the given apex DN.  Used by ldif save ftn.
     *
     * @return a Vector of DNs
     */

    public Vector getAllNodes(DN start)
    {
        if (start == null) return new Vector(0);          // sanity check
        SmartNode apex = treeModel.getNodeForDN(start);   // need the smart node to find children
        if (apex == null) return new Vector(0);           // another sanity check

        try
        {
            Vector result = new Vector(10);

            result.add(start);                    //

            Enumeration children = apex.children();  // find children of 'from'
            while (children.hasMoreElements())
            {
                DN next = new DN(start);
                next.addChildRDN(((SmartNode) children.nextElement()).getRDN());
                result.addAll(getAllNodes(next));
            }
            return result;
        }
        catch (Exception e)
        {
            log.log(Level.WARNING, "error in SmartTree dump: ", e);
            return new Vector(0);
        }
    }

    /**
     * This sets the root of the tree, creating the nodes
     * necessary to display it.  A small wrinkle: the
     * 'rootDN' is the base DN as given by the user, e.g.
     * 'o=Democorp,c=us'.  This may contain multiple RDNs.
     * the root node, however, is the top level node in the
     * display tree; it has only a single RDN (i.e. 'c=us'
     * in the above example.)  The rootDN therefore may be
     * displayed as a number of nodes in the tree (maybe the
     * rootDN should be renamed the 'baseDN' or something...)
     *
     * @param rootString the DN of the root as a string
     */

    public void setRoot(String rootString)
    {
        if (rootString == null)
            rootString = "";

        rootDN = new DN(rootString);   // rootString MAY BE BLANK!
        setRoot(rootDN);
    }

    /**
     * This sets the root of the tree, creating the nodes
     * necessary to display it.  A small wrinkle: the
     * 'rootDN' is the base DN as given by the user, e.g.
     * 'o=Democorp,c=us'.  This may contain multiple RDNs.
     * the root node, however, is the top level node in the
     * display tree; it has only a single RDN (i.e. 'c=us'
     * in the above example.)  The rootDN therefore may be
     * displayed as a number of nodes in the tree (maybe the
     * rootDN should be renamed the 'baseDN' or something...)
     *
     * @param rootDN the DN of the root as a DN object
     */

    public void setRoot(DN rootDN)
    {
        rootSet = true;
        if (rootDN == null) rootDN = new DN();  // equivalent to empty DN, 'cn=World'

        /*
         *    Special handling for 'No Data' trees...
         */

        if (NODATA.equals(rootDN.toString()))
        {
            rootDN = new DN(NODATA);
            root = new SmartNode(NODATA);
            rootDNBase = root;
            rootSet = false;
            if (treeModel != null)
            {
                treeModel.setRoot(root);
                treeModel.reload();
            }
            return;
        }

        this.rootDN = rootDN;

        root = new SmartNode("");      	// equivalent to new SmartNode("cn=World")
        root.setRoot(true);
        root.setStructural(true);

        treeModel.setRoot(root); 		// reset the tree Model

        // set up the path to the lowest node of the DN, creating smart nodes for each RDN.

        SmartNode parent = root;
        rootDNBase = root;

        for (int i = 0; i < rootDN.size(); i++)
        {
            SmartNode child = new SmartNode(rootDN.getRDN(i));
            child.setStructural(true);
            parent.add(child);
            parent = child;
        }
        rootDNBase = parent;
        rootDNBase.add(new SmartNode());  // stick in a dummy node so there's something to expand to...

        treeModel.reload();

        if (rootDN.size() > 0)
            expandPath(treeModel.getPathForNode(rootDNBase));
        else
            collapseRow(0);


    }


    /**
     * Forces a particular DN that is already in the tree to be displayed.
     */

    public void expandDN(DN dn)
    {
        TreePath path = treeModel.getPathForDN(dn);

        expandPath(path.getParentPath());  // without the 'getParentPath()' the next level children are shown as well.
    }

    /**
     * Forces the root node of the tree to expand.
     * (May trigger a list request)
     */

    public void expandRoot()
    {
        expandRow(0);
    }

    /**
     * Get the rootDN of the tree (often the same as the directory DSE
     * naming prefix, e.g. 'o=DemoCorp,c=au'.
     *
     * @return the root DN
     */

    public DN getRootDN()
    {
        return (rootSet) ? rootDN : null;
    }

    /**
     * Get the root node of tree.  Needed for root.setStructural() hack
     */
    public SmartNode getRootNode()
    {
        return root;
    }

    /**
     * Get the lowest smart node of the baseDN.
     * For example, if base dn is ou=R&D,o=Democorp,c=au, this
     * returns the SmartNode corresponding to ou=R&D.
     */
    public SmartNode getLowestRootNode()
    {
        return rootDNBase;
    }

    /**
     * Returns the tree model used by the Smart Tree to store node data in.
     */

    public SmartModel getTreeModel()
    {
        return treeModel;
    }

    /**
     * registers the data source the tree is to use to read its
     * data (e.g. a JNDIBroker).  There can be only one of these.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -