| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| <!-- NewPage --> |
| <html lang="en"> |
| <head> |
| <!-- Generated by javadoc (1.8.0_181) on Fri Sep 14 11:35:15 BST 2018 --> |
| <title>Overview (Editor Code Folding)</title> |
| <meta name="date" content="2018-09-14"> |
| <link rel="stylesheet" type="text/css" href="javadoc.css" title="Style"> |
| <script type="text/javascript" src="script.js"></script> |
| </head> |
| <body> |
| <script type="text/javascript"><!-- |
| try { |
| if (location.href.indexOf('is-external=true') == -1) { |
| parent.document.title="Overview (Editor Code Folding)"; |
| } |
| } |
| catch(err) { |
| } |
| //--> |
| </script> |
| <noscript> |
| <div>JavaScript is disabled on your browser.</div> |
| </noscript> |
| <!-- ========= START OF TOP NAVBAR ======= --> |
| <div class="topNav"><a name="navbar.top"> |
| <!-- --> |
| </a> |
| <div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div> |
| <a name="navbar.top.firstrow"> |
| <!-- --> |
| </a> |
| <ul class="navList" title="Navigation"> |
| <li class="navBarCell1Rev">Overview</li> |
| <li>Package</li> |
| <li>Class</li> |
| <li>Use</li> |
| <li><a href="overview-tree.html">Tree</a></li> |
| <li><a href="deprecated-list.html">Deprecated</a></li> |
| <li><a href="index-files/index-1.html">Index</a></li> |
| <li><a href="help-doc.html">Help</a></li> |
| </ul> |
| <div class="aboutLanguage">org.netbeans.modules.editor.fold/1 1.47.1 </div> |
| </div> |
| <div class="subNav"> |
| <ul class="navList"> |
| <li>Prev</li> |
| <li>Next</li> |
| </ul> |
| <ul class="navList"> |
| <li><a href="index.html?overview-summary.html" target="_top">Frames</a></li> |
| <li><a href="overview-summary.html" target="_top">No Frames</a></li> |
| </ul> |
| <ul class="navList" id="allclasses_navbar_top"> |
| <li><a href="allclasses-noframe.html">All Classes</a></li> |
| </ul> |
| <div> |
| <script type="text/javascript"><!-- |
| allClassesLink = document.getElementById("allclasses_navbar_top"); |
| if(window==top) { |
| allClassesLink.style.display = "block"; |
| } |
| else { |
| allClassesLink.style.display = "none"; |
| } |
| //--> |
| </script> |
| </div> |
| <a name="skip.navbar.top"> |
| <!-- --> |
| </a></div> |
| <!-- ========= END OF TOP NAVBAR ========= --> |
| <div class="header"> |
| <h1 class="title">Editor Code Folding<br/><span style='font-style:normal; font-size:medium; font-weight:normal; background-color:#ffffff;'><a href='http://wiki.netbeans.org/API_Stability#Official' target='_blank'>Official</a></span></h1> |
| </div> |
| <div class="header"> |
| <div class="subTitle"> |
| <div class="block"> |
| The Code Folding was created to address requirements |
| described in |
| <a href="http://ui.netbeans.org/docs/ui/code_folding/cf_uispec.html" shape="rect"> |
| Code Folding UI Specification |
| </a></div> |
| </div> |
| <p>See: <a href="#overview.description">Description</a></p> |
| </div> |
| <div class="contentContainer"> |
| <table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Editor Code Folding table, listing packages, and an explanation"> |
| <caption><span>Editor Code Folding</span><span class="tabEnd"> </span></caption> |
| <tr> |
| <th class="colFirst" scope="col">Package</th> |
| <th class="colLast" scope="col">Description</th> |
| </tr> |
| <tbody> |
| <tr class="altColor"> |
| <td class="colFirst"><a href="org/netbeans/api/editor/fold/package-summary.html">org.netbeans.api.editor.fold</a></td> |
| <td class="colLast"> </td> |
| </tr> |
| <tr class="rowColor"> |
| <td class="colFirst"><a href="org/netbeans/spi/editor/fold/package-summary.html">org.netbeans.spi.editor.fold</a></td> |
| <td class="colLast"> </td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| <div class="contentContainer"><a name="overview.description"> |
| <!-- --> |
| </a> |
| <div class="block"><p> |
| The Code Folding was created to address requirements |
| described in |
| <a href="http://ui.netbeans.org/docs/ui/code_folding/cf_uispec.html" shape="rect"> |
| Code Folding UI Specification |
| </a> |
| |
| |
| <p> |
| It is a module located under /cvs/editor/fold directory. |
| </p> |
| |
| |
| <p> |
| It consists of |
| </p> |
| |
| |
| <ul> |
| |
| <li>API in org.netbeans.api.editor.fold</li> |
| |
| <li>SPI in org.netbeans.spi.editor.fold</li> |
| |
| <li>Implementation in org.netbeans.modules.editor.fold</li> |
| |
| </ul> |
| |
| Code Folding defines CodeFoldingAPI. |
| |
| <p> |
| The Javadoc documentation can be generated by using |
| </p> |
| |
| <pre xml:space="preserve"> |
| cd /cvs/editor/fold |
| ant javadoc |
| </pre> |
| |
| |
| </p> |
| <h3>What is New (see <a href="apichanges.html">all changes</a>)?</h3> |
| <ul> |
| |
| |
| <!--Search for dates that are later or equal to 1997-09-01 in |
| .--> |
| <!--Checking date 2013-3-12 with count of newer 0--><!--year ok--> |
| <li>Mar 12 '13 <a href="apichanges.html#fold-api-enhancements">Extensible FoldTypes, enhanced support for fold updates</a> |
| <p> |
| |
| <p> |
| |
| <code>FoldTypes</code> can be defined for a <i>mime type</i> by <code>FoldTypeProviders</code>. They |
| can form a type hierarchy. <code>FoldUtilities</code> provide methods to check fold enablement and |
| available FoldTypes. Working directly with Preferences is not advised. |
| </p> |
| |
| <p> |
| Fold can provide offsets to start and end of its content excluding <i>guard areas</i>. <code>FoldingSupport</code> |
| provides factories for comment-driven <code>FoldManager</code> and for fold <code>ContentReader</code> capable |
| of reading javadoc-style comments or similar. |
| </p> |
| |
| <p> |
| |
| <code>FoldOperation</code> allows to <code>update</code> folds with <code>FoldInfos</code>, removing, adding |
| or updating Folds as necessary. Existing FoldManagers can be simplified. Folds can be defined wihtout |
| initial state - the state will be determined form the options by the infrastructure. All folds defined |
| by a FoldManager can be retrieved from <code>FoldOperation.foldIterator()</code>, even though they are |
| blocked. |
| </p> |
| |
| </p> |
| </li> |
| <!--Checking date 2013-3-8 with count of newer 1--><!--year ok--> |
| <li>Mar 8 '13 <a href="apichanges.html#fold-editorlib-separation">Fold UI separation from Editor Library</a> |
| <p> |
| |
| <p> |
| |
| <code>FoldHierarchyMonitor</code> was introduced to allow hooking into UI when |
| a FoldHierarchy is produced for a JTextComponent. The 'active' flag is provided on |
| the <code>FoldHierarchy</code> to determine whether the hierarchy be popuplated with folds |
| at all. |
| </p> |
| |
| <p> |
| Using <code>FoldingSupport</code> utility class, clients can create instance of |
| <code>FoldManager</code> that creates folds based on comments, previously <code>CustomFoldManager</code> |
| in editor.lib module. |
| </p> |
| |
| </p> |
| </li> |
| <!--Checking date 2008-3-3 with count of newer 2--><!--year ok--> |
| <li>Mar 3 '08 <a href="apichanges.html#FoldOperation-owns-added">FoldOperation.owns(Fold) added</a> |
| <p> |
| |
| <p> |
| Added FoldOperation.owns(Fold) to check whether fold was produced |
| by a particular FoldOperation. |
| </p> |
| |
| </p> |
| </li> |
| </ul> |
| <h3>Use Cases</h3> |
| <answer id="arch-usecases"> |
| |
| |
| <h2> |
| API Use Cases |
| </h2> |
| |
| |
| <h3> |
| Exploring of the Folds |
| </h3> |
| |
| |
| <p> |
| The code folding structure (fold hierarchy) relates |
| to <code>javax.swing.JTextComponent</code> instance in one-to-one relationship. |
| <br> |
| To find the code folding hierarchy instance for the given non-null text component |
| the following code snippet can be used: |
| </p> |
| |
| |
| <pre xml:space="preserve"> |
| JTextComponent editorComponent = ... |
| FoldHierarchy hierarchy = FoldHierarchy.get(editorComponent); |
| </pre> |
| |
| |
| |
| <h3> |
| Explore the Folds Hierarchy |
| </h3> |
| |
| |
| <p> |
| The tree-based hierarchy has one non-removable and non-collapsable root fold |
| that covers the whole document. It can be obtained by |
| </p> |
| |
| |
| <pre xml:space="preserve"> |
| FoldHierarchy foldHierarchy = ... |
| Fold rootFold = hierarchy.getRootFold(); |
| </pre> |
| |
| |
| <p> |
| The children folds of the root fold (or children folds) |
| can be obtained by |
| </p> |
| |
| |
| <pre xml:space="preserve"> |
| // 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(); |
| } |
| </pre> |
| |
| |
| <p> |
| Index of the child in its parent can be found by |
| </p> |
| |
| |
| <pre xml:space="preserve"> |
| hierarchy.lock(); |
| try { |
| Fold rootFold = ... |
| int foldIndex = rootFold.getFoldIndex(childFold); |
| } finally { |
| hierarchy.unlock(); |
| } |
| </pre> |
| |
| |
| |
| <h3> |
| Collapse Nearest Fold |
| </h3> |
| |
| |
| <p> |
| In the given fold hierarchy find the nearest fold right at or after the given offset |
| and collapse it. |
| </p> |
| |
| |
| <pre xml:space="preserve"> |
| hierarchy.lock(); |
| try { |
| Fold fold = FoldUtilities.findNearestFold(hierarchy, offset); |
| hierarchy.collapse(fold); |
| } finally { |
| hierarchy.unlock(); |
| } |
| </pre> |
| |
| |
| |
| <h3> |
| Expand All Folds |
| </h3> |
| |
| |
| <p> |
| In the given fold hierarchy expand all folds that are currently collapsed. |
| </p> |
| |
| |
| <pre xml:space="preserve"> |
| FoldUtilities.expand(hierarchy, null); |
| </pre> |
| |
| |
| |
| <h3> |
| Collapse All Folds of Certain Type |
| </h3> |
| |
| |
| <p> |
| In the given fold hierarchy collapse all e.g. javadoc folds that are currently collapsed. |
| <br> |
| The example can be generalized to any fold type. |
| </p> |
| |
| |
| <pre xml:space="preserve"> |
| FoldUtilities.collapse(hierarchy, JAVADOC_FOLD_TYPE); |
| </pre> |
| |
| |
| |
| <h3> |
| Start Listening on Fold Hierarchy Changes |
| </h3> |
| |
| |
| <p> |
| In the given fold hierarchy start to listen on all changes |
| done in the hierarchy. |
| <br> |
| This is actually used e.g. in the Editor's View Hierarchy that needs |
| to refresh views based on the fold changes. |
| </p> |
| |
| |
| <pre xml:space="preserve"> |
| 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 |
| } |
| }); |
| |
| </pre> |
| |
| |
| |
| <h3> |
| Inspect Collapsed Folds in Affected Area |
| </h3> |
| |
| |
| <p> |
| Listen on the hierarchy changes |
| and refresh the views in the text area affected by the fold change. |
| <br> |
| Inspect the collapsed folds in the affected area |
| because special views need to be created for the collapsed folds. |
| <br> |
| The actual code in the View Hierarchy is somewhat different |
| but the one given here is more descriptive. |
| </p> |
| |
| |
| <pre xml:space="preserve"> |
| 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 |
| } |
| } |
| }); |
| </pre> |
| |
| |
| |
| |
| <h2> |
| SPI Use Cases |
| </h2> |
| |
| |
| <h3> |
| Create a New Fold Manager |
| </h3> |
| |
| |
| <p> |
| Manipulation of the folds is designed to be done by fold managers. |
| <br> |
| Those classes implement <code>FoldManager</code> interface in the SPI. |
| <br> |
| At initialization time they are given instance of <code>FoldOperation</code> |
| through which they can create, add or remove the fold instances. |
| </p> |
| |
| |
| <p> |
| To create and use a new <code>FoldManager</code> instance |
| it's necessary to |
| </p> |
| |
| |
| <ul> |
| |
| <li> Define the class of the FoldManager. |
| <pre xml:space="preserve"> |
| public class MyFoldManager implements FoldManager { // or extends AbstractFoldManager |
| |
| ... |
| |
| } |
| </pre> |
| |
| </li> |
| |
| |
| <li> Create FoldManagerFactory for the FoldManager. |
| <pre xml:space="preserve"> |
| |
| public class MyFoldManager ... |
| |
| ... |
| |
| public static final class Factory implements FoldManagerFactory { |
| |
| public FoldManager createFoldManager() { |
| return new MyFoldManager(); |
| } |
| |
| } |
| |
| } |
| </pre> |
| |
| </li> |
| |
| |
| <li> Register FoldManagerFactory into xml layer into the directory |
| "Editors/<mime-type>/FoldManager/" |
| </li> |
| |
| |
| <li> Enable Code Folding in editor's Settings initializer |
| (please see e.g. <code>NbJavaSettingsInitializer</code>) |
| <pre xml:space="preserve"> |
| |
| public class MySettingsInitializer ... |
| |
| public void updateSettingsMap(Class kitClass, Map settingsMap) { |
| ... |
| settingsMap.put(SettingsNames.CODE_FOLDING_ENABLE, Boolean.TRUE); |
| } |
| |
| } |
| </pre> |
| |
| </li> |
| |
| |
| </ul> |
| |
| |
| |
| <h3> |
| Create a New Fold by Fold Manager |
| </h3> |
| |
| |
| <p> |
| Create a new fold and add it to the hierarchy. The operation |
| is performed by the fold manager either at initialization phase |
| (in the <code>initFolds()</code> 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). |
| </p> |
| |
| |
| <p> |
| Operations that manipulate the hierarchy are done |
| in terms of a valid transaction over the fold hierarchy. |
| <br> |
| Transactions allow to fire the collected changes as a single |
| <code>FoldHierarchyEvent</code> at the time when they are committed. |
| </p> |
| |
| |
| <pre xml:space="preserve"> |
| // In the FoldManager's context |
| FoldOperation operation = getOperation(); |
| FoldHierarchyTransaction transaction = operation.openTransaction(); |
| try { |
| Fold fold = operation.createFold(...); |
| operation.addFoldToHierarchy(fold, transaction); |
| } finally { |
| transaction.commit(); |
| } |
| </pre> |
| |
| |
| |
| <h3> |
| Remove Fold from Hierarchy by Fold Manager |
| </h3> |
| |
| |
| <p> |
| Remove the existing fold from the hierarchy |
| </p> |
| |
| |
| <pre xml:space="preserve"> |
| // In the FoldManager's context |
| FoldOperation operation = getOperation(); |
| FoldHierarchyTransaction transaction = operation.openTransaction(); |
| try { |
| Fold fold = ... |
| operation.removeFoldFromHierarchy(fold, transaction); |
| } finally { |
| transaction.commit(); |
| } |
| </pre> |
| |
| |
| <h3>Updating Fold hierarchy</h3> |
| In the preceding cases, maintaining Folds was the FoldManager's responsibility. The FoldManager typically |
| held a copy of the Folds added to the hierarchy, and during the refresh, it compared them to the new data |
| and decided what folds to remove. |
| For simple cases, which only create/remove folds based on text positions, part of the work can be offloaded to the |
| FoldOperation: |
| |
| <pre xml:space="preserve"> |
| // create new fold positional information for all folds. |
| Collection<FoldInfo> newInfos = ...; |
| |
| // create FoldInfo for each of the fold |
| newInfos.add( |
| FoldInfo.range(start, end, type). |
| withTemplate(customTemplate). |
| withDescription(veryCustomDescription). |
| collapse(true) |
| ); |
| |
| // the hierarchy must be locked prior to update |
| |
| doc.readLock(); |
| hierarchy.lock(); |
| try { |
| operation.update(newInfos, null, null); |
| } finally { |
| } |
| </pre> |
| |
| The <code>update()</code> operation performs a diff, creates new folds, discards old ones, and updates the folds, which |
| prevailed. |
| |
| <h3>Accessing folds</h3> |
| Instead of keeping a copy of created folds, the FoldManager may call <code>operation.foldIterator</code>. The iterator |
| will enumerate all folds, including (recursively) blocked ones. |
| |
| </answer> |
| <h3>Exported Interfaces</h3> |
| |
| This table lists all of the module exported APIs |
| with |
| defined stability classifications. It is generated |
| based on answers to questions about the architecture |
| of the module. <a href="architecture-summary.html">Read them all</a>... |
| |
| |
| <a name="group-java"> |
| <h5>Group of java interfaces</h5> |
| </a> |
| <table cellpadding="1" cellspacing="0" border="0" class="tablebg" width="100%"> |
| <tr> |
| <td> |
| <table border="0" cellpadding="3" cellspacing="1" width="100%"> |
| <tr class="tablersh"> |
| <td align="CENTER" width="25%"><span class="titlectable">Interface Name</span></td><td align="CENTER" width="10%"><span class="titlectable">In/Out</span></td><td align="CENTER" width="10%"><span class="titlectable">Stability</span></td><td align="CENTER"><span class="titlectable">Specified in What Document?</span></td> |
| </tr> |
| <tr class="tabler"> |
| <td>CodeFoldingAPI</td><td>Exported</td><td><a href="http://wiki.netbeans.org/API_Stability#Official">Official</a></td><td><a name="java-CodeFoldingAPI"></a></td> |
| </tr> |
| </table> |
| </td> |
| </tr> |
| </table> |
| <p></p> |
| <h3>Implementation Details</h3> |
| <h5>Where are the sources for the module?</h5> |
| |
| <p> |
| <p> |
| The sources for the module are in the |
| <a href="http://hg.netbeans.org/" shape="rect">NetBeans Mercurial repositories</a>. |
| </p> |
| </p> |
| |
| <h5>What do other modules need to do to declare a dependency on this one, in addition to or instead of a plain module dependency?</h5> |
| Nothing. |
| <p> |
| Read more about the implementation in the <a href="architecture-summary.html">answers to |
| architecture questions</a>. |
| </p></div> |
| </div> |
| <!-- ======= START OF BOTTOM NAVBAR ====== --> |
| <div class="bottomNav"><a name="navbar.bottom"> |
| <!-- --> |
| </a> |
| <div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div> |
| <a name="navbar.bottom.firstrow"> |
| <!-- --> |
| </a> |
| <ul class="navList" title="Navigation"> |
| <li class="navBarCell1Rev">Overview</li> |
| <li>Package</li> |
| <li>Class</li> |
| <li>Use</li> |
| <li><a href="overview-tree.html">Tree</a></li> |
| <li><a href="deprecated-list.html">Deprecated</a></li> |
| <li><a href="index-files/index-1.html">Index</a></li> |
| <li><a href="help-doc.html">Help</a></li> |
| </ul> |
| <div class="aboutLanguage">org.netbeans.modules.editor.fold/1 1.47.1 </div> |
| </div> |
| <div class="subNav"> |
| <ul class="navList"> |
| <li>Prev</li> |
| <li>Next</li> |
| </ul> |
| <ul class="navList"> |
| <li><a href="index.html?overview-summary.html" target="_top">Frames</a></li> |
| <li><a href="overview-summary.html" target="_top">No Frames</a></li> |
| </ul> |
| <ul class="navList" id="allclasses_navbar_bottom"> |
| <li><a href="allclasses-noframe.html">All Classes</a></li> |
| </ul> |
| <div> |
| <script type="text/javascript"><!-- |
| allClassesLink = document.getElementById("allclasses_navbar_bottom"); |
| if(window==top) { |
| allClassesLink.style.display = "block"; |
| } |
| else { |
| allClassesLink.style.display = "none"; |
| } |
| //--> |
| </script> |
| </div> |
| <a name="skip.navbar.bottom"> |
| <!-- --> |
| </a></div> |
| <!-- ======== END OF BOTTOM NAVBAR ======= --> |
| <p class="legalCopy"><small><span class="footnote">Built on September 14 2018. | Copyright © 2017-2018 Apache Software Foundation. All Rights Reserved.</span></small></p> |
| </body> |
| </html> |