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.