模块 java.desktop

类 HTMLDocument

所有已实现的接口:
Serializable , Document , StyledDocument

public class HTMLDocument extends DefaultStyledDocument
模拟 HTML 的文档。该模型的目的是支持浏览和编辑。因此,默认情况下不会完全复制 HTML 文档描述的结构。默认建模的元素结构由类 HTMLDocument.HTMLReader 构建,它实现了解析器期望的 HTMLEditorKit.ParserCallback 协议。要更改结构,可以继承 HTMLReader 并重新实现方法 getReader(int) 以返回新的读取器实现。应查阅 HTMLReader 的文档以了解创建的默认结构的详细信息。目的是使文档无损(尽管复制 HTML 格式可能会导致不同的格式)。

该文档仅对 HTML 建模,并没有尝试在其中存储视图属性。元素由 StyleContext.NameAttribute 属性标识,该属性应始终具有标识元素类型的 HTML.Tag 类型的值。一些元素(例如评论)是合成的。 HTMLFactory 使用此属性来确定要构建哪种视图。

本文档支持增量加载。 TokenThreshold 属性控制在尝试更新文档的元素结构之前缓冲了多少解析。此属性由 EditorKit 设置,以便子类可以禁用它。

Base 属性确定用于解析相对 URL 的 URL。默认情况下,如果属性的值是 URL,这将是 Document.StreamDescriptionProperty。如果遇到 <BASE> 标签,基础将成为该标签指定的 URL。因为base URL是一个属性,当然可以直接设置。

本文档的默认内容存储机制是间隙缓冲区 (GapContent)。可以使用采用 Content 实现的构造函数来提供替代方案。

修改 HTMLDocument

除了 Document 和 StyledDocument 提供的用于改变 HTMLDocument 的方法之外,HTMLDocument 还提供了许多方便的方法。以下方法可用于将 HTML 内容插入现有文档。

以下示例说明如何使用这些方法。每个示例都假定 HTML 文档按以下方式初始化:

 JEditorPane p = new JEditorPane();
 p.setContentType("text/html");
 p.setText("..."); // Document text is provided below.
 HTMLDocument d = (HTMLDocument) p.getDocument();
 

具有以下 HTML 内容:

 <html>
  <head>
   <title>An example HTMLDocument</title>
   <style type="text/css">
    div { background-color: silver; }
    ul { color: blue; }
   </style>
  </head>
  <body>
   <div id="BOX">
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
   </div>
  </body>
 </html>
 

所有修改 HTML 文档的方法都需要一个 Element 。可以使用方法 getElement(Element e, Object attribute, Object value) 从 HTML 文档中获取元素。它以深度优先顺序返回包含具有给定值的指定属性的第一个后代元素。例如,d.getElement(d.getDefaultRootElement(), StyleConstants.NameAttribute, HTML.Tag.P) 返回第一个段落元素。

定位元素的便捷快捷方式是方法 getElement(String) ;返回其 ID 属性与指定值匹配的元素。例如,d.getElement("BOX") 返回 DIV 元素。

getIterator(HTML.Tag t) 方法也可用于查找文档中指定 HTML 标记的所有匹配项。

插入元素

可以使用方法 insertAfterStartinsertBeforeEnd 在任何非叶元素的现有子元素之前或之后插入元素。例如,如果 eDIV 元素,则 d.insertAfterStart(e, "<ul><li>List Item</li></ul>") 会在第一段之前插入列表,而 d.insertBeforeEnd(e, "<ul><li>List Item</li></ul>") 会在最后一段之后插入列表。 DIV 块成为新插入元素的父元素。

可以使用方法 insertBeforeStartinsertAfterEnd 在任何元素之前或之后插入同级元素。例如,如果 eDIV 元素,则 d.insertBeforeStart(e, "<ul><li>List Item</li></ul>") 会在 DIV 元素之前插入列表,而 d.insertAfterEnd(e, "<ul><li>List Item</li></ul>") 会在 DIV 元素之后插入列表。新插入的元素成为 DIV 元素的兄弟元素。

替换元素

可以使用方法 setInnerHTMLsetOuterHTML 替换元素及其所有后代。例如,如果 eDIV 元素,则 d.setInnerHTML(e, "<ul><li>List Item</li></ul>") 会用列表替换所有子段落,而 d.setOuterHTML(e, "<ul><li>List Item</li></ul>") 会替换 DIV 元素本身。在后一种情况下,列表的父元素是 BODY 元素。

概括

下表显示了示例文档和上述各种方法的结果。

以上示例的 HTML 内容
示例 insertAfterStart insertBeforeEnd insertBeforeStart insertAfterEnd setInnerHTML setOuterHTML

第 1 款

第 2 段

  • 项目清单

第 1 款

第 2 段

第 1 款

第 2 段

  • 项目清单
  • 项目清单

第 1 款

第 2 段

第 1 款

第 2 段

  • 项目清单
  • 项目清单
  • 项目清单

Warning: 此类的序列化对象将与未来的 Swing 版本不兼容。当前的序列化支持适用于运行相同版本 Swing 的应用程序之间的短期存储或 RMI。从 1.4 开始,对所有 JavaBeans 的长期存储的支持已添加到 java.beans 包中。请参阅 XMLEncoder

  • 字段详细信息

    • AdditionalComments

      public static final String  AdditionalComments
      文档属性键值。键的值将是一个字符串向量,这些字符串是在正文中找不到的注解。
      参见:
  • 构造方法详细信息

    • HTMLDocument

      public HTMLDocument()
      使用默认缓冲区大小和默认 StyleSheet 构造 HTML 文档。这是构造函数 HTMLDocument(Content, StyleSheet) 的便捷方法。
    • HTMLDocument

      public HTMLDocument(StyleSheet  styles)
      构造具有默认内容存储实现和指定样式/属性存储机制的 HTML 文档。这是构造函数 HTMLDocument(Content, StyleSheet) 的便捷方法。
      参数:
      styles - 样式
    • HTMLDocument

      public HTMLDocument(AbstractDocument.Content  c, StyleSheet  styles)
      使用给定的内容存储实现和给定的样式/属性存储机制构造一个 HTML 文档。
      参数:
      c - 内容容器
      styles - 样式
  • 方法详情

    • getReader

      public HTMLEditorKit.ParserCallback  getReader(int pos)
      获取读取器供解析器在使用 HTML 加载文档时使用。这是为了返回 HTMLDocument.HTMLReader 的实例而实现的。如果需要,子类可以重新实现此方法以更改文档的结构化方式。 (例如,处理自定义标签,或在结构上表示字符样式元素。)
      参数:
      pos - 起始位置
      返回:
      解析器用来加载文档的阅读器
    • getReader

      public HTMLEditorKit.ParserCallback  getReader(int pos, int popDepth, int pushDepth, HTML.Tag  insertTag)
      返回解析器的读取器以使用 HTML 加载文档。这是为了返回 HTMLDocument.HTMLReader 的实例而实现的。如果需要,子类可以重新实现此方法以更改文档的结构化方式。 (例如,处理自定义标签,或在结构上表示字符样式元素。)

      这是 getReader(int, int, int, HTML.Tag, TRUE) 的便捷方法。

      参数:
      pos - 起始位置
      popDepth - 插入前要生成的 ElementSpec.EndTagTypes 的数量
      pushDepth - 方向为 ElementSpec.JoinNextDirectionElementSpec.StartTagTypes 的数量应在插入之前生成,但在生成结束标记之后
      insertTag - 开始插入文档的第一个标签
      返回:
      解析器用来加载文档的阅读器
    • getBase

      public URL  getBase()
      返回用于解析相对 URL 的位置。默认情况下,如果文档是从 URL 加载的,这将是文档的 URL。如果找到并可以解析基本标记,则将其用作基本位置。
      返回:
      基地位置
    • setBase

      public void setBase(URL  u)
      设置用于解析相对 URL 的位置。默认情况下,如果文档是从 URL 加载的,这将是文档的 URL。如果找到并可以解析基本标记,则将其用作基本位置。

      这还将 StyleSheet 的基数设置为 u 以及文档的基数。

      参数:
      u - 所需的基本 URL
    • insert

      protected void insert(int offset, DefaultStyledDocument.ElementSpec [] data) throws BadLocationException
      批量插入新元素。这就是在文档中创建元素的方式。解析确定需要什么结构,并将规范创建为一组描述编辑的标记,同时使文档不受写锁定影响。然后,读取器可以突发调用此方法以获取较短持续时间的写锁定(即,当文档实际被更改时)。
      重写:
      insert 在类 DefaultStyledDocument
      参数:
      offset - 起始偏移量
      data - 元素数据
      抛出:
      BadLocationException - 如果给定位置不代表相关文档中的有效位置。
    • insertUpdate

      protected void insertUpdate(AbstractDocument.DefaultDocumentEvent  chng, AttributeSet  attr)
      作为文本插入的结果更新文档结构。这将在写锁内发生。此实现简单地解析插入的内容以换行并为元素缓冲区构建一组指令。
      重写:
      insertUpdate 在类 DefaultStyledDocument
      参数:
      chng - 文档更改的描述
      attr - 属性
    • create

      protected void create(DefaultStyledDocument.ElementSpec [] data)
      用给定的元素规范替换文档的内容。如果加载以突发方式完成,则在插入之前调用。这是在一次性加载整个文档时调用的唯一方法。
      重写:
      create 在类 DefaultStyledDocument
      参数:
      data - 文档的新内容
    • setParagraphAttributes

      public void setParagraphAttributes(int offset, int length, AttributeSet  s, boolean replace)
      设置段落的属性。

      此方法是线程安全的,尽管大多数 Swing 方法不是。请参阅 Swing 中的并发 了解更多信息。

      指定者:
      setParagraphAttributes 在接口 StyledDocument
      重写:
      setParagraphAttributes 在类 DefaultStyledDocument
      参数:
      offset - 段落中的偏移量(必须至少为 0)
      length - 受影响的字符数(必须至少为 0)
      s - 属性
      replace - 是否替换现有属性,或合并它们
    • getStyleSheet

      public StyleSheet  getStyleSheet()
      使用在 HTML 文档本身中指定的特定于文档的显示规则 (CSS) 获取 StyleSheet
      返回:
      StyleSheet
    • getIterator

      public HTMLDocument.Iterator  getIterator(HTML.Tag  t)
      获取指定 HTML 标记的迭代器。这可用于迭代包含的锚点集或迭代输入元素。
      参数:
      t - 请求的 HTML.Tag
      返回:
      给定 HTML 标记的 Iterator
      参见:
    • createLeafElement

      protected Element  createLeafElement(Element  parent, AttributeSet  a, int p0, int p1)
      创建一个直接表示文本的文档叶元素(没有任何子元素)。这是为了返回 HTMLDocument.RunElement 类型的元素而实现的。
      重写:
      createLeafElement 在类 AbstractDocument
      参数:
      parent - 父元素
      a - 元素的属性
      p0 - 范围的开始(必须至少为 0)
      p1 - 范围的结尾(必须至少为 p0)
      返回:
      新元素
    • createBranchElement

      protected Element  createBranchElement(Element  parent, AttributeSet  a)
      创建一个文档分支元素,它可以包含其他元素。这是为了返回 HTMLDocument.BlockElement 类型的元素而实现的。
      重写:
      createBranchElement 在类 AbstractDocument
      参数:
      parent - 父元素
      a - 属性
      返回:
      元素
    • createDefaultRoot

      protected AbstractDocument.AbstractElement  createDefaultRoot()
      创建用于表示默认文档结构的根元素。
      重写:
      createDefaultRoot 在类 DefaultStyledDocument
      返回:
      元素基础
    • setTokenThreshold

      public void setTokenThreshold(int n)
      在尝试更新文档元素结构之前设置要缓冲的标记数。
      参数:
      n - 要缓冲的令牌数
    • getTokenThreshold

      public int getTokenThreshold()
      在尝试更新文档元素结构之前获取要缓冲的标记数。默认值为 Integer.MAX_VALUE
      返回:
      要缓冲的令牌数
    • setPreservesUnknownTags

      public void setPreservesUnknownTags(boolean preservesTags)
      确定解析器如何处理未知标记。如果设置为 true,未知标签将放入模型中,否则将被丢弃。
      参数:
      preservesTags - 如果模型中应保存未知标签则为真,否则标签将被丢弃
      参见:
    • getPreservesUnknownTags

      public boolean getPreservesUnknownTags()
      返回解析器在遇到未知标记时观察到的行为。
      返回:
      如果在解析时要保留未知标记,则为 true
      参见:
    • processHTMLFrameHyperlinkEvent

      public void processHTMLFrameHyperlinkEvent(HTMLFrameHyperlinkEvent  e)
      由 HTML 框架中的文档生成的进程 HyperlinkEventsHyperlinkEvent 类型,如参数所示,是 HTMLFrameHyperlinkEvent 。除了 HyperlinkEvent 中包含的典型信息外,此事件还包含与发生点击的帧(源元素)和目标名称相对应的元素。目标名称有 4 个可能的值:
      • _自己
      • _parent
      • _顶部
      • 命名框架
      如果目标是 _self,则操作是更改 HTML.Attribute.SRC 属性的值并触发 ChangedUpdate 事件。

      如果目标是 _parent,则它删除父元素,这是一个 <FRAMESET> 元素,并插入一个新的 <FRAME> 元素,并将其 HTML.Attribute.SRC 属性设置为具有等于目标 URL 的值并触发 RemovedUpdateInsertUpdate .

      如果目标是 _top,则此方法不执行任何操作。在框架视图的实现中,即 FrameView ,处理 _top 的处理。鉴于 _top 意味着替换整个文档,因此在它将替换的文档之外处理它是有意义的。

      如果目标是命名框架,则在元素层次结构中搜索名称等于目标的元素,更新其 HTML.Attribute.SRC 属性并触发 ChangedUpdate 事件。

      参数:
      e - 事件
    • setParser

      public void setParser(HTMLEditorKit.Parser  parser)
      设置将 html 插入现有文档的方法使用的解析器,例如 setInnerHTMLsetOuterHTML

      HTMLEditorKit.createDefaultDocument 将为您设置解析器。如果您手动创建 HTMLDocument,请确保相应地设置解析器。

      参数:
      parser - 用于文本插入的解析器
      自从:
      1.3
    • getParser

      public HTMLEditorKit.Parser  getParser()
      返回将 HTML 插入现有文档时使用的解析器。
      返回:
      用于文本插入的解析器
      自从:
      1.3
    • setInnerHTML

      public void setInnerHTML(Element  elem, String  htmlText) throws BadLocationException , IOException
      用指定为 HTML 字符串的内容替换给定元素的子元素。

      这将被视为至少两个事件,n 个插入,然后是一个删除。

      考虑以下结构(elem 参数是粗体).

         <body>
          |
         <div>
         / \
        <p>  <p>
       

      调用 setInnerHTML(elem, "<ul><li>") 会产生以下结构(新元素是穿蓝色衣服).

         <body>
          |
         <div>
           \
           <ul>
            \
            <li>
       

      参数 elem 不能是叶元素,否则会抛出 IllegalArgumentException。如果 elemhtmlText 参数为 null ,则不会对文档进行任何更改。

      为了使其正常工作,文档必须有一个 HTMLEditorKit.Parser 集。如果文档是通过 createDefaultDocument 方法从 HTMLEditorKit 创建的,就会出现这种情况。

      参数:
      elem - 子元素将被替换的分支元素
      htmlText - 要解析并分配给 elem 的字符串
      抛出:
      IllegalArgumentException - 如果 elem 是一片叶子
      IllegalStateException - 如果尚未定义 HTMLEditorKit.Parser
      BadLocationException - 如果由于结构问题无法更换
      IOException - 如果发生 I/O 异常
      自从:
      1.3
    • setOuterHTML

      public void setOuterHTML(Element  elem, String  htmlText) throws BadLocationException , IOException
      用指定为 HTML 字符串的内容替换父元素中的给定元素。

      这将被视为至少两个事件,n 个插入,然后是一个删除。

      替换叶子时,如果需要,这将尝试确保存在换行符。这可能会导致插入一个额外的元素。考虑一下,如果您要用 <img> 替换包含换行符的字符元素,这将创建两个元素,一个用于图像,一个用于换行符。

      如果您尝试替换元素的长度,您很可能会以两个元素结束,例如 setOuterHTML(getCharacterElement (getLength()), "blah") 将在末尾产生两个叶元素,一个代表“blah”,另一个代表结束元素。

      考虑以下结构(elem 参数是粗体).

         <body>
          |
         <div>
         / \
        <p>  <p>
       

      调用 setOuterHTML(elem, "<ul><li>") 会产生以下结构(新元素是穿蓝色衣服).

        <body>
         |
         <ul>
          \
          <li>
       

      如果 elemhtmlText 参数为 null ,则不会对文档进行任何更改。

      为了使其正常工作,文档必须设置 HTMLEditorKit.Parser。如果文档是通过 createDefaultDocument 方法从 HTMLEditorKit 创建的,就会出现这种情况。

      参数:
      elem - 要替换的元素
      htmlText - 要解析和插入的字符串以代替 elem
      抛出:
      IllegalStateException - 如果未设置 HTMLEditorKit.Parser
      BadLocationException - 如果由于结构问题无法更换
      IOException - 如果发生 I/O 异常
      自从:
      1.3
    • insertAfterStart

      public void insertAfterStart(Element  elem, String  htmlText) throws BadLocationException , IOException
      在元素的开头插入指定为字符串的 HTML。

      考虑以下结构(elem 参数是粗体).

         <body>
          |
         <div>
         / \
        <p>  <p>
       

      调用 insertAfterStart(elem, "<ul><li>") 会产生以下结构(新元素是穿蓝色衣服).

          <body>
           |
          <div>
          / | \
        <ul> <p> <p>
         /
       <li>
       

      insertBeforeStart 方法不同,新元素成为指定元素的 children,而不是兄弟元素。

      参数 elem 不能是叶元素,否则会抛出 IllegalArgumentException。如果 elemhtmlText 参数为 null ,则不会对文档进行任何更改。

      为了使其正常工作,文档必须有一个 HTMLEditorKit.Parser 集。如果文档是通过 createDefaultDocument 方法从 HTMLEditorKit 创建的,就会出现这种情况。

      参数:
      elem - 作为新文本根的分支元素
      htmlText - 要解析并分配给 elem 的字符串
      抛出:
      IllegalArgumentException - 如果 elem 是一片叶子
      IllegalStateException - 如果尚未在文档上设置 HTMLEditorKit.Parser
      BadLocationException - 如果由于结构问题无法插入
      IOException - 如果发生 I/O 异常
      自从:
      1.3
    • insertBeforeEnd

      public void insertBeforeEnd(Element  elem, String  htmlText) throws BadLocationException , IOException
      在元素末尾插入指定为字符串的 HTML。

      如果 elem 的子节点是叶子,而 elem.getEndOffset() - 1 处的字符是换行符,这将在换行符之前插入,这样换行符之后就没有文本了。

      考虑以下结构(elem 参数是粗体).

         <body>
          |
         <div>
         / \
        <p>  <p>
       

      调用 insertBeforeEnd(elem, "<ul><li>") 会产生以下结构(新元素是穿蓝色衣服).

          <body>
           |
          <div>
          / | \
         <p> <p> <ul>
              \
              <li>
       

      insertAfterEnd 方法不同,新元素成为指定元素的 children,而不是兄弟元素。

      参数 elem 不能是叶元素,否则会抛出 IllegalArgumentException。如果 elemhtmlText 参数为 null ,则不会对文档进行任何更改。

      为了使其正常工作,文档必须有一个 HTMLEditorKit.Parser 集。如果文档是通过 createDefaultDocument 方法从 HTMLEditorKit 创建的,就会出现这种情况。

      参数:
      elem - 作为新文本根的元素
      htmlText - 要解析并分配给 elem 的字符串
      抛出:
      IllegalArgumentException - 如果 elem 是一片叶子
      IllegalStateException - 如果尚未在文档上设置 HTMLEditorKit.Parser
      BadLocationException - 如果由于结构问题无法插入
      IOException - 如果发生 I/O 异常
      自从:
      1.3
    • insertBeforeStart

      public void insertBeforeStart(Element  elem, String  htmlText) throws BadLocationException , IOException
      在给定元素的开始之前插入指定为字符串的 HTML。

      考虑以下结构(elem 参数是粗体).

         <body>
          |
         <div>
         / \
        <p>  <p>
       

      调用 insertBeforeStart(elem, "<ul><li>") 会产生以下结构(新元素是穿蓝色衣服).

          <body>
           / \
         <ul> <div>
          /  / \
         <li> <p> <p>
       

      insertAfterStart 方法不同,新元素成为指定元素的 siblings,而不是子元素。

      如果 elemhtmlText 参数为 null ,则不会对文档进行任何更改。

      为了使其正常工作,文档必须有一个 HTMLEditorKit.Parser 集。如果文档是通过 createDefaultDocument 方法从 HTMLEditorKit 创建的,就会出现这种情况。

      参数:
      elem - 内容插入之前的元素
      htmlText - 要解析并插入到elem之前的字符串
      抛出:
      IllegalStateException - 如果尚未在文档上设置 HTMLEditorKit.Parser
      BadLocationException - 如果由于结构问题无法插入
      IOException - 如果发生 I/O 异常
      自从:
      1.3
    • insertAfterEnd

      public void insertAfterEnd(Element  elem, String  htmlText) throws BadLocationException , IOException
      在给定元素的末尾之后插入指定为字符串的 HTML。

      考虑以下结构(elem 参数是粗体).

         <body>
          |
         <div>
         / \
        <p>  <p>
       

      调用 insertAfterEnd(elem, "<ul><li>") 会产生以下结构(新元素是穿蓝色衣服).

          <body>
           / \
         <div> <ul>
          / \  \
         <p> <p> <li>
       

      insertBeforeEnd 方法不同,新元素成为指定元素的 siblings,而不是子元素。

      如果 elemhtmlText 参数为 null ,则不会对文档进行任何更改。

      为了使其正常工作,文档必须有一个 HTMLEditorKit.Parser 集。如果文档是通过 createDefaultDocument 方法从 HTMLEditorKit 创建的,就会出现这种情况。

      参数:
      elem - 内容插入后的元素
      htmlText - 在elem之后要解析和插入的字符串
      抛出:
      IllegalStateException - 如果尚未在文档上设置 HTMLEditorKit.Parser
      BadLocationException - 如果由于结构问题无法插入
      IOException - 如果发生 I/O 异常
      自从:
      1.3
    • getElement

      public Element  getElement(String  id)
      返回具有给定 id Attribute 的元素。如果找不到该元素,则返回 null。请注意,此方法适用于 Attributenot一个字符标签。在以下 HTML 片段中:<a id="HelloThere"> 属性是“id”,字符标签是“a”。这是 getElement(RootElement, HTML.Attribute.id, id) 的便捷方法。这不是线程安全的。
      参数:
      id - 代表所需 Attribute 的字符串
      返回:
      具有指定 Attributenull 的元素(如果找不到),或 null(如果 idnull
      自从:
      1.3
      参见:
    • getElement

      public Element  getElement(Element  e, Object  attribute, Object  value)
      返回包含属性的 e 的子元素,值为 valueattribute,如果未找到则返回 null。这不是线程安全的。
      参数:
      e - 搜索开始的根元素
      attribute - 所需的 Attribute
      value - 指定 Attribute 的值
      返回:
      具有指定 Attribute 和指定 value 的元素,如果找不到则为 null
      自从:
      1.3
      参见:
    • fireChangedUpdate

      protected void fireChangedUpdate(DocumentEvent  e)
      通知所有已注册对此事件类型的通知感兴趣的监听。事件实例是使用传递给 fire 方法的参数延迟创建的。
      重写:
      fireChangedUpdate 在类 AbstractDocument
      参数:
      e - 事件
      参见:
    • fireUndoableEditUpdate

      protected void fireUndoableEditUpdate(UndoableEditEvent  e)
      通知所有已注册对此事件类型的通知感兴趣的监听。事件实例是使用传递给 fire 方法的参数延迟创建的。
      重写:
      fireUndoableEditUpdate 在类 AbstractDocument
      参数:
      e - 事件
      参见: