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-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.openide.explorer.view;

import java.util.*;

import org.openide.nodes.*;

/** List of Visualizers. This is holded by parent visualizer by a
* weak reference, 
*
* @author Jaroslav Tulach
*/
final class VisualizerChildren extends Object {
    /** parent visualizer */
    public final VisualizerNode parent;
    /** list of all objects here (VisualizerNode) */
    public final List list = new LinkedList ();

    /** Creates new VisualizerChildren.
    * Can be called only from EventQueue.
    */
    public VisualizerChildren (VisualizerNode parent, Node[] nodes) {
        this.parent = parent;
        int s = nodes.length;
        for (int i = 0; i < s; i++) {
            VisualizerNode v = VisualizerNode.getVisualizer (this, nodes[i]);
            list.add (v);
        }
    }

    /** Notification of children addded event. Modifies the list of nodes
    * and fires info to all listeners.
    */
    public void added (VisualizerEvent.Added ev) {
        ListIterator it = list.listIterator ();
        boolean empty = !it.hasNext ();

        int[] indxs = ev.getArray ();
        Node[] nodes = ev.getAdded ();

        int current = 0;
        int inIndxs = 0;
        while (inIndxs < indxs.length) {
            while (current++ < indxs[inIndxs]) {
                it.next ();
            }
            it.add (VisualizerNode.getVisualizer (this, nodes[inIndxs]));
            inIndxs++;
        }


        VisualizerNode parent = this.parent;
        while (parent != null) {
            Object[] listeners = parent.getListenerList ();
            for (int i = listeners.length - 1; i >= 0; i -= 2) {
                ((NodeModel)listeners[i]).added (ev);
            }
            parent = (VisualizerNode)parent.getParent ();
        }

        if (empty) {
            // change of state
            this.parent.notifyVisualizerChildrenChange (list.size (), this);
        }

    }

    /** Notification that children has been removed. Modifies the list of nodes
    * and fires info to all listeners.
    */
    public void removed (VisualizerEvent.Removed ev) {
        List remList = Arrays.asList (ev.getRemovedNodes ());
        
        Iterator it = list.iterator ();
        
        VisualizerNode vis;
        
        int[] indx = new int[remList.size ()];
        int count = 0, remSize = 0;
        while (it.hasNext ()) {
            // take visualizer node
            vis = (VisualizerNode)it.next ();
            // check if it will removed
            if (remList.contains (vis.node)) {
                indx[remSize++] = count;
                // remove this VisualizerNode from children
                it.remove ();
                // bugfix #36389, add the removed node to VisualizerEvent
                ev.removed.add (vis);
            }
            count++;
        }
        
        // notify event about changed indexes
        ev.setRemovedIndicies (indx);
        
        VisualizerNode parent = this.parent;
        while (parent != null) {
            Object[] listeners = parent.getListenerList ();
            for (int i = listeners.length - 1; i >= 0; i -= 2) {
                ((NodeModel)listeners[i]).removed (ev);
            }
            parent = (VisualizerNode)parent.getParent ();
        }

        if (list.isEmpty ()) {
            // now is empty
            this.parent.notifyVisualizerChildrenChange (0, this);
        }
    }
    
    /**
     * Issue 37802, sort the actual list of children with the comparator, 
     * rather than expecting it to match the current children of the node,
     * which may be in an inconsistent state.
     */
    private int[] reorderByComparator (Comparator c) {
        Object[] old = list.toArray();
        Arrays.sort (old, c);
        
        int[] idxs = new int[old.length];
        for (int i=0; i < idxs.length; i++) {
            idxs[i] = list.indexOf (old[i]);
        }
        
        list.clear();
        list.addAll (Arrays.asList(old));
        return idxs;
    }
    
    /** Notification that children has been reordered. Modifies the list of nodes
    * and fires info to all listeners.
    */
    public void reordered (VisualizerEvent.Reordered ev) {
        if (ev.getComparator() != null) {
            //#37802
            ev.array = reorderByComparator (ev.getComparator());
        } else {
            
        int[] indxs = ev.getArray ();
        Object[] old = list.toArray ();
        Object[] arr = new Object[old.length];


        int s = indxs.length;
        try {
            for (int i = 0; i < s; i++) {
                // arr[indxs[i]] = old[i];
                Object old_i = old[i];
                int indxs_i = indxs[i];
                if (arr[indxs_i] != null) {
                    // this is bad <-- we are rewriting some old value --> there will remain some null somewhere
                    System.err.println("Writing to this index for the second time: " + indxs_i); // NOI18N
                    System.err.println("Length of indxs array: " + indxs.length); // NOI18N
                    System.err.println("Length of actual array: " + old.length); // NOI18N
                    System.err.println("Indices of reorder event:"); // NOI18N
                    for (int j = 0; i < indxs.length; j++)
                        System.err.println("\t" + indxs[j]); // NOI18N
                    Thread.dumpStack();
                    return;
                }
                arr[indxs_i] = old_i;
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
            System.err.println("Length of actual array: " + old.length); // NOI18N
            System.err.println("Indices of reorder event:"); // NOI18N
            for (int i = 0; i < indxs.length; i++)
                System.err.println("\t" + indxs[i]); // NOI18N
            return;
        }

        assert !Arrays.asList(arr).contains(null) : "Null element in reorderer list " + Arrays.asList(arr) + "; list=" + list + " indxs=" + Arrays.asList(org.openide.util.Utilities.toObjectArray(indxs));
        list.clear ();
        list.addAll (Arrays.asList (arr));
        assert !list.contains(null);
        
        }

        VisualizerNode parent = this.parent;
        while (parent != null) {
            Object[] listeners = parent.getListenerList ();
            for (int i = listeners.length - 1; i >= 0; i -= 2) {
                ((NodeModel)listeners[i]).reordered (ev);
            }
            parent = (VisualizerNode)parent.getParent ();
        }
    }

}
... 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.