|
It is a module located under /cvs/editor/fold directory.
It consists of
The Javadoc documentation can be generated by using
cd /cvs/editor/fold ant javadocQuestion (arch-usecases): Describe the main use cases of the new API. Who will use it under what circumstances? What kind of code would typically need to be written to use the module? Answer:
The code folding structure (fold hierarchy) relates
to javax.swing.JTextComponent
instance in one-to-one relationship.
To find the code folding hierarchy instance for the given non-null text component
the following code snippet can be used:
JTextComponent editorComponent = ... FoldHierarchy hierarchy = FoldHierarchy.get(editorComponent);
The tree-based hierarchy has one non-removable and non-collapsable root fold that covers the whole document. It can be obtained by
FoldHierarchy foldHierarchy = ... Fold rootFold = hierarchy.getRootFold();
The children folds of the root fold (or children folds) can be obtained by
// the hierarchy must be locked prior exploration or manipulation hierarchy.lock(); try { Fold rootFold = ... int foldCount = rootFold.getFoldCount(); for (int i = 0; i < foldCount; i++) { Fold childFold = rootFold.getFold(i); } } finally { hierarchy.unlock(); }
Index of the child in its parent can be found by
hierarchy.lock(); try { Fold rootFold = ... int foldIndex = rootFold.getFoldIndex(childFold); } finally { hierarchy.unlock(); }
In the given fold hierarchy find the nearest fold right at or after the given offset and collapse it.
hierarchy.lock(); try { Fold fold = FoldUtilities.findNearestFold(hierarchy, offset); hierarchy.collapse(fold); } finally { hierarchy.unlock(); }
In the given fold hierarchy expand all folds that are currently collapsed.
FoldUtilities.expand(hierarchy, null);
In the given fold hierarchy collapse all e.g. javadoc folds that are currently collapsed.
The example can be generalized to any fold type.
FoldUtilities.collapse(hierarchy, JAVADOC_FOLD_TYPE);
In the given fold hierarchy expand the fold into which the caret
is going to be moved by Caret.setDot(offset)
.
The hierarchy must be locked and this example assumes that the underlying
document is already read-locked e.g. by Document.render()
.
FoldHierarchy hierarchy = FoldHierarchy.get(caretComponent); hierarchy.lock(); try { Fold collapsed = FoldUtilities.findCollapsedFold(hierarchy, offset, offset); if (collapsed != null && collapsed.getStartOffset() < offset && collapsed.getEndOffset() > offset) { hierarchy.expand(collapsed); } } finally { hierarchy.unlock(); }
In the given fold hierarchy start to listen on all changes
done in the hierarchy.
This is actually used e.g. in the Editor's View Hierarchy that needs
to refresh views based on the fold changes.
hierarchy.addFoldHierarchyListener(new FoldHierarchyListener() { public void foldHierarchyChanged(FoldHierarchyEvent evt) { // Hierarchy does not need to be locked here // // evt.getAffectedStartOffset() and getAffectedEndOffset() // give text area affected by the fold changes in the event } });
Listen on the hierarchy changes
and refresh the views in the text area affected by the fold change.
Inspect the collapsed folds in the affected area
because special views need to be created for the collapsed folds.
The actual code in the View Hierarchy is somewhat different
but the one given here is more descriptive.
hierarchy.addFoldHierarchyListener(new FoldHierarchyListener() { public void foldHierarchyChanged(FoldHierarchyEvent evt) { for (Iterator collapsedFoldIterator = FoldUtilities.collapsedFoldIterator(hierarchy, evt.getAffectedStartOffset(), evt.getAffectedEndOffset() ); it.hasNext(); ) { Fold collapsedFold = (Fold)it.next(); // Create special view for the collapsedFold } } });
Manipulation of the folds is designed to be done by fold managers.
Those classes implement FoldManager
interface in the SPI.
At initialization time they are given instance of FoldOperation
through which they can create, add or remove the fold instances.
To create and use a new FoldManager
instance
it's necessary to
public class MyFoldManager implements FoldManager { // or extends AbstractFoldManager ... }
public class MyFoldManager ... ... public static final class Factory implements FoldManagerFactory { public FoldManager createFoldManager() { return new MyFoldManager(); } } }
NbJavaSettingsInitializer
)
public class MySettingsInitializer ... public void updateSettingsMap(Class kitClass, Map settingsMap) { ... settingsMap.put(SettingsNames.CODE_FOLDING_ENABLE, Boolean.TRUE); } }
Create a new fold and add it to the hierarchy. The operation
is performed by the fold manager either at initialization phase
(in the initFolds()
which gets called automatically
by the infrastructure) or at any other time when the fold manager's
operation gets invoked (usually by a listener that the fold manager
attaches to be notified about changes that can cause the folds structure
to be changed - e.g. a parsing listener for java folds).
Operations that manipulate the hierarchy are done
in terms of a valid transaction over the fold hierarchy.
Transactions allow to fire the collected changes as a single
FoldHierarchyEvent
at the time when they are committed.
// In the FoldManager's context FoldOperation operation = getOperation(); FoldHierarchyTransaction transaction = operation.openTransaction(); try { Fold fold = operation.createFold(...); operation.addFoldToHierarchy(fold, transaction); } finally { transaction.commit(); }
Remove the existing fold from the hierarchy
// In the FoldManager's context FoldOperation operation = getOperation(); FoldHierarchyTransaction transaction = operation.openTransaction(); try { Fold fold = ... operation.removeFoldFromHierarchy(fold, transaction); } finally { transaction.commit(); }Question (arch-time): What are the time estimates of the work? Answer: The cvs/editor/fold module is currently maintained under fold_api branch of the editor module. Question (arch-quality): How will the quality of your code be tested and how are future regressions going to be prevented? Answer: The unit tests will be created to cover the functionality testing.
We are also considering to create randomized tests that would construct artificial fold managers and randomly insert/remove folds and do random modifications to the file. This way we could make a stress test for the fold merging algorithms present in FoldHierarchyTransaction (and FoldHierarchySpi).
Specific fold managers can have their own additional dependencies (e.g. java fold manager depends on Java Source Hierarchy etc.).
Question (dep-non-nb): What other projects outside NetBeans does this one depend on? Answer: No other projects. Question (dep-platform): On which platforms does your module run? Does it run in the same way on each? Answer: All platforms. Question (dep-jre): Which version of JRE do you need (1.2, 1.3, 1.4, etc.)? Answer: JDK1.4 and higher can be used. Question (dep-jrejdk): Do you require the JDK or is the JRE enough? Answer: JRE is sufficient.OpenIDE-Module-Module-Dependencies: org.netbeans.modules.editor.fold/1 > 1.2.1
java.io.File
directly?
Answer:
No.
Question (resources-layer):
Does your module provide own layer? Does it create any files or
folders in it? What it is trying to communicate by that and with which
components?
Answer:
No.
Question (resources-read):
Does your module read any resources from layers? For what purpose?
Answer:
Module reads fold managers registered fold manager factories for the given mime-type
from the Editors/<mime-type>/FoldManager folder.
Question (resources-mask):
Does your module mask/hide/override any resources provided by other modules in
their layers?
Answer:
No.
org.openide.util.Lookup
or any similar technology to find any components to communicate with? Which ones?
Answer:
No
Question (lookup-register):
Do you register anything into lookup for other code to find?
Answer:
No.
Question (lookup-remove):
Do you remove entries of other modules from lookup?
Answer:
No.
System.getProperty
) property?
Answer:
No.
Question (exec-component):
Is execution of your code influenced by any (string) property
of any of your components?
Answer:
The FoldHierarchy instance is physically stored as client property of the text component with key FoldHierarchy.class.
Question (exec-ant-tasks):
Do you define or register any ant tasks that other can use?
WARNING: Question with id="exec-ant-tasks" has not been answered!
Question (exec-classloader):
Does your code create its own class loader(s)?
Answer:
No.
Question (exec-reflection):
Does your code use Java Reflection to execute other code?
Answer:
No.
Question (exec-privateaccess):
Are you aware of any other parts of the system calling some of
your methods by reflection?
Answer:
No.
Question (exec-process):
Do you execute an external process from your module? How do you ensure
that the result is the same on different platforms? Do you parse output?
Do you depend on result code?
Answer:
No.
Question (exec-introspection):
Does your module use any kind of runtime type information (instanceof
,
work with java.lang.Class
, etc.)?
Answer:
No.
Question (exec-threading):
What threading models, if any, does your module adhere to?
Answer:
FoldHierarchy needs to be locked exclusively prior manipulation; FoldHierarchy.render(Runnable)
(or FoldHierarchy.lock()
) can be used to lock the hierarchy for an exclusive use.
java.awt.datatransfer.Transferable
?
Answer:
No clipboard support.
Typically the physical fold creation
and updating is fast compared to the collecting of the underlying
information. For example collecting of the information
for java folds requires consulting of parser information
which may not be present at the time yet so this may result
in even a few seconds delay waiting for document parsing.
Therefore the fold managers are encouraged to prepare
the fold-related data (resulting into fold boundary positions)
in a separate thread and schedule the physical fold creation
and fold hierarchy updates (which are reasonably fast)
into EDT thread (due to consistency purposes as the EDT
controls the document switching in the editor text component).
The FoldManager class javadoc contains the guiding information
as well.
Built on May 4 2005. | Portions Copyright 1997-2005 Sun Microsystems, Inc. All rights reserved.