001: package Schmortopf.FileComponents.Model;
002:
003: /**
004: * A basic tree model, without climbim yet.
005: *
006: * By a call to initializeTreeFromEditorContent( huge string )
007: * it will build a parser tree from the passed string.
008: *
009: */
010:
011: import java.awt.*;
012: import javax.swing.tree.*;
013: import java.io.*;
014:
015: import Schmortopf.JavaLanguageParser.*;
016: import Schmortopf.JavaLanguageParser.JavaCCParser.*;
017: import Schmortopf.FileComponents.View.*;
018: import Schmortopf.JavaSourceEditor.SourceEditorDocument;
019: import Schmortopf.FileStructure.*;
020: import Schmortopf.FileStructure.Descriptions.*;
021: import Schmortopf.ProjectFiles.ProjectFilesTree.ProjectFilesTreeModel;
022: import Shared.Logging.Log;
023:
024: public class FileComponentsTreeModel extends DefaultTreeModel {
025:
026: private DefaultMutableTreeNode rootNode;
027:
028: public FileComponentsTreeModel() {
029: super (new DefaultMutableTreeNode("", true), true);
030: // second parm true -> GUI difference between files and
031: // directories given by canHaveChildren.
032: this .rootNode = (DefaultMutableTreeNode) super .getRoot();
033: // and set it :
034: super .setRoot(this .rootNode);
035: }
036:
037: private void addFileNodes(final File basisFile,
038: final DefaultMutableTreeNode basisNode) {
039: if (basisFile.isDirectory()) {
040: File[] children = basisFile.listFiles();
041: for (int i = 0; i < children.length; i++) {
042: if (children[i].isDirectory()) {
043: // add to tree (allowsChildren = 2nd parm = true) :
044: final DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(
045: children[i].getName(), true);
046: basisNode.add(childNode);
047: // continue recursion :
048: this .addFileNodes(children[i], childNode);
049: } else {
050: // Just add that file :
051: final String fileName = children[i].getName();
052: // add to tree (allowsChildren = 2nd parm = false) :
053: final DefaultMutableTreeNode fileNode = new DefaultMutableTreeNode(
054: fileName, false);
055: basisNode.add(fileNode);
056: }
057: } // for
058: } // if
059: } // addFileNodes
060:
061: /**
062: * Called by the combined view-controler, when a new
063: * file has been selected and has been displayed in the editor.
064: *
065: * NOTE: This method must be threadsafe, because it also is called
066: * from outside the eventdispatch thread.
067: */
068: final public void initializeTreeFrom(
069: final FileStructureDescription fsd) {
070: // Convert the FSD into a tree model for the fileComponents tree :
071: final FileComponentsFSDProcessor treeConverter = new FileComponentsFSDProcessor();
072: final DefaultMutableTreeNode newFileComponentsRootNode = treeConverter
073: .convertFSDToTree(fsd);
074: // Now the view stuff :
075: // Change to EDT, if we aren't in already :
076: if (EventQueue.isDispatchThread()) {
077: // Remove any nodes without children :
078: removeNodesWithoutChildren(newFileComponentsRootNode);
079: // Now all is done, so set the new root node [which updates the view automatically, OF COURSE]:
080: setRoot(newFileComponentsRootNode);
081: } else {
082: try {
083: EventQueue.invokeAndWait(new Runnable() {
084: public void run() {
085: try {
086: // Remove any nodes without children :
087: removeNodesWithoutChildren(newFileComponentsRootNode);
088: // Now all is done, so set the new root node [which updates the view automatically, OF COURSE]:
089: setRoot(newFileComponentsRootNode);
090: } catch (Exception fce) {
091: Log.Error(fce);
092: }
093: }
094: });
095: } catch (Exception sdhkwer) {
096: }
097: }
098: } // initializeTreeFromEditorContent
099:
100: public void removeAll(final String emptyRootName) {
101: // Create the package root node :
102: final DefaultMutableTreeNode emptyRootNode = new DefaultMutableTreeNode(
103: emptyRootName, true);
104: this .setRoot(emptyRootNode);
105: }
106:
107: /**
108: * recursive method
109: */
110: private void removeNodesWithoutChildren(
111: final DefaultMutableTreeNode node) {
112: if (node.getAllowsChildren()) {
113: if (node.getChildCount() > 0) {
114: // Caution: indices and counts are modified, when one is removed,
115: // therefore we go reverse :
116: for (int i = node.getChildCount() - 1; i >= 0; i--) {
117: final DefaultMutableTreeNode this ChildNode = (DefaultMutableTreeNode) node
118: .getChildAt(i);
119: this .removeNodesWithoutChildren(this ChildNode);
120: }
121: } else {
122: node.removeFromParent();
123: }
124: }
125: }
126:
127: /**
128: * GC assistance, before this object is decoupled from the application.
129: * It should release reference connections.
130: * Called by the projectframe when it's closed.
131: * Calling method is projectframe.doFinalCleanUp() [ in a ThreadEngine thread ]
132: */
133: public void terminate() {
134: this .removeAll("");
135: } // terminate
136:
137: } // FileComponentsTreeModel
|