【问题标题】:Java HTMLDocument (insertAfterEnd, insertAfterStart, insertBeforeEnd, insertBeforeStart) not working?Java HTMLDocument(insertAfterEnd、insertAfterStart、insertBeforeEnd、insertBeforeStart)不起作用?
【发布时间】:2012-01-03 02:23:39
【问题描述】:

我有一个JEditorPane,它显示以编程方式(在运行时)生成的 HTML。 到目前为止,当我添加“行”时,我正在字符串缓冲区中重新创建整个 HTML 文本,然后将其传递给 JEditorPane.setText 方法。

现在创建的 HTML 已经变得非常大(可以达到几 MB),我只需在末尾添加我的新行,而不是重新生成所有 HTML 文本。

我尝试在末尾附加的原因是避免 Swing(或套件?)不得不再次渲染/解析整个文本。因为即使不是在 EDT 中而是在另一个 swingworker 线程中执行 HTML 生成,“渲染”也需要很长时间。或者最好是有一个显示渲染进度的进度条,这是不可能的(是吗?)。

所以我的想法是简单地追加到最后,但如果你有更好的想法,欢迎!

由于我的文本是在 HTML 表格中格式化的,因此我想将我的新文本附加到该表格的末尾。为此,我尝试使用HTMLDocumentinsertBeforeEnd,但即使我尝试了很多解决方案,我也无法让它工作。请注意,我只有“table”标签。

这是我的代码的一部分

JEditorPane jep = new JEditorPane();
HTMLEditorKit kit = new HTMLEditorKit();
HTMLDocument doc = new HTMLDocument();

jep.setEditorKit(kit);
jep.setDocument(doc);

//setting dummy text within a HTML table
jep.setText("<table><tr><td>A line of text</td></tr><tr><td>Another line of text</td></tr></table>");

现在在表格末尾添加一些文本

//getting the Table Element
Element e = doc.getElement(doc.getDefaultRootElement(), StyleConstants.NameAttribute, HTML.Tag.TABLE);

请注意,似乎可以正确找到该元素,因为System.out.println(e.getName()) 给出了“table”

现在

//inserting text at the end of the table
try {
        doc.insertBeforeEnd(e, "<tr><td>A New Line</td></tr>");
    } catch (BadLocationException ex) {
        System.out.println(ex);
    } catch (IOException ex) {
        System.out.println(ex);
    }

向我提出了一个例外:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: No HTMLEditorKit.Parser
at javax.swing.text.html.HTMLDocument.verifyParser(HTMLDocument.java:1500)
at javax.swing.text.html.HTMLDocument.insertBeforeEnd(HTMLDocument.java:1248)
...

编辑

我已经开始了一个关于后续问题的新问题,这是链接:

https://stackoverflow.com/questions/9659209/jeditorpane-htmldocument-different-rendering-how-why

尽管@JoopEggen 的回答一切正常,但字体渲染并不相同,我不明白为什么。在我看来,这里发布的问题与我在另一个问题(上面给出的链接)中提出的问题不同。但在我的情况下,这是对这个的一些跟进。

因为有些人可能会遇到同样的问题,所以我设置了这个 EDIT 以将您指向相应的线程。

【问题讨论】:

    标签: java swing jtextpane jeditorpane dom


    【解决方案1】:
    private HTMLDocument doc;
    ...
    JTextPane jep = jTextPane1;
    jep.setContentType("text/html");
    jep.setText("<html><table><tr><td>A line of text</td></tr><tr><td>Another line of text</td></tr></table>");
    doc = (HTMLDocument)jep.getStyledDocument();
    

    后跟 setText 的内容类型会安装 EditorKit 并确定文档。出于这个原因,之后使用 StyledDocument。 setText("...") 再次确保采用 HTML。 (您可以使用带有“Hello!!!”的 JLabel 或 JButton。

    JTextPane 比 JEditorPane 更高级(奇怪的命名)。它提供了 StyledDocument,您可以通过它做更多事情。

    其他都还好。

    【讨论】:

    • +1 setText() 实际上可以重新创建文档实例。检查 getDocument() 是否返回相同的。如果不使用最新的文档实例。
    • 感谢你们俩。我也理解您的建议,即 JTextPane 比 JEditorPane 更“高级”。我这样说是因为根据您的解释,我删除了“jep.setDocument(doc)”并添加了“doc = (HTMLDocument)jep.getDocument();”在 setText 之后,一切正常。非常感谢。但是,我需要一些进一步的信息。我需要一个非常快速的应用程序,这就是我使用 JEditorPane 而不是 JTextPane 的原因,因为据我了解,JEditorPane 的“开销”比 JTextPane 少。你同意这一点还是我应该切换到 JTextPane(更“高级”)?
    • (抱歉回复晚了。)没有经验。我发现源代码的结构不是很好。尽管人们可能不会抱怨从 Java 开始就如此复杂:编辑 HTML 等等。
    • 非常感谢。这篇文章节省了时间。在过去的三天里,我一直在努力解决同样的问题。我正在通过 setText () 重新设置文档模型,但通过较早的调用 getDocument () 对文档的引用已过时。在 setText () 之后删除 getDocument () 并用 getStyledDocument () 替换它就可以了!
    猜你喜欢
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 2014-11-23
    • 2017-08-26
    • 2016-08-28
    • 2012-07-21
    相关资源
    最近更新 更多