[MOBY-guts] biomoby commit

Paul Gordon gordonp at dev.open-bio.org
Mon Apr 26 17:50:34 UTC 2010


gordonp
Mon Apr 26 13:50:33 EDT 2010
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui
In directory dev.open-bio.org:/tmp/cvs-serv29151/src/main/ca/ucalgary/seahawk/gui

Modified Files:
	FilterSearchWidget.java 
Log Message:
Kung foo with semaphores to let search filter only apply every 600ms or so when typing a longer string
moby-live/Java/src/main/ca/ucalgary/seahawk/gui FilterSearchWidget.java,1.4,1.5
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/FilterSearchWidget.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/FilterSearchWidget.java	2010/04/26 16:28:11	1.4
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/FilterSearchWidget.java	2010/04/26 17:50:33	1.5
@@ -5,6 +5,7 @@
 import java.awt.Dimension;
 import java.awt.event.*;
 import java.net.URL;
+import java.util.concurrent.*;
 import java.util.logging.*;
 import javax.swing.*;
 import javax.swing.event.*; 
@@ -22,6 +23,8 @@
     private JTextField searchField;
     private JComboBox docPartOptions;
     private MobyContentPane contentPane;
+    private Semaphore semaphore; // for search update delays in multikeystroke
+
     public static final String CASE_SENSITIVE_ICON_RESOURCE = "ca/ucalgary/seahawk/resources/images/case_sensitive.png";
     public static final String CASE_INSENSITIVE_ICON_RESOURCE = "ca/ucalgary/seahawk/resources/images/case_insensitive.png";
     private static final String IF_TEXT = "<html><u>if</u></html>";
@@ -48,6 +51,8 @@
 	closeIcon.addMouseListener(new Closer(this));
 	closeIcon.setToolTipText("Remove filter criteria");
 
+	semaphore = new Semaphore(1);  //1 search update for a given timeframe
+
 	Dimension buttonSize = new Dimension(24,24);
 	caseButton = new JToggleButton(new ImageIcon(cl.getResource(CASE_SENSITIVE_ICON_RESOURCE)));
 	caseButton.setDisabledIcon(new ImageIcon(cl.getResource(CASE_INSENSITIVE_ICON_RESOURCE)));
@@ -162,8 +167,10 @@
 	    return;
 	}
 	StringBuffer sb = currentFilterSearch.getFilterRegex();
-	sb.replace(0, sb.length(), searchField.getText());
-	contentPane.applyFilter(true);
+	synchronized(searchField){
+	    sb.replace(0, sb.length(), searchField.getText());
+	}
+	applyFilterWhenSuitable();
     }
 
     public void insertUpdate(DocumentEvent e){
@@ -171,8 +178,10 @@
 	    return;
 	}
 	StringBuffer sb = currentFilterSearch.getFilterRegex();
-	sb.replace(0, sb.length(), searchField.getText());
-	contentPane.applyFilter(true);
+	synchronized(searchField){
+	    sb.replace(0, sb.length(), searchField.getText());
+	}
+	applyFilterWhenSuitable();
     }
 
     public void removeUpdate(DocumentEvent e){
@@ -180,10 +189,53 @@
 	    return;
 	}
 	StringBuffer sb = currentFilterSearch.getFilterRegex();
-	sb.replace(0, sb.length(), searchField.getText());
-	contentPane.applyFilter(true);
+	synchronized(searchField){
+	    sb.replace(0, sb.length(), searchField.getText());
+	}
+	applyFilterWhenSuitable();
     }
 
+    // Waits 600 milliseconds to see if the user is typing a phrase, rather than 
+    // filtering for each letter added, which can be slow
+    private void applyFilterWhenSuitable(){
+	try{
+	    final Semaphore sem = semaphore;
+	    final MobyContentPane pane = contentPane;
+	    final JTextField sf = searchField;
+	    if(sem.tryAcquire()){
+		new Thread(){
+		    public void run(){
+			try{
+			    Thread.sleep(500);
+			}
+			catch(Exception e){
+			    logger.log(Level.WARNING, 
+				       "Delay less than 400ms on search input due to interrupt", 
+				       e);
+			}
+			synchronized(sf){
+			    try{
+				// Give 100ms for other threads past sb.replace() in DocumentListener callbacks to 
+				// try to acquire a permit, avoiding redundant applyFiolter call
+				Thread.sleep(100);
+			    }
+			    catch(Exception e){
+				logger.log(Level.WARNING, 
+					   "Delay less than 100ms on search input due to interrupt", 
+					   e);
+			    }
+			    pane.applyFilter(true);	
+			    sem.release();
+			}
+		    }
+		}.start();
+	    }
+	}catch(Exception e){
+	    logger.log(Level.SEVERE, "Search result updater was interrupted while waiting for a semaphore," +
+		                     "GUI may not reflect search field", e);
+	}
+	// else, it's going to be updated soon anyway with the latest string buffer...just return
+    }
 
     class Closer extends MouseAdapter{
 	boolean active = false;




More information about the MOBY-guts mailing list