原文地址:http://blog.youkuaiyun.com/lyq19870515/article/details/19904913
最近在开发EclipsePlug, 开发一个SQL代码编辑器, 所以就写一篇文章. 希望对大家有帮助. 让大家少走弯路. (代码可能不能运行, 但关键部分都有). 因为代码比较多. 所以可能不能一次性上传完成. 毕竟我还要修改, 空话不多说. 直接上代码.
首先是Editor类, 我取名为SQLEditor, 继承TextEditor:
- package com.test.editors;
- import org.eclipse.core.runtime.IProgressMonitor;
- import org.eclipse.jface.text.BadLocationException;
- import org.eclipse.jface.text.IDocument;
- import org.eclipse.jface.text.IRegion;
- import org.eclipse.jface.text.formatter.IContentFormatter;
- import org.eclipse.swt.SWT;
- import org.eclipse.swt.graphics.Font;
- import org.eclipse.swt.graphics.FontData;
- import org.eclipse.swt.graphics.Point;
- import org.eclipse.swt.widgets.Composite;
- import org.eclipse.ui.IViewPart;
- import org.eclipse.ui.PartInitException;
- import org.eclipse.ui.PlatformUI;
- import org.eclipse.ui.editors.text.TextEditor;
- import com.zdk.platform.studio.dbassistant.codeassistent.ColorManager;
- import com.zdk.platform.studio.dbassistant.codeassistent.SQLConfiguration;
- import com.zdk.platform.studio.dbassistant.codeassistent.SQLDocumentProvider;
- /**
- * 类说明: SQL语句编辑器.
- * @author xiao天__
- *
- */
- public class SQLEditor extends TextEditor {
- /**editorID**/
- public static String ID = "com.test.SQLEditor";
- private ColorManager colorManager;
- private SQLConfiguration configuration;
- public SQLEditor() {
- super();
- configuration = new SQLConfiguration();
- setSourceViewerConfiguration(configuration);
- setDocumentProvider(new SQLDocumentProvider());
- }
- /**
- * 方法说明: 设置字体.
- */
- public void initFont() {
- FontData fontData = new FontData("Consolas", 11, SWT.NORMAL);
- Font font = new Font(getEditorSite().getShell().getDisplay(), fontData);
- this.getSourceViewer().getTextWidget().setFont(font);
- }
- public void dispose() {
- if(colorManager != null) {
- colorManager.dispose();
- }
- super.dispose();
- }
- @Override
- public void createPartControl(Composite parent) {
- super.createPartControl(parent);
- initFont();
- }
- }
如果大家使用的是有文件的方式. 就可以直接配置Plug-in.xml文件方式来打开SQLEditor, 而小天__使用的是不需要文件的方式来打开SQLEditor, 主要是项目需要, 所以这里给大家写两种方式:
方式一:
Plug-in.xml:
- <plugin>
- <extension
- point="org.eclipse.ui.editors">
- <editor
- name="SQL编辑器"
- extensions="xml"
- icon="icons/sample.gif"
- contributorClass="org.eclipse.ui.texteditor.BasicTextEditorActionContributor"
- class="com.test.SQLEditor"
- id="com.test.SQLEditor">
- </editor>
- </extension>
- </plugin>
方式二:
Plug-in.xml的配置都是一样的, 因为没有文件. 所以我们必须要构建一个Input对象:
SQLEditorInput:
- package com.test.editors;
- import java.io.ByteArrayInputStream;
- import java.io.InputStream;
- import org.eclipse.core.resources.IStorage;
- import org.eclipse.core.runtime.CoreException;
- import org.eclipse.core.runtime.IPath;
- import org.eclipse.jface.resource.ImageDescriptor;
- import org.eclipse.ui.IPersistableElement;
- import org.eclipse.ui.IStorageEditorInput;
- import org.eclipse.ui.IViewPart;
- import org.eclipse.ui.PartInitException;
- import org.eclipse.ui.PlatformUI;
- public class SQLEditorInput implements IStorageEditorInput {
- /**显示名称**/
- private String name;
- /**正文**/
- private String content = "";
- /**存储器**/
- public IStorage storage;
- public SQLEditorInput(String name) {
- this.name = name;
- storage = new IStorage() {
- @Override
- public Object getAdapter(Class adapter) {
- return null;
- }
- @Override
- public boolean isReadOnly() {
- return isReadOnly;
- }
- @Override
- public String getName() {
- return SQLEditorInput.this.name;
- }
- @Override
- public IPath getFullPath() {
- return null;
- }
- @Override
- public InputStream getContents() throws CoreException {
- return new ByteArrayInputStream(content.getBytes());
- }
- };
- }
- public SQLEditorInput(String name, IStorage is) {
- this.name = name;
- this.storage = is;
- }
- @Override
- public boolean exists() {
- return true;
- }
- @Override
- public ImageDescriptor getImageDescriptor() {
- return null;
- }
- @Override
- public String getName() {
- return name;
- }
- @Override
- public IPersistableElement getPersistable() {
- return null;
- }
- @Override
- public String getToolTipText() {
- return "SQL编辑器";
- }
- @Override
- public Object getAdapter(Class adapter) {
- return null;
- }
- @Override
- public IStorage getStorage() throws CoreException {
- return storage;
- }
- @Override
- public boolean equals(Object obj) {
- if(obj instanceof SQLEditorInput){
- SQLEditorInput newDbEditorInput = (SQLEditorInput)obj;
- if(this.name.equals(newDbEditorInput.getName())) {
- return true;
- }
- }
- return false;
- }
- }
打开编辑器方法:
这个方法可以写在工具栏的事件里. 右键菜单里. 这个就看需求了.
- public void openView() {
- SQLEditorInput input = new SQLEditorInput("新建查询");
- try {
- page.openEditor(input, "com.test.SQLEditor");
- } catch (PartInitException e) {
- e.printStackTrace();
- }
- }
SQLConfiguration类:
- package com.zdk.platform.studio.dbassistant.codeassistent;
- import org.eclipse.jface.text.IDocument;
- import org.eclipse.jface.text.contentassist.ContentAssistant;
- import org.eclipse.jface.text.contentassist.IContentAssistant;
- import org.eclipse.jface.text.formatter.ContentFormatter;
- import org.eclipse.jface.text.formatter.IContentFormatter;
- import org.eclipse.jface.text.presentation.IPresentationReconciler;
- import org.eclipse.jface.text.presentation.PresentationReconciler;
- import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
- import org.eclipse.jface.text.source.ISourceViewer;
- import org.eclipse.jface.text.source.SourceViewerConfiguration;
- import com.zdk.platform.studio.dbassistant.codeassistent.assistent.SQLContentAssistent;
- public class SQLConfiguration extends SourceViewerConfiguration {
- private SQLContentAssistent assistent;
- public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
- PresentationReconciler reconciler = new PresentationReconciler();
- DefaultDamagerRepairer dr = new DefaultDamagerRepairer(new SQLPartitionScanner());
- reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
- reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
- return reconciler;
- }
- @Override
- public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
- ContentFormatter formatter = new ContentFormatter();
- formatter.setFormattingStrategy(new SQLFormattingStrategy(), IDocument.DEFAULT_CONTENT_TYPE);
- formatter.enablePartitionAwareFormatting(true);
- return formatter;
- }
- /**
- * 设置自动提示.
- */
- @Override
- public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
- ContentAssistant contentAssistent = new ContentAssistant();
- assistent = new SQLContentAssistent();
- contentAssistent.setContentAssistProcessor(assistent, IDocument.DEFAULT_CONTENT_TYPE);
- contentAssistent.enableAutoActivation(true);
- contentAssistent.setAutoActivationDelay(200);
- return contentAssistent;
- }
- public DBConfig getDbConfig() {
- return dbConfig;
- }
- }
SQLDocumentProvider类(说实话这个类.小天__都不清楚有什么用):
- package com.zdk.platform.studio.dbassistant.codeassistent;
- import org.eclipse.core.runtime.CoreException;
- import org.eclipse.jface.text.IDocument;
- import org.eclipse.jface.text.IDocumentPartitioner;
- import org.eclipse.jface.text.rules.FastPartitioner;
- import org.eclipse.ui.editors.text.FileDocumentProvider;
- public class SQLDocumentProvider extends FileDocumentProvider {
- protected IDocument createDocument(Object element) throws CoreException {
- IDocument document = super.createDocument(element);
- if (document != null) {
- IDocumentPartitioner partitioner =
- new FastPartitioner(
- new SQLPartitionScanner(),
- new String[] { });
- partitioner.connect(document);
- document.setDocumentPartitioner(partitioner);
- }
- return document;
- }
- }
代码高亮部分:
ColorManager类:
- package com.zdk.platform.studio.dbassistant.codeassistent;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- import org.eclipse.swt.graphics.Color;
- import org.eclipse.swt.graphics.RGB;
- import org.eclipse.swt.widgets.Display;
- /**
- * 类说明: 颜色管理类.
- * @author 小天__
- *
- */
- public class ColorManager {
- /**注释颜色**/
- public static final RGB COLOR_COMMENT = new RGB(0, 128, 0);
- /**关键字颜色**/
- public static final RGB COLOR_KEYWORD = new RGB(128, 0, 0);
- /**普通文本颜色**/
- public static final RGB COLOR_TEXT = new RGB(0, 0, 0);
- protected static Map fColorTable = new HashMap(10);
- public void dispose() {
- Iterator e = fColorTable.values().iterator();
- while (e.hasNext())
- ((Color) e.next()).dispose();
- }
- public static Color getColor(RGB rgb) {
- Color color = (Color) fColorTable.get(rgb);
- if (color == null) {
- color = new Color(Display.getCurrent(), rgb);
- fColorTable.put(rgb, color);
- }
- return color;
- }
- }
SQLPartitionScanner:
- package com.test.codeassistent;
- import org.eclipse.jface.text.TextAttribute;
- import org.eclipse.jface.text.rules.EndOfLineRule;
- import org.eclipse.jface.text.rules.IPredicateRule;
- import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
- import org.eclipse.jface.text.rules.SingleLineRule;
- import org.eclipse.jface.text.rules.Token;
- import com.test.rule.KeyWordDetector;
- import com.test.rule.KeyWordRule;
- public class SQLPartitionScanner extends RuleBasedPartitionScanner {
- private TextAttribute keywordAttr = new TextAttribute(ColorManager.getColor(ColorManager.COLOR_KEYWORD));
- public SQLPartitionScanner() {
- IPredicateRule[] rules = new IPredicateRule[1];
- rules[0] = new KeyWordRule(new KeyWordDetector(), new Token(keywordAttr));
- setPredicateRules(rules);
- }
- }
KeyWordRule:
- package com.zdk.platform.studio.dbassistant.codeassistent.rule;
- import org.eclipse.jface.text.rules.ICharacterScanner;
- import org.eclipse.jface.text.rules.IPredicateRule;
- import org.eclipse.jface.text.rules.IToken;
- import org.eclipse.jface.text.rules.IWordDetector;
- import org.eclipse.jface.text.rules.Token;
- import org.eclipse.jface.text.rules.WordRule;
- import com.test.SQLPartitionScanner;
- public class KeyWordRule extends WordRule implements IPredicateRule {
- private StringBuffer fBuffer= new StringBuffer();
- private boolean fIgnoreCase= false;
- /**关键字**/
- public String keywords = "insert,update,delete,select";
- public KeyWordRule(IWordDetector detector, IToken defaultToken) {
- super(detector, new Token(SQLPartitionScanner.textAttr));
- //增加关键字
- String[] keywordArray = keywords.split(",");
- for (int i = 0; i < keywordArray.length; i++) {
- String keywrod = keywordArray[i];
- addWord(keywrod, defaultToken);
- }
- }
- public IToken evaluate(ICharacterScanner scanner) {
- int c= scanner.read();
- if (c != ICharacterScanner.EOF && fDetector.isWordStart((char) c)) {
- if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {
- fBuffer.setLength(0);
- do {
- fBuffer.append((char) c);
- c= scanner.read();
- } while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c));
- scanner.unread();
- String buffer= fBuffer.toString();
- if (fIgnoreCase) {
- buffer = buffer.toLowerCase();
- }
- IToken token= (IToken)fWords.get(buffer);
- if (token != null) {
- return token;
- }
- if (fDefaultToken.isUndefined()) {
- unreadBuffer(scanner);
- }
- return fDefaultToken;
- }
- }
- scanner.unread();
- return Token.UNDEFINED;
- }
- @Override
- public IToken getSuccessToken() {
- return Token.UNDEFINED;
- }
- @Override
- public IToken evaluate(ICharacterScanner scanner, boolean resume) {
- return this.fDefaultToken;
- }
- }
KeyWordDetector:
- package com.zdk.platform.studio.dbassistant.codeassistent.rule;
- /*******************************************************************************
- * Copyright (c) 2000 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * QNX Software System
- *******************************************************************************/
- import org.eclipse.jface.text.rules.IWordDetector;
- /**
- * A C aware word detector.
- */
- public class KeyWordDetector implements IWordDetector {
- /**
- * @see IWordDetector#isWordIdentifierStart
- */
- public boolean isWordStart(char c) {
- if(64 < c && c < 123 || c == '=') { //大写字母A-Z, 小写字母a-z;
- return true;
- }
- return false;
- }
- /**
- * @see IWordDetector#isWordIdentifierPart
- */
- public boolean isWordPart(char c) {
- if(64 < c && c < 123 || c == '=') { //大写字母A-Z, 小写字母a-z;
- return true;
- }
- return false;
- }
- }
代码提示部分:
SQLContentAssistent:
- package com.test.assistent;
- import java.util.ArrayList;
- import java.util.List;
- import org.eclipse.jface.text.BadLocationException;
- import org.eclipse.jface.text.IDocument;
- import org.eclipse.jface.text.ITextViewer;
- import org.eclipse.jface.text.contentassist.CompletionProposal;
- import org.eclipse.jface.text.contentassist.ICompletionProposal;
- import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
- import org.eclipse.jface.text.contentassist.IContextInformation;
- import org.eclipse.jface.text.contentassist.IContextInformationValidator;
- import com.zdk.platform.studio.pojo.DBConfig;
- public class SQLContentAssistent implements IContentAssistProcessor {
- /**提示集合**/
- public List<IAssistentContent> assistentContentList = new ArrayList<IAssistentContent>();
- /**开始位置**/
- public int startIndex = 0;
- /**当前文档**/
- public IDocument doc;
- /**数据连接对象**/
- private DBConfig dbConfig;
- /**
- * 构造方法: 添加提示种类.
- */
- public SQLContentAssistent() {
- super();
- assistentContentList.add(new KeywordAssistentData());
- }
- @Override
- public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
- this.doc = viewer.getDocument();
- List list = new KeywordAssistentData().getAssistentData(this.doc, offset);
- return (CompletionProposal[]) list.toArray(new CompletionProposal[list.size()]);
- }
- @Override
- public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
- // TODO 自动生成的方法存根
- return null;
- }
- /**
- * 设置何时激活
- */
- @Override
- public char[] getCompletionProposalAutoActivationCharacters() {
- return new char[] {'.'};
- }
- @Override
- public char[] getContextInformationAutoActivationCharacters() {
- return null;
- }
- @Override
- public String getErrorMessage() {
- // TODO 自动生成的方法存根
- return null;
- }
- @Override
- public IContextInformationValidator getContextInformationValidator() {
- // TODO 自动生成的方法存根
- return null;
- }
- /**
- * 方法说明: 获取提示前面的字符串.
- * @param doc
- * @param offest
- * @return
- */
- public String getFrontText(IDocument doc, int offest) {
- StringBuffer buf = new StringBuffer();
- while(true) { //循环添加关键字.
- try {
- char c = doc.getChar(--offest);
- startIndex = offest;
- if(Character.isWhitespace(c)) {
- startIndex++;
- break;
- }
- if(c == ';' || c == '(' || c == ')' || c == '{' || c == '}' || c == ',') { //结束符号.
- startIndex++;
- break;
- }
- buf.append(c);
- } catch (BadLocationException e) {
- break;
- }
- }
- return buf.reverse().toString();
- }
- }
KeywordAssistentData:
- package com.test.assistent;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import org.eclipse.jface.text.BadLocationException;
- import org.eclipse.jface.text.IDocument;
- import org.eclipse.jface.text.contentassist.CompletionProposal;
- import com.zdk.platform.studio.dbassistant.codeassistent.Contents;
- /**
- * 类说明: 关键字提示数据类.
- * @author Administrator
- *
- */
- public class KeywordAssistentData implements IAssistentContent {
- private int start = 0;
- @Override
- public List<CompletionProposal> getAssistentData(IDocument doc, int offset) {
- String str = getFrontText(doc, offset);
- List<CompletionProposal> list = new ArrayList<CompletionProposal>();
- //用正则匹配.
- Pattern p = null;
- Matcher m = null;
- for (int i = 0; i < Contents.KEY_WORD_ARRAY.length; i++) {
- String keyWord = Contents.KEY_WORD_ARRAY[i];
- p = Pattern.compile("(^" + str + ")", Pattern.CASE_INSENSITIVE);
- m = p.matcher(keyWord);
- if(m.find()) {
- String insert = Contents.KEY_WORD_ARRAY[i];
- //创建替换类容. insert:替换文本, offset:替换其实位置.
- //0:替换结束位置.偏移量, insert.length:替换完成后.光标位置偏移量.
- CompletionProposal proposal = new CompletionProposal(insert, start, offset - start, insert.length());
- list.add(proposal);
- }
- }
- return list;
- }
- /**
- * 方法说明: 获取提示前面的字符串.
- * @param doc
- * @param offest
- * @return
- */
- public String getFrontText(IDocument doc, int offest) {
- StringBuffer buf = new StringBuffer();
- while(true) { //循环添加关键字.
- try {
- char c = doc.getChar(--offest);
- start = offest;
- if(Character.isWhitespace(c)) {
- start++;
- break;
- }
- if(c == ';' || c == '(' || c == ')' || c == '{' || c == '}' || c == ',') { //结束符号.
- start++;
- break;
- }
- buf.append(c);
- } catch (BadLocationException e) {
- break;
- }
- }
- return buf.reverse().toString();
- }
- }
以上就是大部分代码了.