javaregexcounterjtextpanestyleddocument

Issue with JTextPane and regex


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.

enter image description here

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!


Solution

  • 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