Word wrap in a JEditorPane

A very simple thing I found out today, despite lots of searching around!

I once had a professor who stated that:

A text editor is something so very personal, that everyone should write their own.

Of course I’ve always found vim a perfectly good text editor, but for my Swing projects it’s hard to embed it, so I have indeed written my own text editor that allows a user to edit documents and add hyperlinks and media to them.

public class TextEditor extends javax.swing.JEditorPane {

To display all these things I use HTMLEditorKit, but I found that word wrap didn’t work as expected. Word wrap means that words that would normally cross the right margin, are placed entirely on the next line.

When the previous version of my TextEditor object first displayed the text, almost all of the words at the end of all the lines would break off just before the last character before the right edge of the editor pane. Only when the user placed the caret somewhere in the same paragraph and then pressed the Enter key, thereby splitting the paragraph in two, it would do the word wrapping properly, but only for that paragraph. So when typing in a text at first, word wrapping would work correctly, but reading a previously entered text was therefore very inconvenient.

To get word wrapping to work properly, I Googled around a lot, but subsequent searches didn’t reveal anything useful. Most sites stated that JEditorPane defaults to word wrap anyway, so I became only more puzzled. At some point I found myself attempting things like sub classing HTMLWriter, but I actually felt I was on the wrong track.

And I was. At some point, scrolling through my code, I found this bit:

HTMLDocument doc = (HTMLDocument)this.getDocument();
StyleSheet ss = doc.getStyleSheet();
ss.addRule("h1, h2, h3, h4, h5 { font-family: sans-serif }");
ss.addRule("h1 { font-size: 105% }");
ss.addRule("h2 { font-size: 103% }");
ss.addRule("h3 { font-size: 102% }");
ss.addRule("h4 { font-size: 101% }");
ss.addRule("h5 { font-size: 100% }");
ss.addRule("p { margin-top: 0 }");
ss.addRule("p { margin-bottom: 0 }");
ss.addRule("p { text-indent: 10px }");

And then it became clear: I shouldn’t try to solve this in Java, but in CSS.

I added this line:

ss.addRule("p { word-wrap:break-word }");

And now my text editor correctly displays my text. That was all! No Java code needed, trying to get JEditorPane to implement something it already did, only a single line of CSS. I was thinking in the wrong direction. As are, I get the feeling, many of the people whose questions on the various forums I looked at, that seemed to indicate they were having the same problem.

So I hope this can save somebody a few hours of their time.

Categorised as: howto, java

Comments are closed.