Sam Barnum
Sam Barnum

Reputation: 10714

HTML JTextPane newline support

I'm using a JTextPane to edit HTML. When I enter newlines in the GUI component and call getText() on the JTextPane, I get a string with newline characters. If I then create a new JTextPane and pass that same text in, the newlines are ignored.

Why doesn't JTextPane insert a <br> tag when a newline is entered? Is there a good workaround for this?

    JTextPane test = new JTextPane();
    test.setPreferredSize(new Dimension(300, 300));
    test.setContentType("text/html");
    test.setText("Try entering some newline characters.");
    JOptionPane.showMessageDialog(null, test);
    String testText = test.getText();
    System.out.println("Got text: " + testText);
    // try again
    test.setText(testText);
    JOptionPane.showMessageDialog(null, test);
    testText = test.getText();
    System.out.println("Got text: " + testText);        

Sample output:

<html>
  <head>

  </head>
  <body>
    Try entering some newline characters.
What gives?
  </body>
</html>

I realize I could convert newlines to HTML line breaks before calling setText, but that would convert the newlines after the HTML and BODY tags as well, and seems dumb.

Upvotes: 3

Views: 8414

Answers (3)

Sam Barnum
Sam Barnum

Reputation: 10714

I've resolved this, the problem was the plain text I was passing in in setText. If I take out the call to setText, the result of JTextPane.getText() is nicely formatted HTML with line breaks correctly encoded.

I believe when I call JTextPane.setText("Try entering some newline characters") it sets the HTMLDocument.documentProperties.__EndOfLine__ to "\n". This document property constant is defined here.

The solution is to make sure you wrap your text in <p> tags when passing it to the JTextPane.setText() method (note, the style attribute is used for any subsequent paragraphs):

textPane1.setText("<p style=\"margin-top: 0\">Try entering some newline characters</p>");

Or, after you pass in plain text, replace the EndOfLineStringProperty (this is more of a hack, I wouldn't recommend it):

textPane1.getDocument().putProperty(DefaultEditorKit.EndOfLineStringProperty, "<br/>\n")

Upvotes: 8

Lund Wolfe
Lund Wolfe

Reputation: 319

I struggled with this one for half a day. This is still broken in Java 7. The problem is keeping the new line entered by the user into the JEditorPane (for HTML content type). I was only able to retain the new line in HTML when I added a marker key, "\r", at the user's entered "\n" (still need "\n" to display new line in editor) and then replaced that with a "\n<br/>" when I pulled the whole content out and placed in a different JEditorPane or whatever as desired HTML. I only tested this on Windows.

((AbstractDocument) jEditorPane.getDocument()).setDocumentFilter(new HtmlLineBreakDocumentFilter());

// appears to only affect user keystrokes - not getText() and setText() as claimed
public class HtmlLineBreakDocumentFilter extends DocumentFilter
{
    public void insertString(DocumentFilter.FilterBypass fb, int offs, String str, AttributeSet a)
                        throws BadLocationException
    {
        super.insertString(fb, offs, str.replaceAll("\n", "\n\r"), a); // works
    }

    public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a)
        throws BadLocationException
    {
        super.replace(fb, offs, length, str.replaceAll("\n", "\n\r"), a); // works
    }
}


String str = jEditorPane.getText().replaceAll("\r", "<br/>"); // works
jEditorPane2.setText(str);

Upvotes: 0

Jeff Storey
Jeff Storey

Reputation: 57192

It looks like the HTMLWriter class eats the new line and doesn't read it or translate it to HTML (see line 483 in HTMLWriter). I don't see an easy way around this since it appears to be hard coded to be checking for '\n.' You might be able to set the DefaultEditorKit.EndOfLineStringProperty property of the JTextPane's document (via getDocument().putProperty) to <br> and then override setText to replace "\n" with <br>. Though that will do what you suggested and add breaks between html, head, and body tags as well, so you might want to do the replacement only in the body tags. It doesn't appear there is a very straight forward way to do this.

Upvotes: 0

Related Questions