? src/org/openide/resources/wait.gif Index: src/org/openide/loaders/Bundle.properties =================================================================== RCS file: /cvs/openide/src/org/openide/loaders/Bundle.properties,v retrieving revision 1.94 diff -r1.94 Bundle.properties 199a200,201 > > LBL_Wait=Please wait... Index: src/org/openide/loaders/FolderChildren.java =================================================================== RCS file: /cvs/openide/src/org/openide/loaders/FolderChildren.java,v retrieving revision 1.62 diff -r1.62 FolderChildren.java 24a25 > import org.openide.util.NbBundle; 26a28 > import org.openide.nodes.AbstractNode; 39,42d40 < /** initialization of children task */ < private Task initTask; < /** last task that refreshes the children nodes */ < private Task refreshTask; 47c45,51 < --- > /** this is true between addNotify and removeNotify */ > private boolean active; > > /** Private req processor for the refresh tasks */ > private static RequestProcessor refRP = > new RequestProcessor("FolderChildren_Refresh"); // NOI18N > 80c84 < refreshChildren (); --- > refreshChildren(); 88c92 < refreshChildren (); --- > refreshChildren(); 95,118c99,100 < void refreshChildren () { < initialize (true, false); < } < < /** Creates a key for given data object. < * This method is here to create something different then data object, < * because the data object should be finalized when not needed and < * that is why it should not be used as a key. < * < * @param obj data object < * @return key representing the data object. < */ < static Object createKey (DataObject obj) { < return new Pair (obj.getPrimaryFile ()); < } < < /** This method takes the key created by createKey and converts it < * into primary file. < * < * @param key the key < * @return primary file of the key < */ < private static FileObject getFile (Object key) { < return ((Pair)key).primaryFile; --- > Task refreshChildren() { > return refRP.post(new ChildrenRefreshRunnable()); 126c108 < FileObject fo = getFile (key); --- > FileObject fo = ((Pair)key).primaryFile; 130d111 < 141,183c122,127 < < /** Improves the searching capability to wait till all children < * are found and then searching thru them. < */ < public Node findChild (final String name) { < // start the initialization < Node[] forget = getNodes (); // DO NOT DELETE < < // waits till the list of children is created < < // JST: the folowing code is replacement for < // initialize (false, false).waitFinished () < // < // the orgiginal code caused deadlocks when called with readAccess, < // because the refreshChildren (which we wait for to be finished) < // method calls setKeys and they require write request < // < // this code could probably be replaced by < // Children.MUTEX.isReadAccess, if such call would be added to Mutex < class Jst implements Runnable { < public boolean checkReadOrWrite; < public boolean inReadAccess = true; < public boolean inWriteAccess = true; < public void run () { < if (checkReadOrWrite) { < inReadAccess = false; < } else { < inWriteAccess = false; < } < } < } < Jst t = new Jst (); < // the code will run either immediatally or after we leave readAccess < // section < Children.MUTEX.postWriteRequest(t); < t.checkReadOrWrite = true; < Children.MUTEX.postReadRequest(t); < < if (!t.inReadAccess && !t.inWriteAccess) { < // if we are not in readAccess we can safely wait till < // refreshChildren finishes and sets new keys for the < initialize (name == null, false).waitFinished (); < refreshTask.waitFinished (); --- > > public Node[] getNodes(boolean optimalResult) { > if (optimalResult) { > active = true; > Task t = refreshChildren(); > t.waitFinished(); 185,188c129 < < // do the regular child lookup < Node node = super.findChild (name); < return node; --- > return getNodes(); 190c131 < --- > 194d134 < initialize (true, true); 196a137,140 > // > active = true; > // start the refresh task to compute the children > refreshChildren(); 204,243c148,153 < setKeys (java.util.Collections.EMPTY_SET); < } < < /** Ensures that the content of children will be filled sometime. < * @param force true if the content should be filled immediatelly < */ < private Task initialize (boolean force, boolean waitFirst) { < < Task t = initTask; < < if (t != null && t.isFinished()) { < // if the original refresh task is finished we whould check if there are < // some new changes in progress and wait for them to finish < FolderList l = FolderList.find (folder.getPrimaryFile(), true); < l.waitProcessingFinished (); < < t = initTask; < } < < if (t != null && !force) { < return t; < } < < // if (t != null) { < // t.waitFinished (); < // refreshTask.waitFinished (); < // return t; < // } < < final Addition add = new Addition (waitFirst); < refreshTask = add.refTask; < < initTask = t = folder.computeChildrenList (add); < t.addTaskListener (add); < < if (waitFirst) { < add.waitFirst (); < } < < return t; --- > // > active = false; > // we don't call the setKeys directly here because > // there can be a task spawned by refreshChildren - so > // we want to clear the children after that task is finished > refreshChildren(); 250,256d159 < < /** time delay between two inserts of nodes */ < private static final int TIME_DELAY = 1024; < < /** Private req processor for Addition's refresh tasks */ < private static RequestProcessor refRP = < new RequestProcessor("FolderChildren_refresher"); 258,369c161,168 < /** Support for incremental adding of new nodes. < * < *
< * There is a deadlock warning: < *