|
|||||||||||
PREV NEXT | FRAMES NO FRAMES |
See:
Description
Code Folding API | |
org.netbeans.api.editor.fold | |
org.netbeans.spi.editor.fold |
The Code Folding was created to address requirements described in Code Folding UI Specification
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 javadoc
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(); }
|
OpenIDE-Module-Module-Dependencies: org.netbeans.modules.editor.fold/1 > 1.5.1
Read more about the implementation in the answers to architecture questions.
|
|||||||||||
PREV NEXT | FRAMES NO FRAMES |