I have a JTextPane
which contains a string of XML characters, and I wish to change the colour of XML opening tags; to do this I use a regex to find the opening tags, then set the character attribute of the relevant text indexes to the chosen color. This can be seen in the following code:
import java.awt.*;
import java.util.regex.*;
import javax.swing.*;
import javax.swing.text.*;
public class Test {
String nLine = java.lang.System.getProperty("line.separator");
String xmlString = "<ROOT>" + nLine + " <TAG>Tag Content</TAG>" + nLine + " <TAG>Tag Content</TAG>" + nLine + " <TAG>Tag Content</TAG>" + nLine + "</ROOT>";
public Test(){
JTextPane XMLTextPane = new XMLTextPane();
JScrollPane pane = new JScrollPane(XMLTextPane);
pane.setPreferredSize(new Dimension(500,100));
JOptionPane.showConfirmDialog(null, pane);
}
class XMLTextPane extends JTextPane{
public XMLTextPane(){
super.setText(xmlString);
StyleContext context = new StyleContext();
Style openTagStyle = context.addStyle("Open Tag", null);
openTagStyle.addAttribute(StyleConstants.Foreground, Color.BLUE);
StyledDocument sdocument = this.getStyledDocument();
Pattern pattern = Pattern.compile("<([a-z]|[A-Z])+");
Matcher matcher = pattern.matcher(super.getText());
while (matcher.find()) {
sdocument.setCharacterAttributes(matcher.start(), matcher.group().length() , openTagStyle, true);
}
}
}
public static void main(String[] args){
new Test();
}
}
The problem however is that Matcher.start()
and StyledDocument.setCharacterAttributes()
appear to increment differently (It seems as though StyledDocument
ignores newline characters), thus causing the coloured text to stagger.
The issue is not with the regex itself, as a System.out.println(matcher.group());
in the while loop reveals the following correct output:
<ROOT
<TAG
<TAG
<TAG
Is there a way to force Matcher.start()
and StyledDocument.setCharacterAttributes()
to increment consistently, or will I have to implement a new line counter?
EDIT: As Schlagi suggested, replacing all \r\n
with \n
does work, however I worry that this makes the code a little confusing and difficult to maintain. Other suggestions are welcome!
I do not know why the JTextPane do it wrong. It could be, that in the styledocument think, that "\r\n"
is only one character. Do not asked why.
When you change the line
String nLine = java.lang.System.getProperty("line.separator");
to
String nLine = "\n";
it works.
JTextPane only need a "\n"
for a newline on every OS