- Project: Syntax Highlighting
- The API
- "Listening" for the Caret
- Doing the Highlights
- Running It
- Debugging: Indentation
- Conclusion
"Listening" for the Caret
We want to highlight the character immediately before the current location (if it's a closing brace). Java calls the current location the caret, since it could be represented by a character looking like a caret (^), even though it's usually represented by a vertical bar instead. So we need to listen to the current position of the caret. That's done with a CaretListener, like this:
class BracketMatcher implements CaretListener { public void caretUpdate(CaretEvent e) { // Update the highlighting } }
From the CaretEvent, we can determine the current position of the caret, the JTextComponent being modified, and the Document being edited:
JTextComponent source = (JTextComponent) e.getSource(); int pos = e.getDot(); Document doc = source.getDocument();
The caret is actually divided into two parts: the "dot" (where the user just clicked or moved to) and the "mark," which represents the other end of a selection (for example, if the user has dragged the mouse, or done a Shift-click). We're interested only in the dot for now.
To determine whether we're looking at a closing parenthesis, we have to look at the character before the dot:
char c = doc.getText(e.getDot()-1, 1).charAt(0);
Document only has facilities to return strings, not individual characters, so we have to take a one-character string and retrieve the first character like this. We check c to see if it's a closing parenthesis, brace, or bracket:
if(c != ')') && c != '}') && c != ']') return;
The getText call potentially throws a BadLocationException, which isn't supposed to happen since the dot represents a place where the user just clicked. We do need to deal with the case where the dot is 0, which represents the very beginning of the document, since we can't get the 1st character. That's fine, since a dot of 0 represents the beginning of the document, which means it's impossible to have a character immediately before us. We exclude that case with this code before the getText call:
if(pos == 0) return;
Now all we have to do is determine the position of the matching parenthesis, if any. I won't go into that here, you can read the code for findMatchingParen for yourself. It's primitive, as I said earlier, since the parsing isn't the point. It's all locked up in:
int closeParen = e.getDot()-1; int openParen = findMatchingParen(closeParen);