This may be a sloppy method of doing so, but you can send a reference to the JTextPane that you are using and manipulate the Caret after you are done sending characters to the Document.
/**
*
*/
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
/**
* @author Bill
*
*/
public class SyntaxDocument2 extends DefaultStyledDocument {
private static final long serialVersionUID = 8802669064394912853L;
SimpleAttributeSet norm = new SimpleAttributeSet();
SimpleAttributeSet tag = new SimpleAttributeSet();
SimpleAttributeSet string = new SimpleAttributeSet();
private JTextPane jp = null; // A reference to a JTextPane
/**
* Sets some stuff up.
*/
public SyntaxDocument2( JTextPane jp ) {
this.jp = jp; // assigning the passed reference to the globally scoped one
StyleConstants.setForeground( tag, Color.green );
StyleConstants.setForeground( string, Color.red );
}
/**
* @see javax.swing.text.AbstractDocument#insertString(int, java.lang.String, javax.swing.text.AttributeSet)
*/
@Override
public void insertString( int offs, String str, AttributeSet a )
throws BadLocationException {
super.insertString( offs, str, a );
String str2 = super.getText( 0, super.getLength() );
super.remove( 0, super.getLength() );
int off = 0;
char c;
boolean inTag=false;
boolean inString=false;
for(int i = 0;i<str2.length();i++,off++) {
c=str2.charAt( i );
switch( c ) {
case '<':
inTag=true;
super.insertString( off, ""+c, tag );
break;
case '>':
inTag=false;
super.insertString( off, ""+c, tag );
break;
case '"':
if(inTag) {
inString=!inString;
super.insertString( off, ""+c, string );
} else {
super.insertString( off, ""+c, norm );
}
break;
default:
if(inTag) {
if(inString) {
super.insertString( off, ""+c, string );
} else {
super.insertString( off, ""+c, tag );
}
} else {
super.insertString( off, ""+c, norm );
}
break;
}
}
/*
* Assuming the '^' char is our cursor,
* the desired result for input into the document
* is as follows--
*
* [H, i, , T, h,^ r, e]
* [1, 2, 3, 4, 5, 6, 7]
*
* after inserting e past h,
*
* [H, i, , T, h, e,^ r, e]
* [1, 2, 3, 4, 5, 6, 7, 8]
*
* -- basically we want the cursor to act like a regular
* cursor in a text document. That is, we want the cursor
* to increment by one after we insert a character into the
* document.
*
* http://java.sun.com/javase/6/docs/api/javax/swing/text/Caret.html
* Shows the Caret API used in the JTextPane. Although a JTextPane
* will view/modify its Document, ultimately the interface needed to
* operate on the JTextPane itself is its Caret.
*
* I'm assuming that the JTextPane is listening for property and
* key events, but I'm not entirely sure of the exact relationship
* between the events occurring on the pane and the Caret's position.
*
* This is an expirimental solution. There may be a way to send a
* hint to the JTextPane (a flag, or maybe another command) such that
* the Caret can be placed without requiring a reference to an existing
* JTextPane. This method may not be incredibly practical, but it does
* form a solution.
*/
jp.getCaret().setDot(offs+1);
}
}