|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV |
TOP THREE LINKS YOU MUST CLICK ON Java SE 6 More on Syntax Highlighting
More on Syntax Highlighting
By: Jim Crafton
Jul. 1, 1999 12:00 AM
Last month we discussed the use of Swing's Document model to create a syntax-highlighting Document model that we could just plug into JTextPane and use. This month we'll continue with that and add complete support for comments, strings and numbers. We'll also cover how easy it is to actually use the model we've developed, and test things out as we go along. To start things out let's try and use what we have so far. If we look at the code below we can see that plugging the Document we've created into a JTextPane component is quite easy. Defining the keywords is also very easy.
JTextPane editor = new JTextPane(); We could have just created the CodeDocument on the fly and passed it in as an argument to the constructor of the JTextPane class, but then the keywords for the Document wouldn't have been set and we'd have had to retrieve the Document and then add them. By running the code above and typing in some text, we get the window in Figure 1 to come up. A word of caution: If you use this and the first word you type in is in your keywords list, you¹ll get an exception. This is a known bug on the Swing Web site (for more information look at .http://developer.java.sun.com/developer/bugParade/bugs/4128967.html) with no known workaround. You may also notice that when you type for a while and then move the cursor back to a previous position and start typing again, the JTextPane doesn't quite repaint itself correctly. This is also a known bug of the JTextPane (for more information see http://developer.java.sun.com/developer/ bugParade/bugs/4127974.html). This has been fixed in Swing version 1.1. Now you can test the modifications we'll be making to the CodeDocument class.
Changing the insertString Method
public void insertString(int offs, The only problem with the solution above is that when reading large chunks of text you may notice a slowdown in JTextPane's performance while it loads and parses all the text. A possible solution would be to use a thread to handle any text not immediately visible to the user, parse it in the background and then...well, that'll be the subject of a future article!
Adding String Support
In addition to variables we'll need some new methods. For strings we'll create a checkForString() method that will determine whether we're inside a string. If it finds that we are, the mode variable will be set appropriately (this will be explained in more detail a few paragraphs down). We'll also need a method called insertTextString() that will actually reinsert the properly formatted string.
Adding Number Support
Like strings, the checkForNumber() method determines whether we're actually entering valid digits. If we are, it sets the CodeDocument's mode accordingly. Like insertTextString, insertNumberString inserts the properly formatted text as a number.
Adding Comment Support
Putting It All Together
For example, when it encounters the character '9', it figures there's a very good chance that this is the start of a number or that a number is currently in the process of being entered. To verify this it calls the checkForNumber() method. If checkForNumber() determines that we're still entering a number, it sets the mode to the number entry mode. If it discovers any other character present, however, such as a space, a parenthesis or a letter, it sets the mode to the default text entry mode (the number entry mode is represented by the static constant NUMBER_MODE, while the text entry mode is represented by the static constant TEXT_MODE). The other checkForXXX() methods work in a similar fashion. After the checkForXXX() method has returned, the mode will have been set correctly and, based on this, the proper insertXXXString() method can be called. If the mode is in TEXT_MODE, the formatting is left alone. Now look at the code in Listing 1 for method processChar. The first thing the method does is to check if we're in COMMENT_MODE. Because comments can include anything (aside from the comment-terminating characters), we'll let the mode default to COMMENT_MODE; otherwise we'll change it to default to TEXT_MODE, which is the standard text entry mode (no formatting). Next, a switch statement is created based on the character passed to the processChar method. As mentioned before, the method works on the assumption that the character being entered belongs to one of five groups (generic text, keywords, strings, numbers or comments), and that the case statements are grouped accordingly. Characters equaling the numbers '1' through '9' cause a check for numbers; characters equaling '*' or '/' suggest the possible start or end of a comment block, and a check is made; and so on. Once the switch statement is finished executing, a final check is made for quoted strings if we're still in TEXT_MODE. Finally, depending on which mode we're in, a call is made to the appropriate insertXXXString method. There are four check methods: checkForComment(), checkForKeyword(), checkForNumber() and checkForString(). While there are some differences from the original checkForKeywords() method, the basic idea, as discussed last month, is the same. We retrieve the current element, get the text from it, find our position in the element and then, starting at the end, we walk backward until a delimiter of some sort is found and then set the mode accordingly. Let's look at some of the checkForString() method's code to examine this more closely. We'll assume we already have the correct offset from the Document's element.
.. The code is fairly simple: we loop backward until we run out of characters to process, each time comparing a character from the element text. If the character is a double quote (" "), we add one to the local variable called quoteCount. Once we're done with the loop, we check the remainder of the quoteCount divided by two and assign the results to another local variable called rem. Why do this? Again, this is another assumption about the way words are put together. Since quotes always come in pairs, if our remainder isn't equal to zero, we know we're "inside" a string quotation. Otherwise we can safely assume that we're "outside" and are just entering normal text.
And Finally...
References
LATEST JAVA STORIES & POSTS
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK SPONSORED BY INFRAGISTICS
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||