关于Java:如何从JtextPane获取样式?

How to get style from JtextPane?

我有一个带有格式化文本的JtextPane。我需要复制完整的样式和属性
从此文本传输到另一个JtextPane。是否有示例或代码段
看看它是如何工作的?

好吧,这是我找到的代码,我做了一些更改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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() {
    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!\
"
);

    //set color = red
    attribute = red;
    append1("Hello world! Hello Stackoverflow\
"
);        

    //set color = black
    attribute = black;
    append1("the text is black again\
"
);    

    StyledDocument styledDocument = textPane1.getStyledDocument();

    textPane2 = new JTextPane();
    textPane2.setEditorKit(new StyledEditorKit());
    doc2 = textPane2.getDocument();
    String text = textPane1.getText();
    append2(text);

    //transfer format data of text in frame1 to frame2
    int docLength = doc1.getLength();
    Element element;        
    AttributeSet attribSet;
    for(int i=0;i<docLength;i++) {            
        element = styledDocument.getCharacterElement(i);            
        attribSet = element.getAttributes();            
        StyleConstants.setForeground(red, Color.red);
    }

    createFrames();        
}

private void append1(String text){
    try {
        doc1.insertString(doc1.getLength(), text, attribute);
    } catch (BadLocationException ex) {
        ex.printStackTrace();
    }
}

private void append2(String text) {
    try {
        doc2.insertString(doc2.getLength(), text, attribute);
    } 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[]) {
    new Main();    
}
}

我还想将格式样式和属性传输到第二帧。


我已经解决了。

enter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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!\
"
);

    //set color = red
    attribute = red;
    append1("Hello world! Hello Stackoverflow\
"
);        

    //set color = black
    attribute = black;
    append1("the text is black again\
"
);    


    //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();    
}
}


我想对该解决方案进行一些改进。可以使用getParagraphElement(int pos)而不是每个单个字符来捕获具有相同样式的文本。第一个元素在位置0处开始,然后在下一个元素处:element.getEndOffset()1。

但是我们必须遍历子元素树以获取所有字符属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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!\
"
);
    append(doc1, red,  "Hello world! Hello Stackoverflow\
"
);        
    append(doc1, blue, "Hello");        
    append(doc1, red,  "Stackoverflow\
"
);        
    append(doc1, black,"the text is black again\
"
);    

    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();
  }
}