[autocomplete] 45/143: AutoCompletions and LanguageSupports can now configure whether to auto-activate the completion window on certain key presses. Java and HTML language supports use this functionality by default, Java activating on '.' and HTML on '<' when not in a tag. JavaLanguageSupport now allows the specifying of "classpath" entries as directories of class files, not just of .jar files.

Benjamin Mesing ben at alioth.debian.org
Sat Oct 19 12:53:15 UTC 2013


This is an automated email from the git hooks/post-receive script.

ben pushed a commit to branch master
in repository autocomplete.

commit a42e9bbb5756aad670637763259a5c275aada139
Author: bobbylight <robert at fifesoft.com>
Date:   Sat Jun 5 16:47:15 2010 +0000

    AutoCompletions and LanguageSupports can now configure whether to auto-activate the completion window on certain key presses.  Java and HTML language supports use this functionality by default, Java activating on '.' and HTML on '<' when not in a tag.
    JavaLanguageSupport now allows the specifying of "classpath" entries as directories of class files, not just of .jar files.
---
 .../ui/autocomplete/AutoCompletePopupWindow.java   |   10 +-
 src/org/fife/ui/autocomplete/AutoCompletion.java   |  184 +++++++++++++++++++-
 .../fife/ui/autocomplete/CompletionProvider.java   |   15 ++
 .../ui/autocomplete/CompletionProviderBase.java    |   50 ++++++
 .../LanguageAwareCompletionProvider.java           |   12 +-
 5 files changed, 260 insertions(+), 11 deletions(-)

diff --git a/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java b/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java
index 13a4a5c..c777891 100644
--- a/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java
+++ b/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java
@@ -83,6 +83,13 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener,
 	private CompletionListModel model;
 
 	/**
+	 * A hack to work around the fact that we clear our completion model (and
+	 * our selection) when hiding the completion window.  This allows us to
+	 * still know what the user selected after the popup is hidden.
+	 */
+	private Completion lastSelection;
+
+	/**
 	 * Optional popup window containing a description of the currently
 	 * selected completion.
 	 */
@@ -289,7 +296,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener,
 	 * @return The selected value.
 	 */
 	public Completion getSelection() {
-		return (Completion)list.getSelectedValue();
+		return isShowing() ? (Completion)list.getSelectedValue():lastSelection;
 	}
 
 
@@ -688,6 +695,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener,
 			// you're getting roughly 2x the necessary Completions in memory
 			// until the Completions are actually passed to this window.
 			if (!visible) { // Do after super.setVisible(false)
+				lastSelection = (Completion)list.getSelectedValue();
 				model.clear();
 			}
 
diff --git a/src/org/fife/ui/autocomplete/AutoCompletion.java b/src/org/fife/ui/autocomplete/AutoCompletion.java
index 1932545..b94899a 100644
--- a/src/org/fife/ui/autocomplete/AutoCompletion.java
+++ b/src/org/fife/ui/autocomplete/AutoCompletion.java
@@ -28,12 +28,16 @@ import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.util.List;
 import javax.swing.*;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.CaretListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
 import javax.swing.text.*;
 
 
 /**
- * Adds autocompletion to a text component.  Provides a popup window with a
- * list of autocomplete choices on a given keystroke, such as Crtrl+Space.<p>
+ * Adds auto-completion to a text component.  Provides a popup window with a
+ * list of auto-complete choices on a given keystroke, such as Crtrl+Space.<p>
  *
  * Depending on the {@link CompletionProvider} installed, the following
  * auto-completion features may be enabled:
@@ -120,13 +124,19 @@ public class AutoCompletion {
 	private boolean showDescWindow;
 
 	/**
-	 * Whether autocomplete is enabled.
+	 * Whether auto-complete is enabled.
 	 */
 	private boolean autoCompleteEnabled;
 
 	/**
+	 * Whether the auto-activation of auto-complete (after a delay, after the
+	 * user types an appropriate character) is enabled.
+	 */
+	private boolean autoActivationEnabled;
+
+	/**
 	 * Whether or not, when there is only a single auto-complete option
-	 * that maches the text at the current text position, that text should
+	 * that matches the text at the current text position, that text should
 	 * be auto-inserted, instead of the completion window displaying.
 	 */
 	private boolean autoCompleteSingleChoices;
@@ -178,6 +188,12 @@ public class AutoCompletion {
 	private TextComponentListener textComponentListener;
 
 	/**
+	 * Listens for events in the text component that cause the popup windows
+	 * to automatically activate.
+	 */
+	private AutoActivationListener autoActivationListener;
+
+	/**
 	 * The key used in the input map for the AutoComplete action.
 	 */
 	private static final String PARAM_TRIGGER_KEY	= "AutoComplete";
@@ -209,9 +225,11 @@ public class AutoCompletion {
 		setTriggerKey(getDefaultTriggerKey());
 		setAutoCompleteEnabled(true);
 		setAutoCompleteSingleChoices(true);
+		setAutoActivationEnabled(false);
 		setShowDescWindow(false);
 		parentWindowListener = new ParentWindowListener();
 		textComponentListener = new TextComponentListener();
+		autoActivationListener = new AutoActivationListener();
 
 		// Automatically update LAF of popup windows on LookAndFeel changes
 		UIManager.addPropertyChangeListener(new PropertyChangeListener() {
@@ -281,8 +299,20 @@ public class AutoCompletion {
 
 
 	/**
-	 * Returns whether, if a single autocomplete choice is available, it should
-	 * be automatically inserted, without displaying the popup menu.
+	 * Returns the delay between when the user types a character and when the
+	 * code completion popup should automatically appear (if applicable).
+	 *
+	 * @return The delay, in milliseconds.
+	 * @see #setAutoActivationDelay(int)
+	 */
+	public int getAutoActivationDelay() {
+		return autoActivationListener.timer.getDelay();
+	}
+
+
+	/**
+	 * Returns whether, if a single auto-complete choice is available, it
+	 * should be automatically inserted, without displaying the popup menu.
 	 *
 	 * @return Whether to autocomplete single choices.
 	 * @see #setAutoCompleteSingleChoices(boolean)
@@ -566,6 +596,10 @@ try {
 		// In case textComponent is already in a window...
 		textComponentListener.hierarchyChanged(null);
 
+		if (isAutoActivationEnabled()) {
+			autoActivationListener.addTo(this.textComponent);
+		}
+
 	}
 
 
@@ -586,9 +620,25 @@ try {
 
 
 	/**
-	 * Returns whether autocompletion is enabled.
+	 * Returns whether auto-activation is enabled (that is, whether the
+	 * completion popup will automatically appear after a delay when the user
+	 * types an appropriate character).  Note that this parameter will be
+	 * ignored if auto-completion is disabled.
 	 *
-	 * @return Whether autocompletion is enabled.
+	 * @return Whether auto-activation is enabled.
+	 * @see #setAutoActivationEnabled(boolean)
+	 * @see #getAutoActivationDelay()
+	 * @see #isAutoCompleteEnabled()
+	 */
+	public boolean isAutoActivationEnabled() {
+		return autoActivationEnabled;
+	}
+
+
+	/**
+	 * Returns whether auto-completion is enabled.
+	 *
+	 * @return Whether auto-completion is enabled.
 	 * @see #setAutoCompleteEnabled(boolean)
 	 */
 	public boolean isAutoCompleteEnabled() {
@@ -706,6 +756,43 @@ try {
 
 
 	/**
+	 * Sets the delay between when the user types a character and when the
+	 * code completion popup should automatically appear (if applicable).
+	 *
+	 * @param ms The delay, in milliseconds.  This should be greater than zero.
+	 * @see #getAutoActivationDelay()
+	 */
+	public void setAutoActivationDelay(int ms) {
+		ms = Math.max(0, ms);
+		autoActivationListener.timer.stop();
+		autoActivationListener.timer.setDelay(ms);
+	}
+
+
+	/**
+	 * Toggles whether auto-activation is enabled.  Note that auto-activation
+	 * also depends on auto-completion itself being enabled.
+	 *
+	 * @param enabled Whether auto-activation is enabled.
+	 * @see #isAutoActivationEnabled()
+	 * @see #setAutoActivationDelay(int)
+	 */
+	public void setAutoActivationEnabled(boolean enabled) {
+		if (enabled!=autoActivationEnabled) {
+			autoActivationEnabled = enabled;
+			if (textComponent!=null) {
+				if (autoActivationEnabled) {
+					autoActivationListener.addTo(textComponent);
+				}
+				else {
+					autoActivationListener.removeFrom(textComponent);
+				}
+			}
+		}
+	}
+
+
+	/**
 	 * Sets whether auto-completion is enabled.
 	 *
 	 * @param enabled Whether auto-completion is enabled.
@@ -892,6 +979,10 @@ try {
 				parentWindowListener.removeFrom(parentWindow);
 			}
 
+			if (isAutoActivationEnabled()) {
+				autoActivationListener.removeFrom(textComponent);
+			}
+
 			textComponent = null;
 			popupWindow = null;
 
@@ -930,6 +1021,81 @@ try {
 
 
 	/**
+	 * Listens for events in the text component to auto-activate the code
+	 * completion popup.
+	 */
+	private class AutoActivationListener extends FocusAdapter
+				implements DocumentListener, CaretListener, ActionListener {
+
+		private Timer timer;
+		private boolean justInserted;
+
+		public AutoActivationListener() {
+			timer = new Timer(200, this);
+			timer.setRepeats(false);
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			doCompletion();
+		}
+
+		public void addTo(JTextComponent tc) {
+			tc.addFocusListener(this);
+			tc.getDocument().addDocumentListener(this);
+			tc.addCaretListener(this);
+		}
+
+		public void caretUpdate(CaretEvent e) {
+			if (justInserted) {
+				justInserted = false;
+			}
+			else {
+				timer.stop();
+			}
+		}
+
+		public void changedUpdate(DocumentEvent e) {
+			 // Ignore
+		}
+
+		public void focusLost(FocusEvent e) {
+			timer.stop();
+			//hideChildWindows(); Other listener will do this
+		}
+
+		public void insertUpdate(DocumentEvent e) {
+			justInserted = false;
+			if (isAutoCompleteEnabled() && isAutoActivationEnabled() &&
+					e.getLength()==1) {
+				if (provider.isAutoActivateOkay(textComponent)) {
+					timer.restart();
+					justInserted = true;
+				}
+				else {
+					timer.stop();
+				}
+			}
+			else {
+				timer.stop();
+			}
+		}
+
+		public void removeFrom(JTextComponent tc) {
+			tc.removeFocusListener(this);
+			tc.getDocument().removeDocumentListener(this);
+			tc.removeCaretListener(this);
+			timer.stop();
+			justInserted = false;
+		}
+
+		public void removeUpdate(DocumentEvent e) {
+			timer.stop();
+		}
+
+	}
+
+
+	/**
 	 * The <code>Action</code> that displays the popup window if
 	 * auto-completion is enabled.
 	 *
@@ -1033,7 +1199,7 @@ try {
 	 * Listens for events from the text component we're installed on.
 	 */
 	private class TextComponentListener extends FocusAdapter
-										implements HierarchyListener {
+				implements HierarchyListener {
 
 		void addTo(JTextComponent tc) {
 			tc.addFocusListener(this);
diff --git a/src/org/fife/ui/autocomplete/CompletionProvider.java b/src/org/fife/ui/autocomplete/CompletionProvider.java
index 7bea05c..67337b4 100644
--- a/src/org/fife/ui/autocomplete/CompletionProvider.java
+++ b/src/org/fife/ui/autocomplete/CompletionProvider.java
@@ -159,6 +159,21 @@ public interface CompletionProvider {
 
 
 	/**
+	 * This method is called if auto-activation is enabled in the parent
+	 * {@link AutoCompletion} after the user types a single character.  This
+	 * provider should check the text at the current caret position of the
+	 * text component, and decide whether auto-activation would be appropriate
+	 * here.  For example, a <code>CompletionProvider</code> for Java might
+	 * want to return <code>true</code> for this method only if the last
+	 * character typed was a '<code>.</code>'.
+	 *
+	 * @param tc The text component.
+	 * @return Whether auto-activation would be appropriate.
+	 */
+	public boolean isAutoActivateOkay(JTextComponent tc);
+
+
+	/**
 	 * Sets the renderer to use when displaying completion choices.
 	 *
 	 * @param r The renderer to use.
diff --git a/src/org/fife/ui/autocomplete/CompletionProviderBase.java b/src/org/fife/ui/autocomplete/CompletionProviderBase.java
index b49b70f..9275755 100644
--- a/src/org/fife/ui/autocomplete/CompletionProviderBase.java
+++ b/src/org/fife/ui/autocomplete/CompletionProviderBase.java
@@ -25,7 +25,10 @@ package org.fife.ui.autocomplete;
 import java.util.Collections;
 import java.util.List;
 import javax.swing.ListCellRenderer;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
 import javax.swing.text.JTextComponent;
+import javax.swing.text.Segment;
 
 
 /**
@@ -65,6 +68,21 @@ public abstract class CompletionProviderBase implements CompletionProvider {
 	 */
 	private String paramListSeparator;
 
+	/**
+	 * Whether auto-activation should occur after letters.
+	 */
+	private boolean autoActivateAfterLetters;
+
+	/**
+	 * Non-letter chars that should cause auto-activation to occur.
+	 */
+	private String autoActivateChars;
+
+	/**
+	 * A segment to use for fast char access.
+	 */
+	private Segment s = new Segment();
+
 	protected static final String EMPTY_STRING = "";
 
 
@@ -143,6 +161,38 @@ public abstract class CompletionProviderBase implements CompletionProvider {
 	/**
 	 * {@inheritDoc}
 	 */
+	public boolean isAutoActivateOkay(JTextComponent tc) {
+		Document doc = tc.getDocument();
+		char ch = 0;
+		try {
+			doc.getText(tc.getCaretPosition(), 1, s);
+			ch = s.first();
+		} catch (BadLocationException ble) { // Never happens
+			ble.printStackTrace();
+		}
+		return (autoActivateAfterLetters && Character.isLetter(ch)) ||
+				(autoActivateChars!=null && autoActivateChars.indexOf(ch)>-1);
+	}
+
+
+	/**
+	 * Sets the characters that auto-activation should occur after.  A Java
+	 * completion provider, for example, might want to set <code>others</code>
+	 * to "<code>.</code>", to allow auto-activation for members of an object.
+	 *
+	 * @param letters Whether auto-activation should occur after any letter.
+	 * @param others A string of (non-letter) chars that auto-activation should
+	 *        occur after.  This may be <code>null</code>.
+	 */
+	public void setAutoActivationRules(boolean letters, String others) {
+		autoActivateAfterLetters = letters;
+		autoActivateChars = others;
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
 	public void setListCellRenderer(ListCellRenderer r) {
 		listCellRenderer = r;
 	}
diff --git a/src/org/fife/ui/autocomplete/LanguageAwareCompletionProvider.java b/src/org/fife/ui/autocomplete/LanguageAwareCompletionProvider.java
index 619dc29..a03cfa6 100644
--- a/src/org/fife/ui/autocomplete/LanguageAwareCompletionProvider.java
+++ b/src/org/fife/ui/autocomplete/LanguageAwareCompletionProvider.java
@@ -131,7 +131,7 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase
 			return EMPTY_STRING;
 		}
 		CompletionProvider provider = getProviderFor(comp);
-		return provider.getAlreadyEnteredText(comp);
+		return provider!=null ? provider.getAlreadyEnteredText(comp) : null;
 	}
 
 
@@ -154,6 +154,7 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase
 				defaultProvider.getCompletionsAt(tc, p);
 	}
 
+
 	/**
 	 * Does the dirty work of creating a list of completions.
 	 *
@@ -319,6 +320,15 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase
 
 
 	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isAutoActivateOkay(JTextComponent tc) {
+		CompletionProvider provider = getProviderFor(tc);
+		return provider!=null ? provider.isAutoActivateOkay(tc) : false;
+	}
+
+
+	/**
 	 * Sets the comment completion provider.
 	 *
 	 * @param provider The provider to use in comments.

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/autocomplete.git



More information about the pkg-java-commits mailing list