SearchResultsTree.java :  » IDE » Schmortopf » Schmortopf » SearchResults » Java Open Source

Java Open Source » IDE » Schmortopf 
Schmortopf » Schmortopf » SearchResults » SearchResultsTree.java
package Schmortopf.SearchResults;
                                                                         
                                                                                              
  /**                                                                          
   *  This tree displays the results of text searches.                               
   *  It contains nodes for all files containing the search text
   *  and leafs, which force the editor to display the associated
   *  file and jump to the line and position of the found text,
   *  when the user clicks that leaf.
   */
                                                                           
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;                 
import java.util.*;
                                   
import Schmortopf.Main.IDE_ProjectFrameProvider;
import Schmortopf.Main.GCMemoryChecker;
import Schmortopf.Main.FilesTreeProvider;
import Schmortopf.ProjectFiles.ProjectFilesTree.*;
import Schmortopf.Utility.ThreadEngine.ThreadEngine;
import Schmortopf.Utility.Text.*;
import Schmortopf.Utility.IniFile.IniFile;
import Schmortopf.Utility.gui.dialogs.ProgressWindow;
import Schmortopf.Utility.gui.dialogs.TextSearchDialog;
import Schmortopf.Utility.SchmortopfConstants;
import Schmortopf.FileComponents.Model.EditableLeafObject;
import Schmortopf.Libraries.LibrariesTree;
import Schmortopf.Libraries.LibrariesTreeLeafObject;
import Schmortopf.FileStructure.FileStructureDescriptionFactory;
import Schmortopf.FileStructure.Descriptions.FileStructureDescription;
import Language.Language;
                                             
  

public class SearchResultsTree extends JTree
{                                                                                                    
                                    

  private IDE_ProjectFrameProvider projectFrame;

  private SearchResultsTreeModel model;
       
  private boolean readyForSpecialUpdates = false;
  // Needed, as some updateUI() calls are too early
  // for the special UI updates, cause some components
  // could not be existing yet.
                          
  private long lastGCCallTime = 0; // used by checkMemory()                        
                      
  private String treeName = "undefined";



 /**
  *  Constructor
  *  @param _projectFrame  the project frame as controller
  *  @param _treeName  the name displayed in the search tabs
  */
  public SearchResultsTree( final IDE_ProjectFrameProvider _projectFrame,
                            final String _treeName )
  {
    this.projectFrame = _projectFrame; 
    this.treeName = _treeName;
    this.model = new SearchResultsTreeModel();                                               
    this.setModel( this.model );
    this.setCellRenderer( new SearchResultsTreeCellRenderer() );

    final SearchResultsTree thisTree = this;
    this.addTreeSelectionListener( new TreeSelectionListener()
     {
       public void valueChanged(TreeSelectionEvent e)
       {             
         final DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)
               thisTree.getLastSelectedPathComponent();
         if( selectedNode != null )
          {
            final Object userObject = selectedNode.getUserObject();
            if( userObject instanceof SearchResultsUserObject )
             {
               final SearchResultsUserObject searchObject = (SearchResultsUserObject)userObject;
               showSearchHit( searchObject ); // does all what's needed :
             }
            else
            if( userObject instanceof SearchResultsFileNodeUserObject )
             {  
               // This is true for results of filename searches, where the file as whole
               // is the subject and should just be displayed, without jumping to a line in it:
               final SearchResultsFileNodeUserObject searchObject = (SearchResultsFileNodeUserObject)userObject;
               showFileNodeHit( searchObject ); // does all what's needed :
             }
          } // if node != null
       }
     });

    // The mouse listener :
    MouseListener mouseListener = new MouseAdapter()
     {
        public void mouseClicked(MouseEvent e)
        {
          processLeftMouseClick( e.getX(), e.getY() );
        }
     };
    this.addMouseListener( mouseListener );

    EventQueue.invokeLater( new Runnable()
     {
        public void run()
        {
          readyForSpecialUpdates = true;
        }
     });

  } // Constructor



  public String getTreeName() {
    return this.treeName;
  }



 /**
  *  Called when the user leftclicks on a tree element.
  */
  public void processLeftMouseClick( int xMouseCoord, int yMouseCoord )
  {
    if( this.getPathForLocation( xMouseCoord, yMouseCoord ) != null )
     {
       this.setSelectionPath( this.getPathForLocation( xMouseCoord, yMouseCoord ) );
       // If all this worked, we now should get the selectedNode as valid object :
       DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)this.getLastSelectedPathComponent();
       if( selectedNode != null )
        {
            Object userObject = selectedNode.getUserObject();
            if( userObject instanceof SearchResultsUserObject )
             {
               final SearchResultsUserObject searchObject = (SearchResultsUserObject)userObject;
               showSearchHit( searchObject ); // does all what's needed :
             }
            else
            if( userObject instanceof SearchResultsFileNodeUserObject )
             {
               // This is true for results of filename searches, where the file as whole
               // is the subject and should just be displayed, without jumping to a line in it:
               final SearchResultsFileNodeUserObject searchObject = (SearchResultsFileNodeUserObject)userObject;
               showFileNodeHit( searchObject ); // does all what's needed :
             }
        }
     }
  } // popupRequest






 /**
  *  Called when the user selects a search leaf entry.
  *  This method then calls the editor and tells it to display
  *  the associated document and jump to the linenumber stored
  *  in the passed userobject.
  */
  private void showSearchHit( SearchResultsUserObject searchObject )
  {
    final EditableLeafObject leaf = searchObject.getEditableLeafObject();
    final int lineNumber = searchObject.getLineNumber();
    // Call the projectfilestree or the libraries tree.
    // Decouple it from the EDT using aThreadEngine task.
    // The called methods will switch back to the EDT, so its no risk to call
    // them outside the EDT here.                    
    Runnable searchHitSelectorTask = new Runnable()
     {
       public void run()
       {
         // Give Swing some cleanup time:
         try{ Thread.sleep(44); } catch( Exception anythingGoes ){}
         if( leaf instanceof ProjectFilesTreeLeafObject )
          {
            projectFrame.selectProjectFilesTreeNodeFor( leaf.getFilePathName(),lineNumber,0,true );
          }
         if( leaf instanceof LibrariesTreeLeafObject )
          {
            projectFrame.selectLibrariesTreeNodeFor( leaf.getJarFilePath(),leaf.jarFileEntryName(),lineNumber,0 );
          }
       }
     };
    ThreadEngine.getInstance().addRunnable( searchHitSelectorTask, "searchHitSelectorTask");   
  } // showSearchHit



                            

 /**
  *  This is used, when the user clicks a filenode after a filename search,
  *  where the tree has depth one.
  */
  private void showFileNodeHit( SearchResultsFileNodeUserObject searchObject )
  {
    // Call the projectfilestree or the libraries tree :
    if( searchObject.getBelongsToProject() )
     {
       this.projectFrame.selectProjectFilesTreeNodeFor( searchObject.getFilePathName(),-1,-1,false );
     }
    else
     {
       final EditableLeafObject leaf = searchObject.getEditableLeafObject();
       if( leaf != null )
        {
          this.projectFrame.selectLibrariesTreeNodeFor( leaf.getJarFilePath(),
                                                        leaf.jarFileEntryName(),
                                                        -1,-1 );
          // For an editable leaf, we must have:
          // searchObject.getFilePathName() = leaf.getJarFilePath()
          // and
          // searchObject.getFileName() = leaf.jarFileEntryName(),lineNumber );
        }
     }
  } // showFileNodeHit


                                    
                                    
  public void initializeTreeWithSingleNode( final String nodeTitle )
  {
    EventQueue.invokeLater( new Runnable()
     {
       public void run()
       {
         model.initializeModel(nodeTitle);
       }
     });    
  }      
   





 /**
  *  Overwritten method. Additionally updates special components.
  */
  public void updateUI()
  {
    super.updateUI();
    if( this.readyForSpecialUpdates )
     {
       // Only thing to do: Recreate the renderer.
       this.setCellRenderer( new SearchResultsTreeCellRenderer() );
     }
  }






 /**
  *  GC assistance, before this object is decoupled from the application.
  *  It should release reference connections.
  *  Called by the projectframe when it's closed.
  *  Calling method is projectframe.doFinalCleanUp() [ in a ThreadEngine thread ]
  */
  public void terminate()
  {
    this.projectFrame = null;
    this.model.initializeModel(""); // has GC assistance
    this.model = null;
  } // terminate

                               
                               
                               

  
  
 /**
  *   This is called from the SymbolUsageLocationSearch, which passes
  *   its results to this tree.
  */                     
  public void setTreeContentWithObjectSearchResults( final SearchResultsUserObject[] searchResultsUserObjects )
  {   
    this.model.initializeModel("Usage Search Results");
    this.model.initializeTreeWith( searchResultsUserObjects );
    // A small netiquette: If there is only one node, open it automatically:
    DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode)this.model.getRoot();
    if( rootNode != null ) {
      if( rootNode.getChildCount() == 1 ) {
        DefaultMutableTreeNode firstChildNode = (DefaultMutableTreeNode)rootNode.getChildAt(0);
        if( firstChildNode.getChildCount() > 0 ) {
          DefaultMutableTreeNode firstLeaf = (DefaultMutableTreeNode)firstChildNode.getChildAt(0);
          this.expandPath( new TreePath( firstChildNode.getPath() ) );
        }
      }
    }
  } // setTreeContentWithObjectSearchResults

 

                               
                               
                               

} // SearchResultsTree










java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.