CPU
Lieutenant
- Registriert
- Jan. 2006
- Beiträge
- 704
Hallo zusammen,
ich habe mir mal Gedanken zu einem Syntax-Highlighter (im Live-Modus, wenn man also noch einen Text schreibt) gemacht. Unten ist der Quellcode angehangen, den ich mir bis jetzt aus Google-Recherchen zusammengeschustert habe
. Funktioniert auch schon proprietär mit den Keywords.
Wenn ich ein Keyword lösche, dann bleibt das Highligthing. Wie entferne ich das Highlighting eines Wortes, wenn ein oder mehr Zeichen von dem Wort entfernt werden?
CPU
-----------------------------------------
CodeDocument.java
Test.java
ich habe mir mal Gedanken zu einem Syntax-Highlighter (im Live-Modus, wenn man also noch einen Text schreibt) gemacht. Unten ist der Quellcode angehangen, den ich mir bis jetzt aus Google-Recherchen zusammengeschustert habe
Wenn ich ein Keyword lösche, dann bleibt das Highligthing. Wie entferne ich das Highlighting eines Wortes, wenn ein oder mehr Zeichen von dem Wort entfernt werden?
CPU
-----------------------------------------
CodeDocument.java
Code:
package high;
import java.awt.Color;
import java.util.Vector;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Element;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
/*
* http://java.sys-con.com/node/36509
*/
public class CodeDocument extends DefaultStyledDocument{
private String word = "";
private SimpleAttributeSet bold = new SimpleAttributeSet();
private SimpleAttributeSet string = new SimpleAttributeSet();
private SimpleAttributeSet normal = new SimpleAttributeSet();
private SimpleAttributeSet number = new SimpleAttributeSet();
private SimpleAttributeSet comments = new SimpleAttributeSet();
private int currentPos = 0;
private Vector keywords = new Vector();
public static int STRING_MODE = 10;
public static int TEXT_MODE = 11;
public static int NUMBER_MODE = 12;
public static int COMMENT_MODE = 13;
private int mode = TEXT_MODE;
public CodeDocument() {
//set the bold attribute
StyleConstants.setBold(bold, true);
StyleConstants.setForeground(string, Color.red);
StyleConstants.setForeground(number, Color.magenta);
StyleConstants.setForeground(comments, Color.blue);
StyleConstants.setItalic(comments, true);
}
private void insertKeyword(String str, int pos){
try{
//remove the old word and formatting
this.remove(pos - str.length(), str.length());
/*replace it with the same word, but new formatting
*we MUST call the super class insertString method here, otherwise we
*would end up in an infinite loop !!!!!*/
super.insertString(pos - str.length(), str, bold);
}
catch (Exception ex){
ex.printStackTrace();
}
}
private void insertTextString(String str, int pos){
try{
//remove the old word and formatting
this.remove(pos,str.length());
super.insertString(pos, str, string);
}
catch (Exception ex){
ex.printStackTrace();
}
}
private void insertNumberString(String str, int pos){
try{
//remove the old word and formatting
this.remove(pos,str.length());
super.insertString(pos, str, number);
}
catch (Exception ex){
ex.printStackTrace();
}
}
private void insertCommentString(String str, int pos){
try{
//remove the old word and formatting
this.remove(pos,str.length());
super.insertString(pos, str, comments);
}
catch (Exception ex){
ex.printStackTrace();
}
}
private void checkForString(){
int offs = this.currentPos;
Element element = this.getParagraphElement(offs);
String elementText = "";
try{
//this gets our chuck of current text for the element we're on
elementText = this.getText(element.getStartOffset(),
element.getEndOffset() -
element.getStartOffset());
}
catch(Exception ex){
//whoops!
System.out.println("no text");
}
int strLen = elementText.length();
if (strLen == 0) {return;}
int i = 0;
if (element.getStartOffset() > 0){
//translates backward if neccessary
offs = offs - element.getStartOffset();
}
int quoteCount = 0;
if ((offs >= 0) && (offs <= strLen-1)){
i = offs;
while (i >0){
//the while loop walks back until we hit a delimiter
char charAt = elementText.charAt(i);
if ((charAt == '"')){
quoteCount ++;
}
i--;
}
int rem = quoteCount % 2;
//System.out.println(rem);
mode = (rem == 0) ? TEXT_MODE: STRING_MODE;
}
}
private void checkForKeyword(){
if (mode != TEXT_MODE) {
return;
}
int offs = this.currentPos;
Element element = this.getParagraphElement(offs);
String elementText = "";
try{
//this gets our chuck of current text for the element we're on
elementText = this.getText(element.getStartOffset(),
element.getEndOffset() - element.getStartOffset());
}
catch(Exception ex){
//whoops!
System.out.println("no text");
}
int strLen = elementText.length();
if (strLen == 0) {return;}
int i = 0;
if (element.getStartOffset() > 0){
//translates backward if neccessary
offs = offs - element.getStartOffset();
}
if ((offs >= 0) && (offs <= strLen-1)){
i = offs;
while (i >0){
//the while loop walks back until we hit a delimiter
i--;
char charAt = elementText.charAt(i);
if ((charAt == ' ') | (i == 0) | (charAt =='(') | (charAt ==')') |
(charAt == '{') | (charAt == '}')){ //if i == 0 then we're at the begininng
if(i != 0){
i++;
}
word = elementText.substring(i, offs);//skip the period
String s = word.trim().toLowerCase();
//this is what actually checks for a matching keyword
if (keywords.contains(s)){
insertKeyword(word, currentPos);
}
break;
}
}
}
}
private void checkForNumber(){
int offs = this.currentPos;
Element element = this.getParagraphElement(offs);
String elementText = "";
try{
//this gets our chuck of current text for the element we're on
elementText = this.getText(element.getStartOffset(),
element.getEndOffset() - element.getStartOffset());
}
catch(Exception ex){
//whoops!
System.out.println("no text");
}
int strLen = elementText.length();
if (strLen == 0) {return;}
int i = 0;
if (element.getStartOffset() > 0){
//translates backward if neccessary
offs = offs - element.getStartOffset();
}
mode = TEXT_MODE;
if ((offs >= 0) && (offs <= strLen-1)){
i = offs;
while (i >0){
//the while loop walks back until we hit a delimiter
char charAt = elementText.charAt(i);
if ((charAt == ' ') | (i == 0) | (charAt =='(') | (charAt ==')') |
(charAt == '{') | (charAt == '}') /*|*/){ //if i == 0 then we're at the begininng
if(i != 0){
i++;
}
mode = NUMBER_MODE;
break;
}
else if (!(charAt >= '0' & charAt <= '9' | charAt=='.'
| charAt=='+' | charAt=='-'
| charAt=='/' | charAt=='*'| charAt=='%' | charAt=='=')){
mode = TEXT_MODE;
break;
}
i--;
}
}
}
private void checkForComment(){
int offs = this.currentPos;
Element element = this.getParagraphElement(offs);
String elementText = "";
try{
//this gets our chuck of current text for the element we're on
elementText = this.getText(element.getStartOffset(),
element.getEndOffset() - element.getStartOffset());
}
catch(Exception ex){
//whoops!
System.out.println("no text");
}
int strLen = elementText.length();
if (strLen == 0) {return;}
int i = 0;
if (element.getStartOffset() > 0){
//translates backward if neccessary
offs = offs - element.getStartOffset();
}
if ((offs >= 1) && (offs <= strLen-1)){
i = offs;
char commentStartChar1 = elementText.charAt(i-1);
char commentStartChar2 = elementText.charAt(i);
if (commentStartChar1 == '/' && commentStartChar2 == '*'){
mode = COMMENT_MODE;
this.insertCommentString("/*", currentPos-1);
}
else if (commentStartChar1 == '*' && commentStartChar2 == '/'){
mode = TEXT_MODE;
this.insertCommentString("*/", currentPos-1);
}
}
}
private void processChar(String str){
char strChar = str.charAt(0);
if (mode != this.COMMENT_MODE){
mode = TEXT_MODE;
}
switch (strChar){
case ('{'):case ('}'):case (' '): case('\n'):
case ('('):case (')'):case (';'):case ('.'):{
checkForKeyword();
if (mode == STRING_MODE && strChar == '\n'){
mode = TEXT_MODE;
}
}
break;
case ('"'):{
insertTextString(str, currentPos);
this.checkForString();
}
break;
case ('0'):case ('1'):case ('2'):case ('3'):case ('4'):
case ('5'):case ('6'):case ('7'):case ('8'):case ('9'):{
checkForNumber();
}
break;
case ('*'):case ('/'):{
checkForComment();
}
break;
}
if (mode == this.TEXT_MODE){
this.checkForString();
}
if (mode == this.STRING_MODE){
insertTextString(str, this.currentPos);
}
else if (mode == this.NUMBER_MODE){
insertNumberString(str, this.currentPos);
}
else if (mode == this.COMMENT_MODE){
insertCommentString(str, this.currentPos);
}
}
private void processChar(char strChar){
char[] chrstr = new char[1];
chrstr[0] = strChar;
String str = new String(chrstr);
processChar(str);
}
public void insertString(int offs,
String str,
AttributeSet a) throws BadLocationException{
super.insertString(offs, str, normal);
int strLen = str.length();
int endpos = offs + strLen;
int strpos;
for (int i=offs;i<endpos;i++){
currentPos = i;
strpos = i - offs;
processChar(str.charAt(strpos));
}
currentPos = offs;
}
public Vector getKeywords(){
return this.keywords;
}
public void setKeywords(Vector aKeywordList){
if (aKeywordList != null){
this.keywords = aKeywordList;
}
}
}
Code:
package high;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JTextPane;
public class Test{
public static void main(String[] args) {
JFrame frame = new JFrame();
JTextPane editor = new JTextPane();
CodeDocument doc = new CodeDocument();
Vector keywords = new Vector();
keywords.addElement("test");
doc.setKeywords(keywords);
editor.setDocument(doc);
frame.setSize(400,400);
frame.getContentPane().add(editor);
frame.show();
}
}