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 <[email protected]> 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 _______________________________________________ pkg-java-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

