从JTextPane获取html - 缺少内容文本

时间:2013-10-09 03:01:44

标签: java html swing file-io jtextpane

我正在尝试从JTextPane获取html格式的内容。

问题是,当我插入带有指定AttributeSet的文本时,尝试将其写入文件时不会输出内容文本,但样式是。

我不确定这是否与我如何插入文本或我是如何尝试将其写入文件有关。

以下是一个例子:

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import java.awt.BorderLayout;
import java.io.*;
import java.awt.Color;

public class SOExample extends JFrame
{
    public static void main (String[] args)
    {
        SwingUtilities.invokeLater(
            new Runnable()
            {
                @Override
                public void run()
                {
                    SOExample aFrame = new SOExample();
                    aFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    aFrame.setVisible(true);
                }
            }
        );
    }

    public SOExample()
    {
        initComponents();
        addText("This is my plain text", null);

        SimpleAttributeSet BOLD = new SimpleAttributeSet();
        StyleConstants.setBold(BOLD, true);
        StyleConstants.setForeground(BOLD, Color.BLUE);
        addText("This is my BLUE BOLD text",BOLD);

        outputHTMLfile();
    }

    private void initComponents()
    {
        this.setBounds(300,300,300,300);
        jtp = new JTextPane();
        jtp.setContentType("text/html");
        jsp = new JScrollPane();
        JPanel jp = new JPanel(new BorderLayout());
        jp.add(jtp);
        jsp.add(jp);
        jsp.setViewportView(jp);
        this.add(jsp, BorderLayout.CENTER);
    }

    private void addText(String text, SimpleAttributeSet attr)
    {
        try
        {
            HTMLDocument doc = (HTMLDocument)jtp.getDocument();
            doc.insertString(doc.getLength(), text +"\n", attr);
        }
        catch (BadLocationException blex)
        {
            blex.printStackTrace();
        }
    }

    private void outputHTMLfile()
    {
        File f = new File("C:\\Temp", "TestFile.html");
        try
        {
            BufferedOutputStream br = new BufferedOutputStream(new FileOutputStream(f));
            HTMLEditorKit kit = new HTMLEditorKit();
            kit.write(br, (HTMLDocument)jtp.getDocument(),  0, ((HTMLDocument)jtp.getDocument()).getLength() );
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }   
    }

    private JTextPane jtp;
    private JScrollPane jsp;
    }

这将为我提供输出文件,其中包含html,如

 <html>
   <head>

   </head>
   <body>
     <p style="margin-top: 0">
       This is my plain text
     </p>
     <p style="margin-top: 0">
       <b><font color="#0000ff"><p>
 </font></b>    </p>
   </body>
 </html>

正如您所看到的,文本"This is my BLUE BOLD text"缺少,但它会在框架中正确显示。

我也尝试将jtp.getText()直接写入文件并获得相同的结果。

1 个答案:

答案 0 :(得分:2)

当我测试你的代码时,我发现了一些奇怪的东西。如果仔细查看JTextPane上的最后一个字符串(这是我的蓝色文本),虽然它以粗体显示,但它与前一个文本的字体不完全相同。

Bold without fix

这是一个明确的迹象,表明某些属性已经丢失。另请注意,插入该字符串(上面发布的字符串)后生成的HTML缺少</p>标记:在字体标记后面打开一个新段落。再一次,某些东西已经丢失了。

那么,这里发生了什么?好吧,当您将属性传递给insertString方法时,这些将覆盖任何已存在的属性。您需要做的是,在插入之前,将这些属性与新的粗体和颜色属性合并。实际上,您必须稍微更改构造函数的代码:

public SOExample() {
    initComponents();
    addText("This is my plain text", null);

    //Retrieve existing attributes.
    SimpleAttributeSet previousAttribs = new SimpleAttributeSet
                                             (jtp.getInputAttributes()
                                                 .copyAttributes());

    SimpleAttributeSet BOLD = new SimpleAttributeSet();
    StyleConstants.setBold (BOLD, true);
    StyleConstants.setForeground (BOLD, Color.BLUE);

    //Merge new attributes with existing ones.    
    previousAttribs.addAttributes (BOLD);

    //Insert the string and apply merged attributes.
    addText ("This is my BLUE BOLD text", previousAttribs);

    outputHTMLfile();

}

bold with fix

看到字体的差异?对于代码中的getInputAttributes()coppyAttributes(),它提供了将在任何后续插入中使用的当前属性集。这几乎是我们所需要的。

如果尚未插入文本,您可能想知道可能存在哪些属性。简而言之,文本中仅文本的每个元素都将由一个名为 content 的特殊内部“标记”标识。此标记存储为属性。正是这种属性的丧失正在造成严重破坏。

希望这有帮助!