[MOBY-guts] biomoby commit

Paul Gordon gordonp at dev.open-bio.org
Thu Feb 3 21:45:38 UTC 2011


gordonp
Thu Feb  3 16:45:38 EST 2011
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui
In directory dev.open-bio.org:/tmp/cvs-serv20116/src/main/ca/ucalgary/seahawk/gui

Modified Files:
	FilterSearchWidget.java 
Log Message:
Several fixes including ability to not have highlight-as-you-type (can cause freezing), suspending matching when regex has trailing pipe, and search input field that responds to user preference for font size (accessibility)
moby-live/Java/src/main/ca/ucalgary/seahawk/gui FilterSearchWidget.java,1.7,1.8
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/FilterSearchWidget.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/FilterSearchWidget.java	2010/06/15 22:20:51	1.7
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/gui/FilterSearchWidget.java	2011/02/03 21:45:38	1.8
@@ -4,6 +4,8 @@
 
 import java.awt.Color;
 import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.geom.AffineTransform;
 import java.awt.event.*;
 import java.net.URL;
 import java.util.concurrent.*;
@@ -15,12 +17,13 @@
  * Displays an editable SearchFilter within a MobyContentPane.
  */
 
-public class FilterSearchWidget extends JPanel implements ActionListener, DocumentListener{
+public class FilterSearchWidget extends JPanel implements ActionListener, DocumentListener, FontSizeChangeListener{
 
     private FilterSearch currentFilterSearch;
     private JLabel closeIcon;
     private JToggleButton caseButton;
     private JButton inverseButton; // decides whether filter is "if" or "unless"
+    private JButton applyButton; // used when filter is in "non-interactive" mode
     private JTextField searchField;
     private JComboBox docPartOptions;
     private MobyContentPane contentPane;
@@ -28,6 +31,7 @@
 
     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 APPLY_TEXT = "<html><i>Apply Filter</i></html>";
     private static final String IF_TEXT = "<html><u>if</u></html>";
     private static final String UNLESS_TEXT = "<html><u>unless</u></html>";
     private static final String CASE_INSENSITIVE_MSG = "<html>The filter is case insensitive,<br>click to make case sensitive</html>";
@@ -80,20 +84,41 @@
 	add(new JLabel("Show data "));
 	add(inverseButton);
 	add(Box.createRigidArea(new Dimension(5,0)));
+
 	searchField = new JTextField(25);
+	setSearchFieldFontSize(SeahawkOptions.getFontSizeAsDouble());
 	searchField.setToolTipText("A literal string, or a regular expression");
 	searchField.getDocument().addDocumentListener(this);
 	add(searchField);
+
 	add(Box.createRigidArea(new Dimension(5,0)));
 	add(new JLabel("in"));
 	add(Box.createRigidArea(new Dimension(5,0)));
 	docPartOptions = new JComboBox();
 	docPartOptions.addActionListener(this);
 	add(docPartOptions);
+	add(Box.createRigidArea(new Dimension(5,0)));
+
+	if(!SeahawkOptions.isFilterInteractive()){
+	    // Normally we update any time the user types a letter.
+	    // On some systems this freezes the system randomly, so there is the option to 
+	    // type, then press a button to apply the filter...
+	    applyButton = new JButton(APPLY_TEXT);
+	    applyButton.setEnabled(true);
+	    applyButton.addActionListener(this);
+	    add(applyButton);
+	}
 	add(Box.createHorizontalGlue());
 	setFilter(null);
     }
 
+    private void setSearchFieldFontSize(double scale){ // Proportion of font compared to default
+	AffineTransform scaler = new AffineTransform();
+	scaler.setToScale(scale, scale);
+	Font preferredFont = (new JTextField(1)).getFont().deriveFont(scaler);
+	searchField.setFont(preferredFont);
+    }
+
     /**
       * The filter to display as editable right now.
       */
@@ -104,6 +129,7 @@
 	    inverseButton.setEnabled(false);
 	    searchField.setEnabled(false);
 	    docPartOptions.setEnabled(false);
+	    if(applyButton != null){applyButton.setEnabled(false);}
 	    return;
 	}
 
@@ -119,6 +145,9 @@
 	docPartOptions.setEnabled(true);
 	docPartOptions.setModel(new DefaultComboBoxModel(fs.getXPathOptions()));
 	docPartOptions.setSelectedItem(fs.getSelectedXPath());
+
+	if(applyButton != null){applyButton.setEnabled(true);}
+
 	currentFilterSearch = fs;  // done in this order so no feedback as DocumentEvents while setting fields programmatically
     }
 
@@ -153,6 +182,14 @@
 	    contentPane.applyFilter(true);
 	    return;
         }
+	else if(e.getSource() == applyButton){
+	    StringBuffer sb = currentFilterSearch.getFilterRegex();
+	    synchronized(searchField){
+		sb.replace(0, sb.length(), searchField.getText());
+	    }
+	    applyFilterWhenSuitable();
+	    return;
+	}
 	else if(currentFilterSearch == null || e.getSource() != docPartOptions){
 	    return;
 	}
@@ -164,7 +201,7 @@
      * Called when the regex has been changed by the user
      */
     public void changedUpdate(DocumentEvent e){
-	if(currentFilterSearch == null){
+	if(currentFilterSearch == null || !SeahawkOptions.isFilterInteractive() || danglingPipe()){
 	    return;
 	}
 	StringBuffer sb = currentFilterSearch.getFilterRegex();
@@ -175,7 +212,7 @@
     }
 
     public void insertUpdate(DocumentEvent e){
-	if(currentFilterSearch == null){
+	if(currentFilterSearch == null || !SeahawkOptions.isFilterInteractive() || danglingPipe()){
 	    return;
 	}
 	StringBuffer sb = currentFilterSearch.getFilterRegex();
@@ -186,7 +223,7 @@
     }
 
     public void removeUpdate(DocumentEvent e){
-	if(currentFilterSearch == null){
+	if(currentFilterSearch == null || !SeahawkOptions.isFilterInteractive() || danglingPipe()){
 	    return;
 	}
 	StringBuffer sb = currentFilterSearch.getFilterRegex();
@@ -196,6 +233,22 @@
 	applyFilterWhenSuitable();
     }
 
+    // Check if the user is typing a regex and current has a | operator at the end.
+    // Don't update the matches at this point because of course the empty right side of the regex
+    // will match between every character, causing hardship for matching and highlight update
+    // on some machines.
+    private boolean danglingPipe(){
+	String currentText = searchField.getText();
+	// Running a regex on a regex to see if there is a trailing unescaped '|'...trippy
+	if(currentText.matches("(^|.*[^\\\\])(\\\\\\\\)*\\|")){
+	    searchField.setBackground(Color.YELLOW);
+	    return true;
+	}
+	else{
+	    return false;
+	}
+    }
+
     // 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(){
@@ -211,7 +264,7 @@
 			}
 			catch(Exception e){
 			    logger.log(Level.WARNING, 
-				       "Delay less than 400ms on search input due to interrupt", 
+				       "Delay less than 500ms on search input due to interrupt", 
 				       e);
 			}
 			synchronized(sf){
@@ -245,6 +298,12 @@
 	// else, it's going to be updated soon anyway with the latest string buffer...just return
     }
 
+    public void fontSizeChanged(String size){
+	// Data coming in is 110%, etc., convert to decimal scale required by 
+	double scale =  Double.parseDouble(size.substring(0, size.length()-1))/100.0; // lop off % sign, convert to ratio
+	setSearchFieldFontSize(scale);
+    }
+
     class Closer extends MouseAdapter{
 	boolean active = false;
 	private FilterSearchWidget widget;




More information about the MOBY-guts mailing list