java - 在 RSyntaxTextArea 中高亮部分 ShorthandCompletion

标签 java syntax-highlighting rsyntaxtextarea

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

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

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

最佳答案

有一个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(<replaceme>);<replaceme>部分将被选中,以便您可以在其上键入。

关于java - 在 RSyntaxTextArea 中高亮部分 ShorthandCompletion,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15483194/

相关文章:

python - 区分 Textmate 中 Python 字符串与 Docstrings 的语法颜色?

java - RSyntaxTextArea 不显示行号

javascript - 使用 AngularJS 和 Highlight.js 进行动态语法高亮

python - xlsxwriter Pandas 框架: to highlight rows if there are blank cells within a column

java - Javafx 中有 RSyntaxTextArea 的替代品吗?

java - JMenuBar 未从 RSyntaxTextArea 接收按键组合

java - 如何在spring boot中从restful Controller 返回一个html页面?

java - 将变量值从循环内部传递到外部

java - 编译错误: “Not a statement” - Equation inside a for loop

java - 我需要在另一个 Activity 中复制我的数组列表