001: package com.pk;
002:
003: //import javax.swing.*;
004: import javax.swing.text.*;
005: import java.awt.*;
006:
007: public class CodeDocument extends DefaultStyledDocument {
008: /**
009: *
010: */
011: private static final long serialVersionUID = 4331100125022402235L;
012: private String word = "";
013: private SimpleAttributeSet bold = new SimpleAttributeSet();
014: private SimpleAttributeSet string = new SimpleAttributeSet();
015: private SimpleAttributeSet normal = new SimpleAttributeSet();
016: private SimpleAttributeSet number = new SimpleAttributeSet();
017: private SimpleAttributeSet comments = new SimpleAttributeSet();
018: private int currentPos = 0;
019: private java.util.List keywords = null;
020: public static int STRING_MODE = 10;
021: public static int TEXT_MODE = 11;
022: public static int NUMBER_MODE = 12;
023: public static int COMMENT_MODE = 13;
024: private int mode = TEXT_MODE;
025:
026: public CodeDocument() {
027: //set the bold attribute
028: //StyleConstants.setBold(bold, true);
029: StyleConstants.setForeground(bold, Color.blue);
030: //StyleConstants.setFontFamily(bold, "Courier");
031: StyleConstants.setForeground(string, Color.red);
032: StyleConstants.setForeground(number, Color.magenta);
033: StyleConstants.setForeground(comments, Color.blue);
034: StyleConstants.setItalic(comments, true);
035: }
036:
037: private void insertKeyword(String str, int pos) {
038: try {
039: //remove the old word and formatting
040: this .remove(pos - str.length(), str.length());
041: /*replace it with the same word, but new formatting
042: *we MUST call the super class insertString method here, otherwise we
043: *would end up in an infinite loop !!!!!*/
044: super .insertString(pos - str.length(), str, bold);
045: } catch (Exception ex) {
046: ex.printStackTrace();
047: }
048: }
049:
050: private void insertTextString(String str, int pos) {
051: try {
052: //remove the old word and formatting
053: this .remove(pos, str.length());
054: super .insertString(pos, str, string);
055: } catch (Exception ex) {
056: ex.printStackTrace();
057: }
058: }
059:
060: private void insertNumberString(String str, int pos) {
061: try {
062: //remove the old word and formatting
063: this .remove(pos, str.length());
064: super .insertString(pos, str, number);
065: } catch (Exception ex) {
066: ex.printStackTrace();
067: }
068: }
069:
070: private void insertCommentString(String str, int pos) {
071: try {
072: //remove the old word and formatting
073: this .remove(pos, str.length());
074: super .insertString(pos, str, comments);
075: } catch (Exception ex) {
076: ex.printStackTrace();
077: }
078: }
079:
080: private void checkForString() {
081: int offs = this .currentPos;
082: Element element = this .getParagraphElement(offs);
083: String elementText = "";
084: try {
085: //this gets our chuck of current text for the element we're on
086: elementText = this .getText(element.getStartOffset(),
087: element.getEndOffset() - element.getStartOffset());
088: } catch (Exception ex) {
089: //whoops!
090: System.out.println("no text");
091: }
092: int strLen = elementText.length();
093: if (strLen == 0) {
094: return;
095: }
096: int i = 0;
097:
098: if (element.getStartOffset() > 0) {
099: //translates backward if neccessary
100: offs = offs - element.getStartOffset();
101: }
102: int quoteCount = 0;
103: if ((offs >= 0) && (offs <= strLen - 1)) {
104: i = offs;
105: while (i > 0) {
106: //the while loop walks back until we hit a delimiter
107:
108: char charAt = elementText.charAt(i);
109: if ((charAt == '"')) {
110: quoteCount++;
111: }
112: i--;
113: }
114: int rem = quoteCount % 2;
115: //System.out.println(rem);
116: mode = (rem == 0) ? TEXT_MODE : STRING_MODE;
117: }
118: }
119:
120: private void checkForKeyword() {
121: if (mode != TEXT_MODE) {
122: return;
123: }
124: int offs = this .currentPos;
125: Element element = this .getParagraphElement(offs);
126: String elementText = "";
127: try {
128: //this gets our chuck of current text for the element we're on
129: elementText = this .getText(element.getStartOffset(),
130: element.getEndOffset() - element.getStartOffset());
131: } catch (Exception ex) {
132: //whoops!
133: System.out.println("no text");
134: }
135: int strLen = elementText.length();
136: if (strLen == 0) {
137: return;
138: }
139: int i = 0;
140:
141: if (element.getStartOffset() > 0) {
142: //translates backward if neccessary
143: offs = offs - element.getStartOffset();
144: }
145: if ((offs >= 0) && (offs <= strLen - 1)) {
146: i = offs;
147: while (i > 0) {
148: //the while loop walks back until we hit a delimiter
149: i--;
150: char charAt = elementText.charAt(i);
151: if ((charAt == ' ') | (i == 0) | (charAt == '(')
152: | (charAt == ')') | (charAt == '{')
153: | (charAt == '}')) { //if i == 0 then we're at the begininng
154: if (i != 0) {
155: i++;
156: }
157: word = elementText.substring(i, offs); //skip the period
158:
159: String s = word.trim().toLowerCase();
160: //this is what actually checks for a matching keyword
161: if (keywords.contains(s)) {
162: insertKeyword(word, currentPos);
163: }
164: break;
165: }
166: }
167: }
168: }
169:
170: private void checkForNumber() {
171: int offs = this .currentPos;
172: Element element = this .getParagraphElement(offs);
173: String elementText = "";
174: try {
175: //this gets our chuck of current text for the element we're on
176: elementText = this .getText(element.getStartOffset(),
177: element.getEndOffset() - element.getStartOffset());
178: } catch (Exception ex) {
179: //whoops!
180: System.out.println("no text");
181: }
182: int strLen = elementText.length();
183: if (strLen == 0) {
184: return;
185: }
186: int i = 0;
187:
188: if (element.getStartOffset() > 0) {
189: //translates backward if neccessary
190: offs = offs - element.getStartOffset();
191: }
192: mode = TEXT_MODE;
193: if ((offs >= 0) && (offs <= strLen - 1)) {
194: i = offs;
195: while (i > 0) {
196: //the while loop walks back until we hit a delimiter
197: char charAt = elementText.charAt(i);
198: if ((charAt == ' ') | (i == 0) | (charAt == '(')
199: | (charAt == ')') | (charAt == '{')
200: | (charAt == '}') /*|*/
201: ) { //if i == 0 then we're at the begininng
202: if (i != 0) {
203: i++;
204: }
205: mode = NUMBER_MODE;
206: break;
207: } else if (!(charAt >= '0' & charAt <= '9'
208: | charAt == '.' | charAt == '+' | charAt == '-'
209: | charAt == '/' | charAt == '*' | charAt == '%' | charAt == '=')) {
210: mode = TEXT_MODE;
211: break;
212: }
213: i--;
214: }
215: }
216: }
217:
218: private void checkForComment() {
219: int offs = this .currentPos;
220: Element element = this .getParagraphElement(offs);
221: String elementText = "";
222: try {
223: //this gets our chuck of current text for the element we're on
224: elementText = this .getText(element.getStartOffset(),
225: element.getEndOffset() - element.getStartOffset());
226: } catch (Exception ex) {
227: //whoops!
228: System.out.println("no text");
229: }
230: int strLen = elementText.length();
231: if (strLen == 0) {
232: return;
233: }
234: int i = 0;
235:
236: if (element.getStartOffset() > 0) {
237: //translates backward if neccessary
238: offs = offs - element.getStartOffset();
239: }
240: if ((offs >= 1) && (offs <= strLen - 1)) {
241: i = offs;
242: char commentStartChar1 = elementText.charAt(i - 1);
243: char commentStartChar2 = elementText.charAt(i);
244: if (commentStartChar1 == '/' && commentStartChar2 == '*') {
245: mode = COMMENT_MODE;
246: this .insertCommentString("/*", currentPos - 1);
247: } else if (commentStartChar1 == '*'
248: && commentStartChar2 == '/') {
249: mode = TEXT_MODE;
250: this .insertCommentString("*/", currentPos - 1);
251: }
252: }
253: }
254:
255: private void processChar(String str) {
256: char strChar = str.charAt(0);
257: if (mode != CodeDocument.COMMENT_MODE) {
258: mode = TEXT_MODE;
259: }
260: switch (strChar) {
261: case ('{'):
262: case ('}'):
263: case (' '):
264: case ('\n'):
265: case ('('):
266: case (')'):
267: case (';'):
268: case ('.'): {
269: checkForKeyword();
270: if (mode == STRING_MODE && strChar == '\n') {
271: mode = TEXT_MODE;
272: }
273: }
274: break;
275: case ('"'): {
276: insertTextString(str, currentPos);
277: this .checkForString();
278: }
279: break;
280: case ('0'):
281: case ('1'):
282: case ('2'):
283: case ('3'):
284: case ('4'):
285: case ('5'):
286: case ('6'):
287: case ('7'):
288: case ('8'):
289: case ('9'): {
290: checkForNumber();
291: }
292: break;
293: case ('*'):
294: case ('/'): {
295: checkForComment();
296: }
297: break;
298: }
299: if (mode == CodeDocument.TEXT_MODE) {
300: this .checkForString();
301: }
302: if (mode == CodeDocument.STRING_MODE) {
303: insertTextString(str, this .currentPos);
304: } else if (mode == CodeDocument.NUMBER_MODE) {
305: insertNumberString(str, this .currentPos);
306: } else if (mode == CodeDocument.COMMENT_MODE) {
307: insertCommentString(str, this .currentPos);
308: }
309:
310: }
311:
312: private void processChar(char strChar) {
313: char[] chrstr = new char[1];
314: chrstr[0] = strChar;
315: String str = new String(chrstr);
316: processChar(str);
317: }
318:
319: public void insertString(int offs, String str, AttributeSet a)
320: throws BadLocationException {
321: super .insertString(offs, str, normal);
322:
323: int strLen = str.length();
324: int endpos = offs + strLen;
325: int strpos;
326: for (int i = offs; i < endpos; i++) {
327: currentPos = i;
328: strpos = i - offs;
329: processChar(str.charAt(strpos));
330: }
331: currentPos = offs;
332: }
333:
334: public java.util.List getKeywords() {
335: return this .keywords;
336: }
337:
338: public void setKeywords(java.util.List aKeywordList) {
339: if (aKeywordList != null) {
340: this.keywords = aKeywordList;
341: }
342: }
343: }
|