【问题标题】:Highlighting part of ShorthandCompletion in RSyntaxTextArea在 RSyntaxTextArea 中突出显示 ShorthandCompletion 的一部分
【发布时间】:2013-03-18 17:33:51
【问题描述】:

我编写了一个调用 RSyntaxTextArea 和自动完成的代码。当用户输入函数时,该单词将被替换为函数。我想在下面的代码中突出显示“标签”一词,以便用户知道他们必须输入一个名称。

provider.addCompletion(new ShorthandCompletion(provider, "function", "function<Label>","function<Label>"));

代码基本上将函数替换为函数并继续前进,而不是突出显示标签并等待用户输入内容。我该怎么做?

【问题讨论】:

    标签: java syntax-highlighting rsyntaxtextarea


    【解决方案1】:

    您可以使用TemplateCompletion 类代替ShorthandCompletion。不幸的是,这似乎对我不起作用(在 AutoCompleteDemo 示例中尝试过)。

    另一种方法是使用CodeTemplateManager 并扩展CodeTemplate。下面是一个例子(来自CodeTemplateDemo)。

    先扩展AbstractCodeTemplate:

    import java.io.IOException;
    import java.io.ObjectInputStream;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.Caret;
    import javax.swing.text.Element;
    
    import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
    import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
    import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
    
    import org.fife.ui.rsyntaxtextarea.templates.*;
    
    public class ArtemisCodeTemplate extends StaticCodeTemplate {
    
        private static final long serialVersionUID = 1;
    
        /**
         * The code inserted before the caret position.
         */
        private String beforeCaret;
    
        /**
         * The code inserted after the caret position.
         */
        private String afterCaret;
    
        /**
         * Cached value representing whether <code>beforeCaret</code> contains
         * one or more newlines.
         */
        private transient int firstBeforeNewline;
    
        /**
         * Cached value representing whether <code>afterCaret</code> contains
         * one or more newlines.
         */
        private transient int firstAfterNewline;
    
        private static final String EMPTY_STRING        = "";
    
        /**
        * Placeholder for the selected keyword
        */
        private String placeholder;
    
        /**
         * Constructor.  This constructor only exists to support persistance
         * through serialization.
         */
        public ArtemisCodeTemplate() {
        }
    
    
        /**
         * Constructor.
         *
         * @param id The ID of this code template.
         * @param beforeCaret The text to place before the caret.
         * @param afterCaret The text to place after the caret.
         */
        public ArtemisCodeTemplate(String id, String beforeCaret, String placeholder, String afterCaret){
            super(id, beforeCaret, afterCaret);
            setPlaceholder(placeholder);
        }
    
        public String getPlaceholder() {
            return placeholder;
        }
    
        public void setPlaceholder(String text) {
            this.placeholder = text;
        }
    
        private String getAfterTextIndented(String indent) {
            return getTextIndented(getAfterCaretText(), firstAfterNewline, indent);
        }
    
        private String getBeforeTextIndented(String indent) {
            return getTextIndented(getBeforeCaretText(),firstBeforeNewline,indent);
        }
    
        private String getTextIndented(String text,int firstNewline,String indent) {
            if (firstNewline==-1) {
                return text;
            }
            int pos = 0;
            int old = firstNewline+1;
            StringBuffer sb = new StringBuffer(text.substring(0, old));
            sb.append(indent);
            while ((pos=text.indexOf('\n', old))>-1) {
                sb.append(text.substring(old, pos+1));
                sb.append(indent);
                old = pos+1;
            }
            if (old<text.length()) {
                sb.append(text.substring(old));
            }
            return sb.toString();
        }
    
        public void invoke(RSyntaxTextArea textArea) throws BadLocationException {
    
            Caret c = textArea.getCaret();
            int dot = c.getDot();
            int mark = c.getMark();
            int p0 = Math.min(dot, mark);
            int p1 = Math.max(dot, mark);
            RSyntaxDocument doc = (RSyntaxDocument)textArea.getDocument();
            Element map = doc.getDefaultRootElement();
    
            int lineNum = map.getElementIndex(dot);
            Element line = map.getElement(lineNum);
            int start = line.getStartOffset();
            int end = line.getEndOffset()-1; // Why always "-1"?
            String s = textArea.getText(start,end-start);
            int len = s.length();
    
            // endWS is the end of the leading whitespace
            // of the current line.
            int endWS = 0;
            while (endWS<len && RSyntaxUtilities.isWhitespace(s.charAt(endWS))) {
                endWS++;
            }
            s = s.substring(0, endWS);
            p0 -= getID().length();
            String beforeText = getBeforeTextIndented(s);
            String afterText = getAfterTextIndented(s);
            doc.replace(p0,p1-p0, beforeText+ placeholder + afterText, null);
            textArea.setCaretPosition(p0+beforeText.length());
            textArea.moveCaretPosition(p0+beforeText.length() + placeholder.length());
        }
    
        private void readObject(ObjectInputStream in) throws ClassNotFoundException,
                                                    IOException  {
                in.defaultReadObject();
                // "Resetting" before and after text to the same values will replace
                // nulls with empty srings, and set transient "first*Newline" values.
                setBeforeCaretText(this.beforeCaret);
                setAfterCaretText(this.afterCaret);
            }
    
        /**
         * Returns a string representation of this template for debugging
         * purposes.
         *
         * @return A string representation of this template.
         */
        public String toString() {
            return "[ArtemisCodeTemplate: id=" + getID() +
                ", text=" + getBeforeCaretText() + "|" +
                     getPlaceholder() + "|" + getAfterCaretText() + "]";
        }
    
    
    }
    

    然后将其添加到CodeTemplateManager:

      RSyntaxTextArea.setTemplatesEnabled(true);
      CodeTemplateManager ctm = RSyntaxTextArea.getCodeTemplateManager();
      CodeTemplate ct = new ArtemisCodeTemplate("sout", "System.out.println(", "<replaceme>", ");");
      ctm.addTemplate(ct);
    

    如果您输入“sout”并按 ctrl+shift+space,它将扩展为 System.out.println(&lt;replaceme&gt;);,并且 &lt;replaceme&gt; 部分将被选中,因此您可以在上面输入。

    【讨论】:

    • 谢谢你的帮助,现在如果我能找到一种方法来调用它而无需按快捷键。
    猜你喜欢
    • 2010-12-26
    • 1970-01-01
    • 2022-01-04
    • 2021-06-14
    • 2020-02-06
    • 1970-01-01
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多