【问题标题】:Getting html from JTextPane - missing content text从 JTextPane 获取 html - 缺少内容文本
【发布时间】:2013-10-16 05:44:56
【问题描述】:

我正在尝试从我的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() 直接写入文件并得到相同的结果。

【问题讨论】:

  • 它“可能”试图在 &lt;html&gt;&lt;/html&gt; 边界之外添加文本,这可能会使编辑无效...
  • 另见相关example
  • 问题在于您在插入之前操作属性的方式。请参阅下面的答案。

标签: java html swing file-io jtextpane


【解决方案1】:

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

这是一个明确的信号,表明某些属性已经丢失。另请注意,插入该字符串(上面发布的那个)后生成的 HTML 缺少&lt;/p&gt; 标签:在字体标签之后立即打开一个新段落。再一次,途中丢失了一些东西。

那么,这里发生了什么?好吧,当您将属性传递给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();

}

看到字体的不同了吗?至于代码中的getInputAttributes().coppyAttributes(),它给出了将在任何后续插入中使用的当前属性集。这正是我们所需要的。

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

希望这会有所帮助!

【讨论】:

  • 注意到不同的字体很好,我什至没有注意到。我想我做的不对,只是不知道它在哪里或是什么。谢谢。
  • @JavaDevil 感谢您的接受。几个月前,我帮助开发了一个名为 ADAPRO 的开源辅助编辑器。自 Java 7 以来,处理所有这些编辑内容的 Swing 类的文档有所改进,但恕我直言,仍然不够好。很多小时都在敲打我的脑袋,试图找到对这种行为的解释。所以,你遇到这个问题是完全可以理解的。再次感谢!
猜你喜欢
  • 2015-01-14
  • 2014-07-22
  • 2012-03-05
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
相关资源
最近更新 更多