abstractdocument.java

来自「linux下建立JAVA虚拟机的源码KAFFE」· Java 代码 · 共 2,243 行 · 第 1/5 页

JAVA
2,243
字号
  /**   * Returns all root elements of this <code>Document</code>. By default   * this just returns the single root element returned by   * {@link #getDefaultRootElement()}. <code>Document</code> implementations   * that support multiple roots must override this method and return all roots   * here.   *   * @return all root elements of this <code>Document</code>   */  public Element[] getRootElements()  {    Element[] elements = new Element[1];    elements[0] = getDefaultRootElement();    return elements;  }  /**   * Returns a {@link Position} which will always mark the beginning of the   * <code>Document</code>.   *   * @return a {@link Position} which will always mark the beginning of the   *         <code>Document</code>   */  public Position getStartPosition()  {    // FIXME: Properly implement this using Content.createPosition().    return new Position()       {                public int getOffset()         {           return 0;         }       };  }  /**   * Returns a piece of this <code>Document</code>'s content.   *   * @param offset the start offset of the content   * @param length the length of the content   *   * @return the piece of content specified by <code>offset</code> and   *         <code>length</code>   *   * @throws BadLocationException if <code>offset</code> or <code>offset +   *         length</code> are invalid locations with this   *         <code>Document</code>   */  public String getText(int offset, int length) throws BadLocationException  {    return content.getString(offset, length);  }  /**   * Fetches a piece of this <code>Document</code>'s content and stores   * it in the given {@link Segment}.   *   * @param offset the start offset of the content   * @param length the length of the content   * @param segment the <code>Segment</code> to store the content in   *   * @throws BadLocationException if <code>offset</code> or <code>offset +   *         length</code> are invalid locations with this   *         <code>Document</code>   */  public void getText(int offset, int length, Segment segment)    throws BadLocationException  {    content.getChars(offset, length, segment);  }  /**   * Inserts a String into this <code>Document</code> at the specified   * position and assigning the specified attributes to it.   *   * @param offset the location at which the string should be inserted   * @param text the content to be inserted   * @param attributes the text attributes to be assigned to that string   *   * @throws BadLocationException if <code>offset</code> is not a valid   *         location in this <code>Document</code>   */  public void insertString(int offset, String text, AttributeSet attributes)    throws BadLocationException  {    // Just return when no text to insert was given.    if (text == null || text.length() == 0)      return;    DefaultDocumentEvent event =      new DefaultDocumentEvent(offset, text.length(),			       DocumentEvent.EventType.INSERT);    try      {        writeLock();        UndoableEdit undo = content.insertString(offset, text);        if (undo != null)          event.addEdit(undo);        insertUpdate(event, attributes);        fireInsertUpdate(event);        if (undo != null)          fireUndoableEditUpdate(new UndoableEditEvent(this, undo));      }    finally      {        writeUnlock();      }  }  /**   * Called to indicate that text has been inserted into this   * <code>Document</code>. The default implementation does nothing.   * This method is executed within a write lock.   *   * @param chng the <code>DefaultDocumentEvent</code> describing the change   * @param attr the attributes of the changed content   */  protected void insertUpdate(DefaultDocumentEvent chng, AttributeSet attr)  {    // Do nothing here. Subclasses may want to override this.  }  /**   * Called after some content has been removed from this   * <code>Document</code>. The default implementation does nothing.   * This method is executed within a write lock.   *   * @param chng the <code>DefaultDocumentEvent</code> describing the change   */  protected void postRemoveUpdate(DefaultDocumentEvent chng)  {    // Do nothing here. Subclasses may want to override this.  }  /**   * Stores a property in this <code>Document</code>'s property list.   *   * @param key the key of the property to be stored   * @param value the value of the property to be stored   */  public void putProperty(Object key, Object value)  {    // FIXME: make me thread-safe    if (properties == null)      properties = new Hashtable();    properties.put(key, value);  }  /**   * Blocks until a read lock can be obtained.  Must block if there is   * currently a writer modifying the <code>Document</code>.   */  public void readLock()  {    if (currentWriter != null && currentWriter.equals(Thread.currentThread()))      return;    synchronized (documentCV)      {        while (currentWriter != null || numWritersWaiting > 0)          {            try              {                documentCV.wait();              }            catch (InterruptedException ie)              {                throw new Error("interrupted trying to get a readLock");              }          }          numReaders++;      }  }  /**   * Releases the read lock. If this was the only reader on this   * <code>Document</code>, writing may begin now.   */  public void readUnlock()  {    // Note we could have a problem here if readUnlock was called without a    // prior call to readLock but the specs simply warn users to ensure that    // balance by using a finally block:    // readLock()    // try    // {     //   doSomethingHere     // }    // finally    // {    //   readUnlock();    // }        // All that the JDK seems to check for is that you don't call unlock    // more times than you've previously called lock, but it doesn't make    // sure that the threads calling unlock were the same ones that called lock    // If the current thread holds the write lock, and attempted to also obtain    // a readLock, then numReaders hasn't been incremented and we don't need    // to unlock it here.    if (currentWriter == Thread.currentThread())      return;    // FIXME: the reference implementation throws a     // javax.swing.text.StateInvariantError here    if (numReaders == 0)      throw new IllegalStateException("document lock failure");        synchronized (documentCV)    {      // If currentWriter is not null, the application code probably had a       // writeLock and then tried to obtain a readLock, in which case       // numReaders wasn't incremented      if (currentWriter == null)        {          numReaders --;          if (numReaders == 0 && numWritersWaiting != 0)            documentCV.notify();        }    }  }  /**   * Removes a piece of content from this <code>Document</code>.   *   * @param offset the start offset of the fragment to be removed   * @param length the length of the fragment to be removed   *   * @throws BadLocationException if <code>offset</code> or   *         <code>offset + length</code> or invalid locations within this   *         document   */  public void remove(int offset, int length) throws BadLocationException  {    DefaultDocumentEvent event =      new DefaultDocumentEvent(offset, length,			       DocumentEvent.EventType.REMOVE);        try      {        writeLock();                // The order of the operations below is critical!                removeUpdate(event);        UndoableEdit temp = content.remove(offset, length);                postRemoveUpdate(event);        fireRemoveUpdate(event);      }    finally      {        writeUnlock();      }   }  /**   * Replaces a piece of content in this <code>Document</code> with   * another piece of content.   *   * @param offset the start offset of the fragment to be removed   * @param length the length of the fragment to be removed   * @param text the text to replace the content with   * @param attributes the text attributes to assign to the new content   *   * @throws BadLocationException if <code>offset</code> or   *         <code>offset + length</code> or invalid locations within this   *         document   *   * @since 1.4   */  public void replace(int offset, int length, String text,		      AttributeSet attributes)    throws BadLocationException  {    remove(offset, length);    insertString(offset, text, attributes);  }  /**   * Adds a <code>DocumentListener</code> object to this document.   *   * @param listener the listener to add   */  public void addDocumentListener(DocumentListener listener)  {    listenerList.add(DocumentListener.class, listener);  }  /**   * Removes a <code>DocumentListener</code> object from this document.   *   * @param listener the listener to remove   */  public void removeDocumentListener(DocumentListener listener)  {    listenerList.remove(DocumentListener.class, listener);  }  /**   * Returns all registered <code>DocumentListener</code>s.   *   * @return all registered <code>DocumentListener</code>s   */  public DocumentListener[] getDocumentListeners()  {    return (DocumentListener[]) getListeners(DocumentListener.class);  }  /**   * Adds an {@link UndoableEditListener} to this <code>Document</code>.   *   * @param listener the listener to add   */  public void addUndoableEditListener(UndoableEditListener listener)  {    listenerList.add(UndoableEditListener.class, listener);  }  /**   * Removes an {@link UndoableEditListener} from this <code>Document</code>.   *   * @param listener the listener to remove   */  public void removeUndoableEditListener(UndoableEditListener listener)  {    listenerList.remove(UndoableEditListener.class, listener);  }  /**   * Returns all registered {@link UndoableEditListener}s.   *   * @return all registered {@link UndoableEditListener}s   */  public UndoableEditListener[] getUndoableEditListeners()  {    return (UndoableEditListener[]) getListeners(UndoableEditListener.class);  }  /**   * Called before some content gets removed from this <code>Document</code>.   * The default implementation does nothing but may be overridden by   * subclasses to modify the <code>Document</code> structure in response   * to a remove request. The method is executed within a write lock.   *   * @param chng the <code>DefaultDocumentEvent</code> describing the change   */  protected void removeUpdate(DefaultDocumentEvent chng)  {    // Do nothing here. Subclasses may wish to override this.  }  /**   * Called to render this <code>Document</code> visually. It obtains a read   * lock, ensuring that no changes will be made to the <code>document</code>   * during the rendering process. It then calls the {@link Runnable#run()}   * method on <code>runnable</code>. This method <em>must not</em> attempt   * to modifiy the <code>Document</code>, since a deadlock will occur if it   * tries to obtain a write lock. When the {@link Runnable#run()} method   * completes (either naturally or by throwing an exception), the read lock   * is released. Note that there is nothing in this method related to   * the actual rendering. It could be used to execute arbitrary code within   * a read lock.   *   * @param runnable the {@link Runnable} to execute   */  public void render(Runnable runnable)  {    readLock();    try    {      runnable.run();    }    finally    {      readUnlock();    }  }  /**   * Sets the asynchronous loading priority for this <code>Document</code>.   * A value of <code>-1</code> indicates that this <code>Document</code>   * should be loaded synchronously.   *   * @param p the asynchronous loading priority to set   */  public void setAsynchronousLoadPriority(int p)  {    // TODO: Implement this properly.  }  /**   * Sets the properties of this <code>Document</code>.   *   * @param p the document properties to set   */  public void setDocumentProperties(Dictionary p)  {    // FIXME: make me thread-safe    properties = p;  }  /**   * Blocks until a write lock can be obtained.  Must wait if there are    * readers currently reading or another thread is currently writing.   */  protected void writeLock()  {    if (currentWriter != null && currentWriter.equals(Thread.currentThread()))      return;    synchronized (documentCV)      {        numWritersWaiting++;        while (numReaders > 0)          {            try              {                documentCV.wait();              }            catch (InterruptedException ie)              {                throw new Error("interruped while trying to obtain write lock");              }          }        numWritersWaiting --;        currentWriter = Thread.currentThread();      }  }  /**   * Releases the write lock. This allows waiting readers or writers to   * obtain the lock.   */  protected void writeUnlock()  {    synchronized (documentCV)    {        if (Thread.currentThread().equals(currentWriter))          {            currentWriter = null;            documentCV.notifyAll();          }    }  }  /**   * Returns the currently installed {@link DocumentFilter} for this   * <code>Document</code>.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?