📄 sqlsyntaxdocument.java
字号:
/* * SQLSyntaxDocument.java * * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */package org.executequery.gui.text.syntax;import java.awt.Color;import java.awt.Font;import java.util.ArrayList;import java.util.List;import java.util.Vector;import javax.swing.text.AttributeSet;import javax.swing.text.DefaultStyledDocument;import javax.swing.text.Element;import javax.swing.text.JTextComponent;import javax.swing.text.Style;import javax.swing.text.BadLocationException;import javax.swing.text.DefaultEditorKit;import javax.swing.text.StyleConstants;import java.util.regex.Matcher;import java.util.regex.Pattern;import org.executequery.Constants;import org.executequery.gui.editor.QueryEditorConstants;import org.executequery.gui.editor.QueryEditorSettings;/* ---------------------------------------------------------- * CVS NOTE: Changes to the CVS repository prior to the * release of version 3.0.0beta1 has meant a * resetting of CVS revision numbers. * ---------------------------------------------------------- *//** * * @author Takis Diakoumis * @version $Revision: 1.4 $ * @date $Date: 2006/05/14 06:56:57 $ */public class SQLSyntaxDocument extends DefaultStyledDocument implements TokenTypes { /** The document root element */ private Element rootElement; /** The text component owner of this document */ private JTextComponent textComponent; /** Convert tabs to spaces */ private boolean tabsToSpaces; /** tracks brace positions */ private Vector braceTokens; /** the current text insert mode */ private int insertMode; /** tracks string literal entries (quotes) */ private List<Token> stringTokens; /* syntax matchers */ private TokenMatcher[] matchers; public SQLSyntaxDocument() { this(null, null); } public SQLSyntaxDocument(List<String> keys) { this(keys, null); } public SQLSyntaxDocument(List<String> keys, JTextComponent textComponent) { rootElement = getDefaultRootElement(); putProperty(DefaultEditorKit.EndOfLineStringProperty, "\n"); initStyles(false); braceTokens = new Vector(); stringTokens = new ArrayList<Token>(); this.textComponent = textComponent; initMatchers(); if (keys != null) { setSQLKeywords(keys, false); } } protected void initMatchers() { matchers = new TokenMatcher[MATCHERS.length]; matchers[NUMBER_MATCH] = new TokenMatcher(NUMBER, styles[NUMBER], Pattern.compile(NUMBER_REGEX). matcher(Constants.EMPTY)); matchers[BRACES_MATCH] = new TokenMatcher(BRACKET, styles[BRACKET], Pattern.compile(BRACES_REGEX). matcher(Constants.EMPTY)); matchers[OPERATOR_MATCH] = new TokenMatcher(OPERATOR, styles[OPERATOR], Pattern.compile(OPERATOR_REGEX). matcher(Constants.EMPTY)); matchers[STRING_MATCH] = new TokenMatcher(STRING, styles[STRING], Pattern.compile(QUOTE_REGEX). matcher(Constants.EMPTY)); matchers[SINGLE_LINE_COMMENT_MATCH] = new TokenMatcher(SINGLE_LINE_COMMENT, styles[SINGLE_LINE_COMMENT], Pattern.compile(SINGLE_LINE_COMMENT_REGEX). matcher(Constants.EMPTY)); char PIPE = '|'; StringBuffer sb = new StringBuffer("\\b("); String[] literals = {Constants.TRUE_LITERAL, Constants.FALSE_LITERAL, Constants.NULL_LITERAL}; for (int i = 0, n = literals.length - 1; i < literals.length; i++) { sb.append(literals[i]); if (i < n) { sb.append(PIPE); } } sb.append(")\\b"); matchers[LITERALS_MATCH] = new TokenMatcher(LITERAL, styles[LITERAL], Pattern.compile( sb.toString(), Pattern.CASE_INSENSITIVE). matcher(Constants.EMPTY)); } public void setTextComponent(JTextComponent textComponent) { this.textComponent = textComponent; } public void resetAttributeSets() { initStyles(true); // update the stored tokens for (int i = 0; i < matchers.length; i++) { TokenMatcher matcher = matchers[i]; int type = matcher.getType(); matcher.setStyle(styles[type]); } } public void setTabsToSpaces(boolean tabsToSpaces) { this.tabsToSpaces = tabsToSpaces; } private Token getAvailableBraceToken() { for (int i = 0, k = braceTokens.size(); i < k; i++) { Token token = (Token)braceTokens.elementAt(i); if (!token.isValid()) { return token; } } Token token = new Token(-1, -1, -1); braceTokens.add(token); return token; } private boolean hasValidBraceTokens() { int size = braceTokens.size(); if (size == 0) { return false; } else { for (int i = 0; i < size; i++) { Token token = (Token)braceTokens.elementAt(i); if (token.isValid()) { return true; } } } return false; } public void resetBracePosition() { if (!hasValidBraceTokens()) { return; } for (int i = 0, k = braceTokens.size(); i < k; i++) { Token token = (Token)braceTokens.elementAt(i); applyBraceHiglight(false, token); token.reset(); } } public void applyBraceHiglight(boolean apply, Token token) { Style style = apply ? styles[token.getStyle()] : styles[BRACKET]; if (token.getStartIndex() != -1) { setCharacterAttributes(token.getStartIndex(), 1, style, !apply); } if (token.getEndIndex() != -1) { setCharacterAttributes(token.getEndIndex(), 1, style, !apply); } } private void applyErrorBrace(int offset, char brace) { if (!isOpenBrace(brace)) { Token token = getAvailableBraceToken(); token.reset(BRACKET_HIGHLIGHT_ERR, offset, -1); applyBraceHiglight(true, token); } } public void updateBraces(int offset) { try { int length = getLength(); if (length == 0) { return; } String text = getText(0, length); char charAtOffset = 0; char charBeforeOffset = 0; if (offset > 0) { charBeforeOffset = text.charAt(offset - 1); } if (offset < length) { charAtOffset = text.charAt(offset); } int matchOffset = -1; if (isBrace(charAtOffset)) { matchOffset = getMatchingBraceOffset(offset, charAtOffset, text); if (matchOffset == -1) { applyErrorBrace(offset, charAtOffset); return; } } else if (isBrace(charBeforeOffset)) { offset--; matchOffset = getMatchingBraceOffset(offset, charBeforeOffset, text); if (matchOffset == -1) { applyErrorBrace(offset, charBeforeOffset); return; } } if (matchOffset == -1) { return; } Token token = getAvailableBraceToken(); token.reset(BRACKET_HIGHLIGHT, offset, matchOffset); applyBraceHiglight(true, token); } catch (BadLocationException e) { throw new Error(e); } } private int getMatchingBraceOffset(int offset, char brace, String text) { int thisBraceCount = 0; int matchingBraceCount = 0; char braceMatch = getMatchingBrace(brace); char[] chars = text.toCharArray(); if (isOpenBrace(brace)) { for (int i = offset; i < chars.length; i++) { if (chars[i] == brace) { thisBraceCount++; } else if (chars[i] == braceMatch) { matchingBraceCount++; } if (thisBraceCount == matchingBraceCount) { return i; } } } else { for (int i = offset; i >= 0; i--) { if (chars[i] == brace) { thisBraceCount++; } else if (chars[i] == braceMatch) { matchingBraceCount++; } if (thisBraceCount == matchingBraceCount) { return i; } } } return -1; } private char getMatchingBrace(char brace) { switch (brace) { case '(': return ')'; case ')': return '('; case '[': return ']'; case ']': return '['; case '{': return '}'; case '}': return '{'; default: return 0; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -