Convert New Line To Pilcrow & Space To Dot In JTextPane’s RTFEditorKit
Posted by admin on
August 16, 2010
An RTF document contains a set of code when you view it in a text editor, codes that only RTF readers and clients can understand. Replacing contents in an RTF document can be tricky. The source code in this post converts new line characters into pilcrow symbols and space characters as dot symbols (see image).
The source code was made by my friend sumpix. To correctly make use of this class, make sure that the RTFEditorKit uses a DefaultStyledDocument as its document. The JTextPane object passed to the RTFEditorKit class will have a KeyListener that when ALT-P is pressed, conversion of new lines and space characters to their intended symbols will occur. Any key pressed after that will convert it back to its original.
To use the class, do this:
JTextPane jTextPane1 = new JTextPane(); MyRTFEditorKit rtfkit = new MyRTFEditorKit(jTextPane1); jTextPane1.setEditorKit(rtfkit); rtfkit.setDocument(new DefaultStyledDocument(new StyleContext()));
Get the customized RTFEditorKit class here.
public class MyRTFEditorKit extends RTFEditorKit {
private JTextPane editorPane;
private MutableAttributeSet attr = null;
private String pilcrow = "\\\\'b6";
private Character space = new Character('\u0020');
private String middleDot = "\\\\'b7";
private String parRegex = "\\\\par";
private String par = "\\par";
private String[] extraSpace = new String[]{"\\ul0\\par", "\\ul0\\sl0\\par"};
private String[] duplicateMiddleDot = new String[]{"\\\\ul", "\\\\ul0", "\\\\b", "\\\\b0", "\\\\i", "\\\\i0"};
private String[] discardthis = new String[]{"\\\\pard"};
private String cfIndex = "\\cf";
private String cfIndexRegex = "\\\\cf";
private String fsIndexRegex = "\\\\fs";
private boolean onPilcrow;
private DefaultStyledDocument doc;
public MyRTFEditorKit(JTextPane editorPane) {
this.editorPane = editorPane;
this.editorPane.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent ke) {
if (ke.isAltDown() && ke.getKeyCode() == KeyEvent.VK_P) {
if (!onPilcrow) {
onPilcrow = true;
} else {
onPilcrow = false;
}
doReplaceSpaceNewLineMarker(false);
return;
}
if (onPilcrow) {
doReplaceSpaceNewLineMarker(true);
}
}
});
}
private String scanOnPilcrowMode(String source) {
int pos = 0;
String text = source;
String a = null;
String b = null;
int ipos = 0;
int kpos = 0;
String ib = null;
String kb = null;
Pattern pPar = Pattern.compile(parRegex);
Matcher mPar = pPar.matcher(text);
text = mPar.replaceAll(pilcrow + parRegex);
pos = text.indexOf(par);
a = text;
b = null;
source = "";
while (pos > 0) {
pos += 4;
b = a.substring(0, pos);
ipos = b.indexOf(cfIndex);
if (ipos > 0) {
ib = b.substring(ipos);
kpos = ib.indexOf(space);
if (kpos > 0) {
kb = ib.substring(kpos + 1);
kb = kb.replaceAll(Character.toString(space), middleDot);
if (b.charAt(0) != '{') {
b = b.substring(0, ipos + kpos + 1);
b = b.replaceAll(Character.toString(space), middleDot) + kb;
} else {
b = b.substring(0, ipos + kpos + 1) + kb;
}
} else {
if (b.charAt(0) != '{') {
b = b.replaceAll(Character.toString(space), middleDot);
}
}
} else {
b = b.replaceAll(Character.toString(space), middleDot);
}
source += b;
a = a.substring(pos);
pos = a.indexOf(par);
if (pos == -1 && !a.trim().equals("")) {
a += pilcrow.substring(1)+ par;
pos = a.indexOf(par);
}
}
text = scanMiddleDotDuplicate(source);
return text;
}
private String scanNotOnPilcrowMode(String source) {
Pattern pPilcrow = Pattern.compile(pilcrow + parRegex);
Matcher mPilcrow = pPilcrow.matcher(source);
source = mPilcrow.replaceAll(parRegex);
source = scanMiddleDotDuplicate(source);
source = source.replaceAll(middleDot, Character.toString(space));
return source;
}
private String scanMiddleDotDuplicate(String source) {
for (int i = 0; i < duplicateMiddleDot.length; i++) { if (onPilcrow) { source = source.replaceAll(duplicateMiddleDot[i] + middleDot, duplicateMiddleDot[i] + Character.toString(space)); } else { source = source.replaceAll(duplicateMiddleDot[i] + middleDot, duplicateMiddleDot[i] + Character.toString(space) + middleDot); } } String[] cfs = source.split(cfIndexRegex); if (cfs.length > 0) {
for (int i = 0; i < cfs.length; i++) { if (onPilcrow) { source = source.replaceAll((cfIndexRegex) + i + middleDot, (cfIndexRegex + i) + Character.toString(space)); } else { source = source.replaceAll((cfIndexRegex) + i + middleDot, (cfIndexRegex + i) + Character.toString(space) + middleDot); } } } String[] fss = source.split(fsIndexRegex); if (fss.length > 0) {
//test
int fssTemp = 100;
for (int i = 0; i < fssTemp; i++) {
if (onPilcrow) {
source = source.replaceAll((fsIndexRegex) + i + middleDot, (fsIndexRegex + i) + Character.toString(space));
} else {
source = source.replaceAll((fsIndexRegex) + i + middleDot, (fsIndexRegex + i) + Character.toString(space) + middleDot);
}
}
}
return source;
}
private String scanExtraSpace(String source) {
for (int i = 0; i < extraSpace.length; i++) { int pos = source.indexOf(extraSpace[i]); if (pos > 0) {
source = source.substring(0, pos);
}
}
return source;
}
private String scanDiscardItems(String source) {
for (int i = 0; i < discardthis.length; i++) {
Pattern p = Pattern.compile(discardthis[i]);
Matcher m = p.matcher(source);
source = m.replaceAll("");
}
return source;
}
private String getDocumentString() throws IOException, BadLocationException {
ByteArrayOutputStream str = new ByteArrayOutputStream();
write(str, doc, 0, doc.getLength());
return scanDiscardItems(str.toString());
}
public void doReplaceSpaceNewLineMarker(boolean onKeyPressed) {
try {
String text = getDocumentString();
System.out.println("before:" + text + "]");
text = scanExtraSpace(text);
if (onKeyPressed && onPilcrow) {
onPilcrow = false;
}
if (onPilcrow) {
text = scanOnPilcrowMode(text);
} else {
text = scanNotOnPilcrowMode(text);
}
System.out.println("after:" + text);
editorPane.setText(text);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setDefaultStyledDocument(DefaultStyledDocument doc) {
this.doc = doc;
}
}
Donations appreciated. Every little $ helps. Or click Google +1.









