Author: paperwing
Date: 2012-04-20 13:25:29 -0700 (Fri, 20 Apr 2012)
New Revision: 28908

Modified:
   
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/net/WebApp.java
   
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanel.java
Log:
Can now filter results by substring by entering text into the "filter apps" 
text field

Modified: 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/net/WebApp.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/net/WebApp.java
  2012-04-20 20:05:02 UTC (rev 28907)
+++ 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/net/WebApp.java
  2012-04-20 20:25:29 UTC (rev 28908)
@@ -1,5 +1,10 @@
 package org.cytoscape.app.internal.net;
 
+import java.util.HashSet;
+import java.util.Set;
+
+import org.cytoscape.app.internal.net.WebQuerier.AppTag;
+
 /**
  * This class is intended to be a container for information obtained about an 
app from the app store website.
  */
@@ -26,6 +31,13 @@
        /** The number of downloads recorded for this app */
        private int downloadCount;
        
+       /** The set of tags associated with this app, which can be useful for 
dividing apps into categories by tag */
+       private Set<AppTag> appTags;
+       
+       public WebApp() {
+               appTags = new HashSet<AppTag>();
+       }
+       
        /** 
         * Obtain the app name that is used as a unique identifier on the app 
store website 
         * @return The unique representative name used by the app store website
@@ -75,6 +87,14 @@
        }
        
        /**
+        * Return the set of tags, represented by {@link AppTag} objects, 
associated with this app.
+        * @return The set of tags, represented by {@link AppTag} objects, 
associated with this app.
+        */
+       public Set<AppTag> getAppTags() {
+               return appTags;
+       }
+       
+       /**
         * Obtain the download count for this app that was obtained from the 
app store website
         * @return The download count for this app
         */
@@ -110,8 +130,12 @@
                this.downloadCount = downloadCount;
        }
        
+       public void setAppTags(Set<AppTag> appTags) {
+               this.appTags = appTags;
+       }
+       
        @Override
        public String toString() {
                return fullName;
-       }       
+       }
 }

Modified: 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanel.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanel.java
    2012-04-20 20:05:02 UTC (rev 28907)
+++ 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanel.java
    2012-04-20 20:25:29 UTC (rev 28908)
@@ -8,8 +8,11 @@
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
 import javax.swing.JFileChooser;
@@ -20,6 +23,8 @@
 import javax.swing.UIManager;
 import javax.swing.event.HyperlinkEvent;
 import javax.swing.event.HyperlinkEvent.EventType;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
 import javax.swing.event.HyperlinkListener;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
@@ -44,6 +49,7 @@
 import org.cytoscape.app.internal.manager.App;
 import org.cytoscape.app.internal.manager.AppManager;
 import org.cytoscape.app.internal.manager.AppParser;
+import org.cytoscape.app.internal.net.ResultsFilterer;
 import org.cytoscape.app.internal.net.WebApp;
 import org.cytoscape.app.internal.net.WebQuerier;
 
@@ -58,13 +64,13 @@
        
     private javax.swing.JScrollPane descriptionScrollPane;
     private javax.swing.JTextPane descriptionTextPane;
+    private javax.swing.JTextField filterTextField;
     private javax.swing.JButton installSelectedButton;
     private javax.swing.JButton jButton1;
     private javax.swing.JScrollPane resultsScrollPane;
     private javax.swing.JSplitPane resultsSplitPane;
     private javax.swing.JTree resultsTree;
     private javax.swing.JLabel searchAppsLabel;
-    private javax.swing.JComboBox searchComboBox;
     private javax.swing.JCheckBox showCompatibleCheckBox;
        
        private JFileChooser fileChooser;
@@ -75,15 +81,16 @@
         this.appManager = appManager;
        initComponents();
         
+       addTagInformation();
+        populateTree(appManager.getWebQuerier().getAllApps());
+        
         setupDescriptionListener();
         setupHyperlinkListener();
-        
-        populateTree();
+        setupTextFieldListener();
     }
 
     private void initComponents() {
 
-        searchComboBox = new javax.swing.JComboBox();
         installSelectedButton = new javax.swing.JButton();
         searchAppsLabel = new javax.swing.JLabel();
         resultsSplitPane = new javax.swing.JSplitPane();
@@ -93,9 +100,8 @@
         descriptionTextPane = new javax.swing.JTextPane();
         showCompatibleCheckBox = new javax.swing.JCheckBox();
         jButton1 = new javax.swing.JButton();
-
-        searchComboBox.setEditable(true);
-
+        filterTextField = new javax.swing.JTextField();
+        
         installSelectedButton.setText("Install Selected");
         installSelectedButton.addActionListener(new 
java.awt.event.ActionListener() {
             public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -105,7 +111,7 @@
 
         searchAppsLabel.setText("Filter Apps:");
 
-        resultsSplitPane.setDividerLocation(215);
+        resultsSplitPane.setDividerLocation(245);
 
         javax.swing.tree.DefaultMutableTreeNode treeNode1 = new 
javax.swing.tree.DefaultMutableTreeNode("JTree");
         resultsTree.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
@@ -140,19 +146,20 @@
                 .addContainerGap()
                 
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                     .add(layout.createSequentialGroup()
+                        .add(resultsSplitPane, 
org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE)
+                        .addContainerGap())
+                    .add(layout.createSequentialGroup()
                         
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                             .add(layout.createSequentialGroup()
+                                .add(filterTextField, 
org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 269, 
org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                                
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
+                                .add(showCompatibleCheckBox))
+                            .add(layout.createSequentialGroup()
                                 .add(installSelectedButton)
                                 
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                 .add(jButton1))
-                            .add(searchAppsLabel)
-                            .add(layout.createSequentialGroup()
-                                .add(searchComboBox, 
org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 269, 
org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
-                                
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
-                                .add(showCompatibleCheckBox)))
-                        .add(0, 55, Short.MAX_VALUE))
-                    .add(resultsSplitPane))
-                .addContainerGap())
+                            .add(searchAppsLabel))
+                        .add(0, 0, Short.MAX_VALUE))))
         );
         layout.setVerticalGroup(
             layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
@@ -161,7 +168,7 @@
                 .add(searchAppsLabel)
                 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                 
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
-                    .add(searchComboBox, 
org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 28, 
org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                    .add(filterTextField, 
org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 
org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 
org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                     .add(showCompatibleCheckBox))
                 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                 .add(resultsSplitPane, 
org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 321, Short.MAX_VALUE)
@@ -177,6 +184,48 @@
         // TODO add your handling code here:
     }                                            
 
+    private void setupTextFieldListener() {
+        filterTextField.getDocument().addDocumentListener(new 
DocumentListener() {
+                       
+                       @Override
+                       public void removeUpdate(DocumentEvent arg0) {
+                               // TODO Auto-generated method stub
+                               filterResults();
+                       }
+                       
+                       @Override
+                       public void insertUpdate(DocumentEvent arg0) {
+                               // TODO Auto-generated method stub
+                               filterResults();
+                       }
+                       
+                       @Override
+                       public void changedUpdate(DocumentEvent arg0) {
+                               // TODO Auto-generated method stub
+                               filterResults();
+                       }
+               });
+    }
+    
+    private void filterResults() {
+        String text = filterTextField.getText();
+       
+       Set<WebApp> allApps = appManager.getWebQuerier().getAllApps();
+       
+       if (text != null && text.length() > 0) {
+               ResultsFilterer filterer = new ResultsFilterer();
+               
+               populateTree(filterer.findMatches(text, allApps));
+               
+       } else {
+               populateTree(allApps);
+       }       
+    }
+    
+    private void searchComboBoxPropertyChange(java.beans.PropertyChangeEvent 
evt) {
+
+    }
+    
     private void 
installSelectedButtonActionPerformed(java.awt.event.ActionEvent evt) {          
                                            
         // TODO add your handling code here:
     }                                                     
@@ -192,7 +241,7 @@
     /**
      * Populate the current tree of results with the available apps from the 
web store.
      */
-    private void populateTree() {
+    private void populateTreeOld() {
        WebQuerier webQuerier = appManager.getWebQuerier();
        
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Available 
Apps (" + webQuerier.getAllApps().size() + ")");
@@ -217,12 +266,65 @@
        resultsTree.setModel(new DefaultTreeModel(root));
     }
     
+    // Populate the tree using a given set of WebApp objects.
+    private void populateTree(Set<WebApp> webApps) {
+       WebQuerier webQuerier = appManager.getWebQuerier();
+       
+       // Assume given apps have been labelled with tags
+       // Above assumption should be valid once web store is updated to 
provide tag information when requesting all apps
+       
+       DefaultMutableTreeNode root = new DefaultMutableTreeNode("Matches (" + 
webApps.size() + ")");
+       
+       // Obtain available tags
+       Set<WebQuerier.AppTag> availableTags = webQuerier.getAllTags();
+       
+       // Construct a dictionary that maps each tag to a set containing all 
the apps associated with that tag
+       // in order to produce the tree
+       Map<WebQuerier.AppTag, Set<WebApp>> dividedApps = new 
HashMap<WebQuerier.AppTag, Set<WebApp>>();
+       for (WebQuerier.AppTag appTag : availableTags) {
+               dividedApps.put(appTag, new HashSet<WebApp>());
+       }
+       
+       for (WebApp webApp : webApps) {
+               // Add the app to the appropriate set(s) in the dictionary
+               for (WebQuerier.AppTag appTag : webApp.getAppTags()) {
+                       dividedApps.get(appTag).add(webApp);
+               }
+       }
+       
+       for (Entry<WebQuerier.AppTag, Set<WebApp>> entry : 
dividedApps.entrySet()) {
+               WebQuerier.AppTag appTag = entry.getKey();
+               Set<WebApp> associatedApps = entry.getValue();
+               
+               if (associatedApps.size() > 0) {
+                       DefaultMutableTreeNode tagNode = new 
DefaultMutableTreeNode(appTag.getFullName() + " (" + associatedApps.size() + 
")");
+                       
+                       for (WebApp webApp : associatedApps) {
+                               tagNode.add(new DefaultMutableTreeNode(webApp));
+                       }
+                       
+                       root.add(tagNode);
+               }
+       }
+       
+       resultsTree.setModel(new DefaultTreeModel(root));
+       
+       for (int index = resultsTree.getRowCount() - 1; index >= 0; index--) {
+               resultsTree.expandRow(index);
+       }
+    }
+    
     /**
      * Obtain the set of {@link WebApp} objects corresponding to currently 
selected entries in the tree of apps
      * @return A set of {@link WebApp} objects corresponding to selected apps 
in the tree
      */
     private Set<WebApp> getSelectedApps() {
        TreePath[] selectedPaths = resultsTree.getSelectionPaths();
+       if (selectedPaths == null) {
+               // Return an empty set if no selections were found
+               return new HashSet<WebApp>();
+       }
+       
        Set<WebApp> selectedApps = new HashSet<WebApp>();
        
        for (int index = 0; index < selectedPaths.length; index++) {
@@ -277,6 +379,26 @@
                });
     }
     
+    // Adds tag information to the set of available apps
+    private void addTagInformation() {
+       WebQuerier webQuerier = appManager.getWebQuerier();
+       Set<WebApp> webApps = webQuerier.getAllApps();
+       
+       // Obtain available tags
+       Set<WebQuerier.AppTag> availableTags = webQuerier.getAllTags();
+       
+       for (WebQuerier.AppTag appTag : availableTags) {
+
+               // Obtain apps for the current tag
+               Set<WebApp> tagApps = webQuerier.getAppsByTag(appTag.getName());
+               
+               // Assume the set of apps returned is a subset of all available 
apps
+               for (WebApp tagApp : tagApps) {
+                       tagApp.getAppTags().add(appTag);
+               }
+       }
+    }
+    
     private void updateDescriptionBox() {
        Set<WebApp> selectedApps = getSelectedApps();
        int numSelected = selectedApps.size();

-- 
You received this message because you are subscribed to the Google Groups 
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/cytoscape-cvs?hl=en.

Reply via email to