I have a JtextPane with formatted text. I need to copy the complete style and attributes from this text to transfer it to another JtextPane. Is there an example or code snippet
I'd like to add some improvements to this solution. The texts with the same style can be caught by getParagraphElement(int pos) instead of each single character. The first element starts at pos 0, followed by the next at: element.getEndOffset() + 1.
But we have to traverse down the tree of sub elements to get all the character attributes.
package demo;
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class TextPaneDemo {
private JTextPane textPane1;
private JTextPane textPane2;
private StyledDocument doc1;
private StyledDocument doc2;
Private JFrame frame1;
private JFrame frame2;
public TextPaneDemo () {
MutableAttributeSet black = new SimpleAttributeSet();
StyleConstants.setForeground(black, Color.black);
MutableAttributeSet red = new SimpleAttributeSet();
StyleConstants.setForeground(red, Color.red);
MutableAttributeSet blue = new SimpleAttributeSet();
StyleConstants.setForeground(blue, Color.blue);
StyleConstants.setBold(blue, true);
textPane1 = new JTextPane();
textPane1.setEditorKit(new StyledEditorKit());
doc1 = textPane1.getStyledDocument();
textPane2 = new JTextPane();
textPane2.setEditorKit(new StyledEditorKit());
doc2 = textPane2.getStyledDocument();
createFrames();
append(doc1, black, "This is a Test!\n");
append(doc1, red, "Hello world! Hello Stackoverflow\n");
append(doc1, blue, "Hello ");
append(doc1, red, "Stackoverflow\n");
append(doc1, black, "the text is black again\n");
copyDoc (doc1, doc1.getParagraphElement(0), doc2);
}
private static void append(StyledDocument doc, AttributeSet style, String text) {
try {
doc.insertString(doc.getLength(), text, style);
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
private static int copyDoc(StyledDocument doc1, Element elem, StyledDocument doc2) {
int pos = elem.getStartOffset();
while( pos < doc1.getLength()) {
Element element = doc1.getParagraphElement(pos);
pos = copyElem(doc1, element, doc2);
}
return pos;
}
private static int copyElem(StyledDocument doc1, Element elem, StyledDocument doc2) {
int pos = elem.getStartOffset();
if (elem.getElementCount() <= 1) {
int length = elem.getEndOffset() - elem.getStartOffset();
AttributeSet attribSet = elem.getElementCount() == 0 ?
elem.getAttributes() :
elem.getElement(0).getAttributes();
try {
String text = doc1.getText(elem.getStartOffset(), length);
append(doc2, attribSet, text);
} catch(BadLocationException e) { }
pos = elem.getEndOffset();
} else {
for (int sub = 0; sub < elem.getElementCount(); sub++) {
Element sElem = elem.getElement(sub);
pos = copyElem(doc1, sElem, doc2);
}
pos = elem.getEndOffset();
}
return pos;
}
private void createFrames() {
frame1 = new JFrame("frame 1");
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setSize(400, 300);
frame1.setLocationRelativeTo(null);
frame1.getContentPane().add(new JScrollPane(textPane1), BorderLayout.CENTER);
frame1.setVisible(true);
frame2 = new JFrame("frame 2");
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.setSize(400, 300);
frame2.setLocation(frame1.getLocation().x + frame1.getWidth(), frame1.getLocation().y);
frame2.getContentPane().add(new JScrollPane(textPane2), BorderLayout.CENTER);
frame2.setVisible(true);
}
public static void main(String args[]) {
new TextPaneDemo();
}
}
I've solved it.
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class Main {
private JTextPane textPane1;
private JTextPane textPane2;
private Document doc1;
private Document doc2;
private JFrame frame1;
private JFrame frame2;
private MutableAttributeSet black;
private MutableAttributeSet red;
private AttributeSet attribute;
public Main() throws BadLocationException {
textPane1 = new JTextPane();
black = new SimpleAttributeSet();
red = new SimpleAttributeSet();
StyleConstants.setForeground(black, Color.black);
StyleConstants.setForeground(red, Color.red);
textPane1.setEditorKit(new StyledEditorKit());
doc1 = textPane1.getDocument();
append1("This is a Test!\n");
//set color = red
attribute = red;
append1("Hello world! Hello Stackoverflow\n");
//set color = black
attribute = black;
append1("the text is black again\n");
//IMPORTANT PART: attribute of each character from the styled text will
//be transfered to the second textpanel
StyledDocument styledDocument = textPane1.getStyledDocument();
Element element;
textPane2 = new JTextPane();
textPane2.setEditorKit(new StyledEditorKit());
doc2 = textPane2.getDocument();
for(int i=0; i<styledDocument.getLength();i++) {
element = styledDocument.getCharacterElement(i);
AttributeSet attributeNew = element.getAttributes();
System.out.println(i);
append2(styledDocument.getText(i, 1), attributeNew);
}
createFrames();
}
private void append1(String text){
try {
doc1.insertString(doc1.getLength(), text, attribute);
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
private void append2(String text, AttributeSet attributeNew) {
try {
doc2.insertString(doc2.getLength(), text, attributeNew);
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
private void createFrames() {
frame1 = new JFrame("frame 1");
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setSize(400, 300);
frame1.setLocationRelativeTo(null);
frame1.getContentPane().add(new JScrollPane(textPane1), BorderLayout.CENTER);
frame1.setVisible(true);
frame2 = new JFrame("frame 2");
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.setSize(400, 300);
frame2.setLocation(300,0);
frame2.getContentPane().add(new JScrollPane(textPane2), BorderLayout.CENTER);
frame2.setVisible(true);
}
public static void main(String args[]) throws BadLocationException {
new Main();
}
}