View Javadoc

1   /*
2    * TextUtilities.java - Utility functions used by the text area classes
3    * Copyright (C) 1999 Slava Pestov
4    *
5    * You may use and modify this package for any purpose. Redistribution is
6    * permitted, in both source and binary form, provided that this notice
7    * remains intact in all source distributions of this package.
8    */
9   package com.ochafik.swing.syntaxcoloring;
10  import javax.swing.text.BadLocationException;
11  import javax.swing.text.Document;
12  
13  /**
14   * Class with several utility functions used by the text area component.
15   * @author Slava Pestov
16   * @version $Id: TextUtilities.java,v 1.4 1999/12/13 03:40:30 sp Exp $
17   */
18  
19  public class TextUtilities
20  {
21  	/**
22  	 * Returns the offset of the bracket matching the one at the
23  	 * specified offset of the document, or -1 if the bracket is
24  	 * unmatched (or if the character is not a bracket).
25  	 * @param doc The document
26  	 * @param offset The offset
27  	 * @exception BadLocationException If an out-of-bounds access
28  	 * was attempted on the document text
29  	 */
30  	public static int findMatchingBracket(Document doc, int offset)
31  		throws BadLocationException
32  	{
33  		if(doc.getLength() == 0)
34  			return -1;
35  		char c = doc.getText(offset,1).charAt(0);
36  		char cprime; // c` - corresponding character
37  		boolean direction; // true = back, false = forward
38  
39  		switch(c)
40  		{
41  		case '(': cprime = ')'; direction = false; break;
42  		case ')': cprime = '('; direction = true; break;
43  		case '[': cprime = ']'; direction = false; break;
44  		case ']': cprime = '['; direction = true; break;
45  		case '{': cprime = '}'; direction = false; break;
46  		case '}': cprime = '{'; direction = true; break;
47  		default: return -1;
48  		}
49  
50  		int count;
51  
52  		// How to merge these two cases is left as an exercise
53  		// for the reader.
54  
55  		// Go back or forward
56  		if(direction)
57  		{
58  			// Count is 1 initially because we have already
59  			// `found' one closing bracket
60  			count = 1;
61  
62  			// Get text[0,offset-1];
63  			String text = doc.getText(0,offset);
64  
65  			// Scan backwards
66  			for(int i = offset - 1; i >= 0; i--)
67  			{
68  				// If text[i] == c, we have found another
69  				// closing bracket, therefore we will need
70  				// two opening brackets to complete the
71  				// match.
72  				char x = text.charAt(i);
73  				if(x == c)
74  					count++;
75  
76  				// If text[i] == cprime, we have found a
77  				// opening bracket, so we return i if
78  				// --count == 0
79  				else if(x == cprime)
80  				{
81  					if(--count == 0)
82  						return i;
83  				}
84  			}
85  		}
86  		else
87  		{
88  			// Count is 1 initially because we have already
89  			// `found' one opening bracket
90  			count = 1;
91  
92  			// So we don't have to + 1 in every loop
93  			offset++;
94  
95  			// Number of characters to check
96  			int len = doc.getLength() - offset;
97  
98  			// Get text[offset+1,len];
99  			String text = doc.getText(offset,len);
100 
101 			// Scan forwards
102 			for(int i = 0; i < len; i++)
103 			{
104 				// If text[i] == c, we have found another
105 				// opening bracket, therefore we will need
106 				// two closing brackets to complete the
107 				// match.
108 				char x = text.charAt(i);
109 
110 				if(x == c)
111 					count++;
112 
113 				// If text[i] == cprime, we have found an
114 				// closing bracket, so we return i if
115 				// --count == 0
116 				else if(x == cprime)
117 				{
118 					if(--count == 0)
119 						return i + offset;
120 				}
121 			}
122 		}
123 
124 		// Nothing found
125 		return -1;
126 	}
127 
128 	/**
129 	 * Locates the start of the word at the specified position.
130 	 * @param line The text
131 	 * @param pos The position
132 	 */
133 	public static int findWordStart(String line, int pos, String noWordSep)
134 	{
135 		char ch = line.charAt(pos - 1);
136 
137 		if(noWordSep == null)
138 			noWordSep = "";
139 		boolean selectNoLetter = (!Character.isLetterOrDigit(ch)
140 			&& noWordSep.indexOf(ch) == -1);
141 
142 		int wordStart = 0;
143 		for(int i = pos - 1; i >= 0; i--)
144 		{
145 			ch = line.charAt(i);
146 			if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
147 				noWordSep.indexOf(ch) == -1))
148 			{
149 				wordStart = i + 1;
150 				break;
151 			}
152 		}
153 
154 		return wordStart;
155 	}
156 
157 	/**
158 	 * Locates the end of the word at the specified position.
159 	 * @param line The text
160 	 * @param pos The position
161 	 */
162 	public static int findWordEnd(String line, int pos, String noWordSep)
163 	{
164 		char ch = line.charAt(pos);
165 
166 		if(noWordSep == null)
167 			noWordSep = "";
168 		boolean selectNoLetter = (!Character.isLetterOrDigit(ch)
169 			&& noWordSep.indexOf(ch) == -1);
170 
171 		int wordEnd = line.length();
172 		for(int i = pos; i < line.length(); i++)
173 		{
174 			ch = line.charAt(i);
175 			if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
176 				noWordSep.indexOf(ch) == -1))
177 			{
178 				wordEnd = i;
179 				break;
180 			}
181 		}
182 		return wordEnd;
183 	}
184 }