模块 java.desktop

类 AbstractDocument

java.lang.Object
javax.swing.text.AbstractDocument
所有已实现的接口:
Serializable , Document
已知子类:
DefaultStyledDocument , PlainDocument

public abstract class AbstractDocument extends Object implements Document , Serializable
文档接口的实现,作为实现各种文档的基础。这一层策略很少,使用难度也相应增加。

此类为文档实现锁定机制。它允许多个读者或一个作者,并且作者必须等到文档的所有观察者都收到先前更改的通知,然后才能开始对文档进行另一个修改。使用render 方法获取和释放读锁。写锁由改变文档的方法获取,并在方法调用期间保持。通知在产生变更的线程上完成,并且线程在通知期间对文档具有完全读取访问权限,但在通知完成之前,其他读者将被拒之门外。该通知是一个 bean 事件通知,在通知所有监听器之前不允许任何进一步的突变。

任何从此类继承并与具有从 BasicTextUI 派生的外观实现的文本组件结合使用的模型都可以安全地异步更新,因为如果文档的类型为 AbstractDocument,则对视图层次结构的所有访问都由 BasicTextUI 序列化.锁定假定一个独立线程将仅从 DocumentListener 方法访问视图层次结构,并且一次只有一个事件线程处于活动状态。

如果需要并发支持,则有以下附加含义。任何 DocumentListener 实现和任何 UndoListener 实现的代码路径必须是线程安全的,并且如果试图避免死锁则不能访问组件锁。 JComponent 上的 repaintrevalidate 方法是安全的。

AbstractDocument 模拟文档末尾的隐含中断。除其他外,这允许您将插入符号定位在最后一个字符之后。因此,getLength 返回的长度比内容的长度少一。如果您创建自己的内容,请确保将其初始化为具有附加字符。有关这方面的示例,请参阅 StringContent 和 GapContent。另一个含义是模拟隐含结束字符的元素将具有 endOffset == (getLength() + 1)。例如,在 DefaultStyledDocument getParagraphElement(getLength()).getEndOffset() == getLength() + 1 中。

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

  • 字段详细信息

    • listenerList

      protected EventListenerList  listenerList
      文档的事件监听列表。
    • BAD_LOCATION

      protected static final String  BAD_LOCATION
      指示错误位置的错误消息。
      参见:
    • ParagraphElementName

      public static final String  ParagraphElementName
      用于表示段落的元素名称
      参见:
    • ContentElementName

      public static final String  ContentElementName
      用于表示内容的元素名称
      参见:
    • SectionElementName

      public static final String  SectionElementName
      用于保存部分(行/段落)的元素的名称。
      参见:
    • BidiElementName

      public static final String  BidiElementName
      用于保持单向运行的元素名称
      参见:
    • ElementNameAttribute

      public static final String  ElementNameAttribute
      用于指定元素名称的属性名称。
      参见:
  • 构造方法详细信息

    • AbstractDocument

      protected AbstractDocument(AbstractDocument.Content  data)
      构造一个新的 AbstractDocument ,包裹一些指定的内容存储机制。
      参数:
      data - 内容
    • AbstractDocument

      protected AbstractDocument(AbstractDocument.Content  data, AbstractDocument.AttributeContext  context)
      构造一个新的 AbstractDocument ,包裹一些指定的内容存储机制。
      参数:
      data - 内容
      context - 属性上下文
  • 方法详情

    • getDocumentProperties

      public Dictionary <Object ,Object > getDocumentProperties()
      支持管理一组属性。调用者可以使用 documentProperties 字典来使用文档范围的属性来注释文档。
      返回:
      null Dictionary
      参见:
    • setDocumentProperties

      public void setDocumentProperties(Dictionary <Object ,Object > x)
      替换此文档的文档属性字典。
      参数:
      x - 新字典
      参见:
    • fireInsertUpdate

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

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

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

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

      public <T extends EventListener > T[] getListeners(Class <T> listenerType)
      返回当前在本文档中注册为 FooListener 的所有对象的数组。 FooListener 是使用 addFooListener 方法注册的。

      您可以使用类文字指定 listenerType 参数,例如 FooListener.class 。例如,您可以使用以下代码查询文档 d 的文档监听器:

      DocumentListener[] mls = (DocumentListener[])(d.getListeners(DocumentListener.class));
      如果不存在这样的监听器,则此方法返回一个空数组。
      类型参数:
      T - 监听器类型
      参数:
      listenerType - 请求的监听器类型
      返回:
      在此组件上注册为 FooListener 的所有对象的数组,如果没有添加此类监听器,则为空数组
      抛出:
      ClassCastException - 如果 listenerType 没有指定实现 java.util.EventListener 的类或接口
      自从:
      1.3
      参见:
    • getAsynchronousLoadPriority

      public int getAsynchronousLoadPriority()
      获取异步加载优先级。如果小于零,则不应异步加载文档。
      返回:
      异步加载优先级,如果文档不应异步加载则为 -1
    • setAsynchronousLoadPriority

      public void setAsynchronousLoadPriority(int p)
      设置异步加载优先级。
      参数:
      p - 新的异步加载优先级;小于零的值表示不应异步加载文档
    • setDocumentFilter

      public void setDocumentFilter(DocumentFilter  filter)
      设置 DocumentFilterDocumentFilter 传递给 insertremove 以有条件地允许插入/删除文本。 null 值表示不会发生过滤。
      参数:
      filter - 用于约束文本的 DocumentFilter
      自从:
      1.4
      参见:
    • getDocumentFilter

      public DocumentFilter  getDocumentFilter()
      返回负责过滤插入/删除的DocumentFilternull 返回值意味着不会发生过滤。
      返回:
      文档过滤器
      自从:
      1.4
      参见:
    • render

      public void render(Runnable  r)
      如果模型支持异步更新,这允许在存在货币的情况下安全地呈现模型。给定的 runnable 将以允许它在执行 runnable 时安全地读取模型而无需更改的方式执行。 runnable 本身可以not 进行任何更改。

      这是为了在可运行对象执行期间获取读锁。可能有多个runnables同时执行,当有active rendering runnables时,所有的writer都会被阻塞。如果可运行对象抛出异常,它的锁将被安全释放。没有针对永不退出的可运行文件的保护措施,这将有效地使文档在其生命周期内处于锁定状态。

      如果给定的 runnable 尝试在此实现中进行任何更改,则会发生死锁。没有跟踪单个渲染线程来检测这种情况,但是子类可能会产生跟踪它们并抛出错误的开销。

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

      指定者:
      render 在接口 Document
      参数:
      r - 要执行的渲染器
    • getLength

      public int getLength()
      返回数据的长度。这是表示用户数据的内容的字符数。
      指定者:
      getLength 在接口 Document
      返回:
      长度 >= 0
      参见:
    • addDocumentListener

      public void addDocumentListener(DocumentListener  listener)
      添加一个文档监听以通知任何更改。
      指定者:
      addDocumentListener 在接口 Document
      参数:
      listener - 要添加的 DocumentListener
      参见:
    • removeDocumentListener

      public void removeDocumentListener(DocumentListener  listener)
      删除文档监听。
      指定者:
      removeDocumentListener 在接口 Document
      参数:
      listener - 要删除的 DocumentListener
      参见:
    • getDocumentListeners

      public DocumentListener [] getDocumentListeners()
      返回在此文档上注册的所有文档监听的数组。
      返回:
      此文档的所有 DocumentListener s 或一个空数组(如果当前没有注册任何文档监听器)
      自从:
      1.4
      参见:
    • addUndoableEditListener

      public void addUndoableEditListener(UndoableEditListener  listener)
      添加一个撤消监听器以通知任何更改。在 UndoableEdit 上执行的撤消/重做操作将导致触发适当的 DocumentEvent 以保持视图与模型同步。
      指定者:
      addUndoableEditListener 在接口 Document
      参数:
      listener - 要添加的 UndoableEditListener
      参见:
    • removeUndoableEditListener

      public void removeUndoableEditListener(UndoableEditListener  listener)
      删除撤消监听。
      指定者:
      removeUndoableEditListener 在接口 Document
      参数:
      listener - 要删除的 UndoableEditListener
      参见:
    • getUndoableEditListeners

      public UndoableEditListener [] getUndoableEditListeners()
      返回在此文档上注册的所有可撤消编辑监听的数组。
      返回:
      此文档的所有 UndoableEditListener s 或一个空数组,如果当前没有注册可撤消的编辑监听器
      自从:
      1.4
      参见:
    • getProperty

      public final Object  getProperty(Object  key)
      一种查找属性值的便捷方法。它相当于:
       getDocumentProperties().get(key);
       
      指定者:
      getProperty 在接口 Document
      参数:
      key - 非null 属性键
      返回:
      此属性的值或 null
      参见:
    • putProperty

      public final void putProperty(Object  key, Object  value)
      一种存储属性值的便捷方法。它等效于:
       getDocumentProperties().put(key, value);
       
      如果 valuenull 此方法将删除该属性。
      指定者:
      putProperty 在接口 Document
      参数:
      key - 非null
      value - 属性值
      参见:
    • remove

      public void remove(int offs, int len) throws BadLocationException
      从文档中删除一些内容。删除内容会导致在实际更改发生时保持写入锁定。观察者会收到调用此方法的线程的更改通知。

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

      指定者:
      remove 在接口 Document
      参数:
      offs - 起始偏移量 >= 0
      len - 要删除的字符数 >= 0
      抛出:
      BadLocationException - 给定的删除位置不是文档中的有效位置
      参见:
    • replace

      public void replace(int offset, int length, String  text, AttributeSet  attrs) throws BadLocationException
      删除从 offsetoffset + length 的文本区域,并将其替换为 text。这取决于实现如何实现,一些实现可能将其视为两个不同的操作:删除后跟插入,其他实现可能将替换视为一个原子操作。
      参数:
      offset - 子元素的索引
      length - 要删除的文本长度,可能为 0,表示不删除任何内容
      text - 要插入的文本,null 表示没有要插入的文本
      attrs - 指示插入文本属性的 AttributeSet,null 是合法的,通常被视为空属性集,但确切的解释留给子类
      抛出:
      BadLocationException - 给定位置不是文档中的有效位置
      自从:
      1.4
    • insertString

      public void insertString(int offs, String  str, AttributeSet  a) throws BadLocationException
      在文档中插入一些内容。插入内容会导致在发生实际更改时持有写锁,然后通知获取写锁的线程上的观察者。

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

      指定者:
      insertString 在接口 Document
      参数:
      offs - 起始偏移量 >= 0
      str - 要插入的字符串;对 null/空字符串不做任何事情
      a - 插入内容的属性
      抛出:
      BadLocationException - 给定的插入位置不是文档中的有效位置
      参见:
    • getText

      public String  getText(int offset, int length) throws BadLocationException
      从文档中获取一系列文本。
      指定者:
      getText 在接口 Document
      参数:
      offset - 起始偏移量 >= 0
      length - 要检索的字符数 >= 0
      返回:
      文本
      抛出:
      BadLocationException - 给定的范围包含文档中无效位置的位置
      参见:
    • getText

      public void getText(int offset, int length, Segment  txt) throws BadLocationException
      获取文档给定部分中包含的文本。

      如果 txt 参数的 partialReturn 属性为 false,则 Segment 中返回的数据将是请求的整个长度,并且可能是也可能不是副本,具体取决于数据的存储方式。如果 partialReturn 属性为真,则只返回无需创建副本即可返回的文本量。在扫描大部分文档的情况下,使用部分返回会提供更好的性能。以下是使用部分返回访问整个文档的示例:

         int nleft = doc.getDocumentLength();
         Segment text = new Segment();
         int offs = 0;
         text.setPartialReturn(true);
         while (nleft > 0) {
           doc.getText(offs, nleft, text);
           // do something with text
           nleft -= text.count;
           offs += text.count;
         }
       
      指定者:
      getText 在接口 Document
      参数:
      offset - 起始偏移量 >= 0
      length - 要检索的字符数 >= 0
      txt - 将文本检索到的 Segment 对象
      抛出:
      BadLocationException - 给定的范围包含文档中无效位置的位置
    • createPosition

      public Position  createPosition(int offs) throws BadLocationException
      返回一个位置,该位置将在文档更改时跟踪更改。

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

      指定者:
      createPosition 在接口 Document
      参数:
      offs - 模型中的位置 >= 0
      返回:
      位置
      抛出:
      BadLocationException - 如果给定位置不代表相关文档中的有效位置
      参见:
    • getStartPosition

      public final Position  getStartPosition()
      返回表示文档开头的位置。可以依靠返回的位置来跟踪更改并保持在文档的开头。
      指定者:
      getStartPosition 在接口 Document
      返回:
      位置
    • getEndPosition

      public final Position  getEndPosition()
      返回表示文档结尾的位置。可以依靠返回的位置来跟踪更改并保持在文档末尾。
      指定者:
      getEndPosition 在接口 Document
      返回:
      位置
    • getRootElements

      public Element [] getRootElements()
      获取定义的所有根元素。通常,只有一个,因此默认实现是返回默认根元素。
      指定者:
      getRootElements 在接口 Document
      返回:
      根元素
    • getDefaultRootElement

      public abstract Element  getDefaultRootElement()
      返回视图应该基于的根元素,除非提供了一些其他的将视图分配给元素结构的机制。
      指定者:
      getDefaultRootElement 在接口 Document
      返回:
      根元素
      参见:
    • getBidiRootElement

      public Element  getBidiRootElement()
      返回此文档的双向结构的根元素。它的子代代表具有给定 Unicode bidi 级别的字符运行。
      返回:
      此文档的双向结构的根元素
    • getParagraphElement

      public abstract Element  getParagraphElement(int pos)
      获取包含给定位置的段落元素。子类必须自己定义段落的确切组成。但是,他们应该记住,段落至少应该是运行 Unicode 双向算法的文本单元。
      参数:
      pos - 起始偏移量 >= 0
      返回:
      元素
    • getAttributeContext

      protected final AbstractDocument.AttributeContext  getAttributeContext()
      获取管理属性的上下文。该方法有效地建立了用于压缩AttributeSet信息的策略。
      返回:
      上下文
    • insertUpdate

      protected void insertUpdate(AbstractDocument.DefaultDocumentEvent  chng, AttributeSet  attr)
      作为文本插入的结果更新文档结构。这将在写锁内发生。如果此类的子类重新实现此方法,它也应该委托给超类。
      参数:
      chng - 更改说明
      attr - 更改的属性
    • removeUpdate

      protected void removeUpdate(AbstractDocument.DefaultDocumentEvent  chng)
      由于文本删除而更新任何文档结构。在实际从内容中删除文本之前调用此方法。这将在写锁内发生。如果此类的子类重新实现此方法,它也应该委托给超类。
      参数:
      chng - 更改说明
    • postRemoveUpdate

      protected void postRemoveUpdate(AbstractDocument.DefaultDocumentEvent  chng)
      由于文本删除而更新任何文档结构。从内容中删除文本后调用此方法。这将在写锁内发生。如果此类的子类重新实现此方法,它也应该委托给超类。
      参数:
      chng - 更改说明
    • dump

      public void dump(PrintStream  out)
      提供诊断转储。
      参数:
      out - 输出流
    • getContent

      protected final AbstractDocument.Content  getContent()
      获取文档的内容。
      返回:
      内容
    • createLeafElement

      protected Element  createLeafElement(Element  parent, AttributeSet  a, int p0, int p1)
      创建文档叶元素。挂钩,通过它创建元素来表示文档结构。因为此实现保持结构和内容分离,所以当内容扩展时元素会自动增长,因此现有元素的拆分随之而来。文档本身决定如何生成元素以灵活使用元素类型。
      参数:
      parent - 父元素
      a - 元素的属性
      p0 - 范围的开始 >= 0
      p1 - 范围结束 >= p0
      返回:
      新元素
    • createBranchElement

      protected Element  createBranchElement(Element  parent, AttributeSet  a)
      创建一个文档分支元素,它可以包含其他元素。
      参数:
      parent - 父元素
      a - 属性
      返回:
      元素
    • getCurrentWriter

      protected final Thread  getCurrentWriter()
      获取当前写入线程(如果有的话)。这可用于区分方法是否作为现有修改的一部分被调用,或者是否需要获取锁并启动新事务。
      返回:
      主动修改文档的线程或 null 如果没有正在进行的修改
    • writeLock

      protected final void writeLock()
      获取锁以开始改变此锁保护的文档。不能为了获得锁定而进行写入、更改通知或读取。此外,允许一个线程获得多个 writeLock,只要它不尝试从文档通知中获得额外的 writeLock。尝试从 DocumentListener 通知中获取 writeLock 将导致 IllegalStateException 。每个线程获得多个 writeLock 的能力允许子类获得一个 writeLock,执行一系列操作,然后释放锁。

      writeLock 的调用必须与对 writeUnlock 的调用保持平衡,否则 Document 将处于锁定状态,因此无法进行读取或写入。

      抛出:
      IllegalStateException - 在非法锁定尝试时抛出。如果文档被正确实现,这只会在文档监听器试图改变文档时发生。这种情况违反了 bean 事件模型,在该模型中,传递顺序无法保证,并且在允许进一步更改之前应通知所有监听器。
    • writeUnlock

      protected final void writeUnlock()
      释放先前通过 writeLock 获得的写锁。如果没有未完成的锁,则在递减锁计数后,这将允许新的写入者或读取者。
      参见:
    • readLock

      public final void readLock()
      获取锁以开始从文档中读取某些状态。可以同时有多个读者。写入会阻塞读取器,直到完成对监听器的更改通知。应非常小心地使用此方法,以避免意外损坏文档。它应该始终与 readUnlock 保持平衡。
      参见:
    • readUnlock

      public final void readUnlock()
      读取解锁。这表明其中一位读者已完成。如果没有更多的读者,那么写作可以重新开始。这应该通过 readLock 来平衡,并且应该出现在 finally 语句中以保证平衡。下面是一个例子。
      
          readLock();
          try {
            // do something
          } finally {
            readUnlock();
          }
        
      参见: