delayed TextComponentMatcherEditor

View: New views
1 Messages — Rating Filter:   Alert me  

delayed TextComponentMatcherEditor

by Ted Zlatanov :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I put together a simple solution based on TextComponentMatcherEditor to
add a delay before refiltering.  It uses java.util.Timer and TimerTask
to accomplish this.  On large lists it makes a big difference.

I did not change the TextComponentMatcherEditor constructor
intentionally, this is just a proof of concept with a quick and dirty
implementation.  It's possible that two events will get scheduled on the
Swing EDT in this implementation if the TimerTask finishes but the EDT
task is still queued.  I didn't think that was a big deal, as in the
worst case we refilter() twice, but certainly it could be a concern.

Also I use a JXBusyLabel, which is IMO very important to the user so
they know something is happening.  Obviously this is not a good general
solution but I don't know what is in the GL context.

If delay is zero, this will work like the current TextComponentMatcherEditor.

Let me know if this is useful and if I should work on it some more.

Ted



--- source/ca/odell/glazedlists/swing/TextComponentMatcherEditor.java 2008-04-28 09:28:34.000000000 -0500
+++ /home/tzz/workspace/HeartbeatMonitor2/src/com/jump/monitoring/dashing/DelayedTextComponentMatcherEditor.java 2009-08-20 13:51:22.000000000 -0500
@@ -1,7 +1,6 @@
 /* Glazed Lists                                                 (c) 2003-2006 */

-/* http://publicobject.com/glazedlists/                      publicobject.com,*/

-/*                                                     O'Dell Engineering Ltd.*/

-package ca.odell.glazedlists.swing;

+package com.jump.monitoring.dashing;

+

 

 import ca.odell.glazedlists.TextFilterator;

 import ca.odell.glazedlists.matchers.TextMatcherEditor;

@@ -12,10 +11,15 @@
 import javax.swing.text.BadLocationException;

 import javax.swing.text.Document;

 import javax.swing.text.JTextComponent;

+

+import org.jdesktop.swingx.JXBusyLabel;

+

 import java.awt.event.ActionEvent;

 import java.awt.event.ActionListener;

 import java.beans.PropertyChangeListener;

 import java.beans.PropertyChangeEvent;

+import java.util.TimerTask;

+import java.util.Timer;

 

 /**

  * A MatcherEditor that matches Objects that contain the filter text located

@@ -24,7 +28,7 @@
  * Document changes. This matcher is fully concrete and is expected to be used

  * by Swing applications.

  *

- * <p>The {@link TextComponentMatcherEditor} constructors require that either a

+ * <p>The {@link DelayedTextComponentMatcherEditor} constructors require that either a

  * {@link Document} or a {@link JTextComponent} (from which a {@link Document}

  * is extracted) be specified.

  *

@@ -41,7 +45,7 @@
  *

  * @author James Lemieux

  */

-public class TextComponentMatcherEditor<E> extends TextMatcherEditor<E> {

+public class DelayedTextComponentMatcherEditor<E> extends TextMatcherEditor<E> {

 

     /** the Document that provides the filter values */

     private Document document;

@@ -55,6 +59,13 @@
     /** The listener attached to the given {@link #document}. */

     private final FilterHandler filterHandler = new FilterHandler();

 

+    /** wait this long before refiltering; this default is pretty reasonable */

+    private long delay = 300;

+    

+    /** refiltering timer support */

+    Timer refilterer_timer = null;

+    public static JXBusyLabel busy = new JXBusyLabel();

+

     /**

      * Creates a TextMatcherEditor bound to the {@link Document} backing the

      * given <code>textComponent</code> with the given

@@ -67,7 +78,7 @@
      *      <code>null</code> then all filtered objects are expected to

      *      implement {@link ca.odell.glazedlists.TextFilterable}.

      */

-    public TextComponentMatcherEditor(JTextComponent textComponent, TextFilterator<E> textFilterator) {

+    public DelayedTextComponentMatcherEditor(JTextComponent textComponent, TextFilterator<E> textFilterator) {

         this(textComponent, textFilterator, true);

     }

 

@@ -89,7 +100,7 @@
      * @throws IllegalArgumentException if the <code>textComponent</code>

      *      is not a {@link JTextField} and non-live filtering is specified.

      */

-    public TextComponentMatcherEditor(JTextComponent textComponent, TextFilterator<? super E> textFilterator, boolean live) {

+    public DelayedTextComponentMatcherEditor(JTextComponent textComponent, TextFilterator<? super E> textFilterator, boolean live) {

         this(textComponent, textComponent.getDocument(), textFilterator, live);

     }

 

@@ -104,7 +115,7 @@
      *      <code>null</code> then all filtered objects are expected to

      *      implement {@link ca.odell.glazedlists.TextFilterable}.

      */

-    public TextComponentMatcherEditor(Document document, TextFilterator<? super E> textFilterator) {

+    public DelayedTextComponentMatcherEditor(Document document, TextFilterator<? super E> textFilterator) {

         this(null, document, textFilterator, true);

     }

 

@@ -112,7 +123,7 @@
      * This private constructor implements the actual construction work and thus

      * ensures that all public constructors agree on the construction logic.

      */

-    private TextComponentMatcherEditor(JTextComponent textComponent, Document document, TextFilterator<? super E> textFilterator, boolean live) {

+    private DelayedTextComponentMatcherEditor(JTextComponent textComponent, Document document, TextFilterator<? super E> textFilterator, boolean live) {

         super(textFilterator);

 

         this.textComponent = textComponent;

@@ -213,15 +224,40 @@
         }

     }

 

+    public void schedule_refilter()

+    {

+        if (delay <= 0) refilter();

+        else

+        {

+            busy.setBusy(true);

+            if (null != refilterer_timer) refilterer_timer.cancel();

+            refilterer_timer = new Timer("refilterer", true);

+            refilterer_timer.schedule(new TimerTask()

+            {

+                @Override

+                public void run()

+                {

+                    SwingUtilities.invokeLater(new Runnable()

+                    {

+                        public void run()

+                        {

+                            refilter();

+                            busy.setBusy(false);

+                        }});

+                }

+            }, delay);

+        }

+    }

+

     /**

      * This class responds to any change in the Document by setting the filter

      * text of this TextMatcherEditor to the contents of the Document.

      */

     private class FilterHandler implements DocumentListener, ActionListener, PropertyChangeListener {

-        public void insertUpdate(DocumentEvent e) { refilter(); }

-        public void removeUpdate(DocumentEvent e) { refilter(); }

-        public void changedUpdate(DocumentEvent e) { refilter(); }

-        public void actionPerformed(ActionEvent e) { refilter(); }

+        public void insertUpdate(DocumentEvent e) { schedule_refilter(); }

+        public void removeUpdate(DocumentEvent e) { schedule_refilter(); }

+        public void changedUpdate(DocumentEvent e) { schedule_refilter(); }

+        public void actionPerformed(ActionEvent e) { schedule_refilter(); }

 

         public void propertyChange(PropertyChangeEvent evt) {

             if ("document" == evt.getPropertyName()) {

@@ -233,7 +269,7 @@
                 registerListeners(live);

 

                 // refilter based on the new Document

-                refilter();

+                schedule_refilter();

             }

         }

     }




---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@...
For additional commands, e-mail: dev-help@...