mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			1223 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			1223 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			Java
		
	
	
	
/* JEditorPane.java --
 | 
						|
   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath is distributed in the hope that it will be useful, but
 | 
						|
WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
 | 
						|
package javax.swing;
 | 
						|
 | 
						|
import java.awt.Container;
 | 
						|
import java.awt.Dimension;
 | 
						|
import java.io.BufferedInputStream;
 | 
						|
import java.io.FilterInputStream;
 | 
						|
import java.io.IOException;
 | 
						|
import java.io.InputStream;
 | 
						|
import java.io.InputStreamReader;
 | 
						|
import java.io.Reader;
 | 
						|
import java.io.StringReader;
 | 
						|
import java.net.MalformedURLException;
 | 
						|
import java.net.URL;
 | 
						|
import java.net.URLConnection;
 | 
						|
import java.util.HashMap;
 | 
						|
 | 
						|
import javax.accessibility.AccessibleContext;
 | 
						|
import javax.accessibility.AccessibleHyperlink;
 | 
						|
import javax.accessibility.AccessibleHypertext;
 | 
						|
import javax.accessibility.AccessibleStateSet;
 | 
						|
import javax.accessibility.AccessibleText;
 | 
						|
import javax.swing.event.HyperlinkEvent;
 | 
						|
import javax.swing.event.HyperlinkListener;
 | 
						|
import javax.swing.plaf.TextUI;
 | 
						|
import javax.swing.text.AbstractDocument;
 | 
						|
import javax.swing.text.BadLocationException;
 | 
						|
import javax.swing.text.DefaultEditorKit;
 | 
						|
import javax.swing.text.Document;
 | 
						|
import javax.swing.text.EditorKit;
 | 
						|
import javax.swing.text.Element;
 | 
						|
import javax.swing.text.JTextComponent;
 | 
						|
import javax.swing.text.View;
 | 
						|
import javax.swing.text.ViewFactory;
 | 
						|
import javax.swing.text.WrappedPlainView;
 | 
						|
import javax.swing.text.html.HTML;
 | 
						|
import javax.swing.text.html.HTMLDocument;
 | 
						|
import javax.swing.text.html.HTMLEditorKit;
 | 
						|
 | 
						|
/**
 | 
						|
 * A powerful text editor component that can handle different types of
 | 
						|
 * content.
 | 
						|
 *
 | 
						|
 * The JEditorPane text component is driven by an instance of
 | 
						|
 * {@link EditorKit}. The editor kit is responsible for providing
 | 
						|
 * a default {@link Document} implementation, a mechanism for loading
 | 
						|
 * and saving documents of its supported content type and providing
 | 
						|
 * a set of {@link Action}s for manipulating the content.
 | 
						|
 *
 | 
						|
 * By default the following content types are supported:
 | 
						|
 * <ul>
 | 
						|
 * <li><code>text/plain</code>: Plain text, handled by
 | 
						|
 *   {@link javax.swing.text.DefaultEditorKit}.</li>
 | 
						|
 * <li><code>text/html</code>: HTML 4.0 styled text, handled by
 | 
						|
 *   {@link javax.swing.text.html.HTMLEditorKit}.</li>
 | 
						|
 * <li><code>text/rtf</code>: RTF text, handled by
 | 
						|
 *   {@link javax.swing.text.rtf.RTFEditorKit}.</li>
 | 
						|
 * </ul>
 | 
						|
 *
 | 
						|
 * @author original author unknown
 | 
						|
 * @author Roman Kennke (roman@kennke.org)
 | 
						|
 * @author Anthony Balkissoon abalkiss at redhat dot com
 | 
						|
 */
 | 
						|
public class JEditorPane extends JTextComponent
 | 
						|
{
 | 
						|
  /**
 | 
						|
   * Provides accessibility support for <code>JEditorPane</code>.
 | 
						|
   *
 | 
						|
   * @author Roman Kennke (kennke@aicas.com)
 | 
						|
   */
 | 
						|
  protected class AccessibleJEditorPane extends AccessibleJTextComponent
 | 
						|
  {
 | 
						|
 | 
						|
    /**
 | 
						|
     * Creates a new <code>AccessibleJEditorPane</code> object.
 | 
						|
     */
 | 
						|
    protected AccessibleJEditorPane()
 | 
						|
    {
 | 
						|
      super();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a description of this <code>AccessibleJEditorPane</code>. If
 | 
						|
     * this property is not set, then this returns the content-type of the
 | 
						|
     * editor pane.
 | 
						|
     *
 | 
						|
     * @return a description of this AccessibleJEditorPane
 | 
						|
     */
 | 
						|
    public String getAccessibleDescription()
 | 
						|
    {
 | 
						|
      String descr = super.getAccessibleDescription();
 | 
						|
      if (descr == null)
 | 
						|
        return getContentType();
 | 
						|
      else
 | 
						|
        return descr;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the accessible state of this <code>AccessibleJEditorPane</code>.
 | 
						|
     *
 | 
						|
     * @return  the accessible state of this <code>AccessibleJEditorPane</code>
 | 
						|
     */
 | 
						|
    public AccessibleStateSet getAccessibleStateSet()
 | 
						|
    {
 | 
						|
      AccessibleStateSet state = super.getAccessibleStateSet();
 | 
						|
      // TODO: Figure out what state must be added here to the super's state.
 | 
						|
      return state;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Provides accessibility support for <code>JEditorPane</code>s, when the
 | 
						|
   * editor kit is an instance of {@link HTMLEditorKit}.
 | 
						|
   *
 | 
						|
   * @author Roman Kennke (kennke@aicas.com)
 | 
						|
   */
 | 
						|
  protected class AccessibleJEditorPaneHTML extends AccessibleJEditorPane
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Returns the accessible text of the <code>JEditorPane</code>. This will
 | 
						|
     * be an instance of
 | 
						|
     * {@link JEditorPaneAccessibleHypertextSupport}.
 | 
						|
     *
 | 
						|
     * @return the accessible text of the <code>JEditorPane</code>
 | 
						|
     */
 | 
						|
    public AccessibleText getAccessibleText()
 | 
						|
    {
 | 
						|
      return new JEditorPaneAccessibleHypertextSupport();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This is the accessible text that is returned by
 | 
						|
   * {@link AccessibleJEditorPaneHTML#getAccessibleText()}.
 | 
						|
   *
 | 
						|
   * @author Roman Kennke (kennke@aicas.com)
 | 
						|
   */
 | 
						|
  protected class JEditorPaneAccessibleHypertextSupport
 | 
						|
    extends AccessibleJEditorPane implements AccessibleHypertext
 | 
						|
  {
 | 
						|
 | 
						|
    /**
 | 
						|
     * Creates a new JEditorPaneAccessibleHypertextSupport object.
 | 
						|
     */
 | 
						|
    public JEditorPaneAccessibleHypertextSupport()
 | 
						|
    {
 | 
						|
      super();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The accessible representation of a HTML link.
 | 
						|
     *
 | 
						|
     * @author Roman Kennke (kennke@aicas.com)
 | 
						|
     */
 | 
						|
    public class HTMLLink extends AccessibleHyperlink
 | 
						|
    {
 | 
						|
 | 
						|
      /**
 | 
						|
       * The element in the document that represents the link.
 | 
						|
       */
 | 
						|
      Element element;
 | 
						|
 | 
						|
      /**
 | 
						|
       * Creates a new <code>HTMLLink</code>.
 | 
						|
       *
 | 
						|
       * @param el the link element
 | 
						|
       */
 | 
						|
      public HTMLLink(Element el)
 | 
						|
      {
 | 
						|
        this.element = el;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns <code>true</code> if this <code>HTMLLink</code> is still
 | 
						|
       * valid. A <code>HTMLLink</code> can become invalid when the document
 | 
						|
       * changes.
 | 
						|
       *
 | 
						|
       * @return <code>true</code> if this <code>HTMLLink</code> is still
 | 
						|
       *         valid
 | 
						|
       */
 | 
						|
      public boolean isValid()
 | 
						|
      {
 | 
						|
        // I test here if the element at our element's start offset is the
 | 
						|
        // same as the element in the document at this offset. If this is true,
 | 
						|
        // I consider the link valid, if not, then this link no longer
 | 
						|
        // represented by this HTMLLink and therefor invalid.
 | 
						|
        HTMLDocument doc = (HTMLDocument) getDocument();
 | 
						|
        return doc.getCharacterElement(element.getStartOffset()) == element;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the number of AccessibleActions in this link object. In
 | 
						|
       * general, link have 1 AccessibleAction associated with them. There are
 | 
						|
       * special cases where links can have multiple actions associated, like
 | 
						|
       * in image maps.
 | 
						|
       *
 | 
						|
       * @return the number of AccessibleActions in this link object
 | 
						|
       */
 | 
						|
      public int getAccessibleActionCount()
 | 
						|
      {
 | 
						|
        // TODO: Implement the special cases.
 | 
						|
        return 1;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Performs the specified action on the link object. This ususally means
 | 
						|
       * activating the link.
 | 
						|
       *
 | 
						|
       * @return <code>true</code> if the action has been performed
 | 
						|
       *         successfully, <code>false</code> otherwise
 | 
						|
       */
 | 
						|
      public boolean doAccessibleAction(int i)
 | 
						|
      {
 | 
						|
        String href = (String) element.getAttributes().getAttribute("href");
 | 
						|
        HTMLDocument doc = (HTMLDocument) getDocument();
 | 
						|
        try
 | 
						|
          {
 | 
						|
            URL url = new URL(doc.getBase(), href);
 | 
						|
            setPage(url);
 | 
						|
            String desc = doc.getText(element.getStartOffset(),
 | 
						|
                            element.getEndOffset() - element.getStartOffset());
 | 
						|
            HyperlinkEvent ev =
 | 
						|
              new HyperlinkEvent(JEditorPane.this,
 | 
						|
                                 HyperlinkEvent.EventType.ACTIVATED, url, desc,
 | 
						|
                                 element);
 | 
						|
            fireHyperlinkUpdate(ev);
 | 
						|
            return true;
 | 
						|
          }
 | 
						|
        catch (Exception ex)
 | 
						|
          {
 | 
						|
            return false;
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the description of the action at action index <code>i</code>.
 | 
						|
       * This method returns the text within the element associated with this
 | 
						|
       * link.
 | 
						|
       *
 | 
						|
       * @param i the action index
 | 
						|
       *
 | 
						|
       * @return the description of the action at action index <code>i</code>
 | 
						|
       */
 | 
						|
      public String getAccessibleActionDescription(int i)
 | 
						|
      {
 | 
						|
        HTMLDocument doc = (HTMLDocument) getDocument();
 | 
						|
        try
 | 
						|
          {
 | 
						|
            return doc.getText(element.getStartOffset(),
 | 
						|
                            element.getEndOffset() - element.getStartOffset());
 | 
						|
          }
 | 
						|
        catch (BadLocationException ex)
 | 
						|
          {
 | 
						|
            throw (AssertionError)
 | 
						|
            new AssertionError("BadLocationException must not be thrown "
 | 
						|
                               + "here.")
 | 
						|
              .initCause(ex);
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns an {@link URL} object, that represents the action at action
 | 
						|
       * index <code>i</code>.
 | 
						|
       *
 | 
						|
       * @param i the action index
 | 
						|
       *
 | 
						|
       * @return an {@link URL} object, that represents the action at action
 | 
						|
       *         index <code>i</code>
 | 
						|
       */
 | 
						|
      public Object getAccessibleActionObject(int i)
 | 
						|
      {
 | 
						|
        String href = (String) element.getAttributes().getAttribute("href");
 | 
						|
        HTMLDocument doc = (HTMLDocument) getDocument();
 | 
						|
        try
 | 
						|
          {
 | 
						|
            URL url = new URL(doc.getBase(), href);
 | 
						|
            return url;
 | 
						|
          }
 | 
						|
        catch (MalformedURLException ex)
 | 
						|
          {
 | 
						|
            return null;
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns an object that represents the link anchor. For examples, if
 | 
						|
       * the link encloses a string, then a <code>String</code> object is
 | 
						|
       * returned, if the link encloses an <img> tag, then an
 | 
						|
       * <code>ImageIcon</code> object is returned.
 | 
						|
       *
 | 
						|
       * @return an object that represents the link anchor
 | 
						|
       */
 | 
						|
      public Object getAccessibleActionAnchor(int i)
 | 
						|
      {
 | 
						|
        // TODO: This is only the String case. Implement all cases.
 | 
						|
        return getAccessibleActionDescription(i);
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the start index of the hyperlink element.
 | 
						|
       *
 | 
						|
       * @return the start index of the hyperlink element
 | 
						|
       */
 | 
						|
      public int getStartIndex()
 | 
						|
      {
 | 
						|
        return element.getStartOffset();
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the end index of the hyperlink element.
 | 
						|
       *
 | 
						|
       * @return the end index of the hyperlink element
 | 
						|
       */
 | 
						|
      public int getEndIndex()
 | 
						|
      {
 | 
						|
        return element.getEndOffset();
 | 
						|
      }
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the number of hyperlinks in the document.
 | 
						|
     *
 | 
						|
     * @return the number of hyperlinks in the document
 | 
						|
     */
 | 
						|
    public int getLinkCount()
 | 
						|
    {
 | 
						|
      HTMLDocument doc = (HTMLDocument) getDocument();
 | 
						|
      HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
 | 
						|
      int count = 0;
 | 
						|
      while (linkIter.isValid())
 | 
						|
        {
 | 
						|
          count++;
 | 
						|
          linkIter.next();
 | 
						|
        }
 | 
						|
      return count;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the <code>i</code>-th hyperlink in the document or
 | 
						|
     * <code>null</code> if there is no hyperlink with the specified index.
 | 
						|
     *
 | 
						|
     * @param i the index of the hyperlink to return
 | 
						|
     *
 | 
						|
     * @return the <code>i</code>-th hyperlink in the document or
 | 
						|
     *         <code>null</code> if there is no hyperlink with the specified
 | 
						|
     *         index
 | 
						|
     */
 | 
						|
    public AccessibleHyperlink getLink(int i)
 | 
						|
    {
 | 
						|
      HTMLDocument doc = (HTMLDocument) getDocument();
 | 
						|
      HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
 | 
						|
      int count = 0;
 | 
						|
      while (linkIter.isValid())
 | 
						|
        {
 | 
						|
          count++;
 | 
						|
          if (count == i)
 | 
						|
            break;
 | 
						|
          linkIter.next();
 | 
						|
        }
 | 
						|
      if (linkIter.isValid())
 | 
						|
        {
 | 
						|
          int offset = linkIter.getStartOffset();
 | 
						|
          // TODO: I fetch the element for the link via getCharacterElement().
 | 
						|
          // I am not sure that this is correct, maybe we must use
 | 
						|
          // getParagraphElement()?
 | 
						|
          Element el = doc.getCharacterElement(offset);
 | 
						|
          HTMLLink link = new HTMLLink(el);
 | 
						|
          return link;
 | 
						|
        }
 | 
						|
      else
 | 
						|
        return null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the index of the link element at the character position
 | 
						|
     * <code>c</code> within the document, or <code>-1</code> if there is no
 | 
						|
     * link at the specified position.
 | 
						|
     *
 | 
						|
     * @param c the character index from which to fetch the link index
 | 
						|
     *
 | 
						|
     * @return the index of the link element at the character position
 | 
						|
     *         <code>c</code> within the document, or <code>-1</code> if there
 | 
						|
     *         is no link at the specified position
 | 
						|
     */
 | 
						|
    public int getLinkIndex(int c)
 | 
						|
    {
 | 
						|
      HTMLDocument doc = (HTMLDocument) getDocument();
 | 
						|
      HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
 | 
						|
      int count = 0;
 | 
						|
      while (linkIter.isValid())
 | 
						|
        {
 | 
						|
          if (linkIter.getStartOffset() <= c && linkIter.getEndOffset() > c)
 | 
						|
            break;
 | 
						|
          count++;
 | 
						|
          linkIter.next();
 | 
						|
        }
 | 
						|
      if (linkIter.isValid())
 | 
						|
        return count;
 | 
						|
      else
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the link text of the link at index <code>i</code>, or
 | 
						|
     * <code>null</code>, if there is no link at the specified position.
 | 
						|
     *
 | 
						|
     * @param i the index of the link
 | 
						|
     *
 | 
						|
     * @return  the link text of the link at index <code>i</code>, or
 | 
						|
     *          <code>null</code>, if there is no link at the specified
 | 
						|
     *          position
 | 
						|
     */
 | 
						|
    public String getLinkText(int i)
 | 
						|
    {
 | 
						|
      HTMLDocument doc = (HTMLDocument) getDocument();
 | 
						|
      HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
 | 
						|
      int count = 0;
 | 
						|
      while (linkIter.isValid())
 | 
						|
        {
 | 
						|
          count++;
 | 
						|
          if (count == i)
 | 
						|
            break;
 | 
						|
          linkIter.next();
 | 
						|
        }
 | 
						|
      if (linkIter.isValid())
 | 
						|
        {
 | 
						|
          int offset = linkIter.getStartOffset();
 | 
						|
          // TODO: I fetch the element for the link via getCharacterElement().
 | 
						|
          // I am not sure that this is correct, maybe we must use
 | 
						|
          // getParagraphElement()?
 | 
						|
          Element el = doc.getCharacterElement(offset);
 | 
						|
          try
 | 
						|
            {
 | 
						|
              String text = doc.getText(el.getStartOffset(),
 | 
						|
                                      el.getEndOffset() - el.getStartOffset());
 | 
						|
              return text;
 | 
						|
            }
 | 
						|
          catch (BadLocationException ex)
 | 
						|
            {
 | 
						|
              throw (AssertionError)
 | 
						|
                new AssertionError("BadLocationException must not be thrown "
 | 
						|
                                   + "here.")
 | 
						|
                  .initCause(ex);
 | 
						|
            }
 | 
						|
        }
 | 
						|
      else
 | 
						|
        return null;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Used to store a mapping for content-type to editor kit class.
 | 
						|
   */
 | 
						|
  private static class EditorKitMapping
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * The classname of the editor kit.
 | 
						|
     */
 | 
						|
    String className;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The classloader with which the kit is to be loaded.
 | 
						|
     */
 | 
						|
    ClassLoader classLoader;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Creates a new EditorKitMapping object.
 | 
						|
     *
 | 
						|
     * @param cn the classname
 | 
						|
     * @param cl the classloader
 | 
						|
     */
 | 
						|
    EditorKitMapping(String cn, ClassLoader cl)
 | 
						|
    {
 | 
						|
      className = cn;
 | 
						|
      classLoader = cl;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * An EditorKit used for plain text. This is the default editor kit for
 | 
						|
   * JEditorPanes.
 | 
						|
   *
 | 
						|
   * @author Roman Kennke (kennke@aicas.com)
 | 
						|
   */
 | 
						|
  private static class PlainEditorKit extends DefaultEditorKit
 | 
						|
  {
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a ViewFactory that supplies WrappedPlainViews.
 | 
						|
     */
 | 
						|
    public ViewFactory getViewFactory()
 | 
						|
    {
 | 
						|
      return new ViewFactory()
 | 
						|
      {
 | 
						|
        public View create(Element el)
 | 
						|
        {
 | 
						|
          return new WrappedPlainView(el);
 | 
						|
        }
 | 
						|
      };
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * A special stream that can be cancelled.
 | 
						|
   */
 | 
						|
  private class PageStream
 | 
						|
    extends FilterInputStream
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * True when the stream has been cancelled, false otherwise.
 | 
						|
     */
 | 
						|
    private boolean cancelled;
 | 
						|
 | 
						|
    protected PageStream(InputStream in)
 | 
						|
    {
 | 
						|
      super(in);
 | 
						|
      cancelled = false;
 | 
						|
    }
 | 
						|
 | 
						|
    private void checkCancelled()
 | 
						|
      throws IOException
 | 
						|
    {
 | 
						|
      if (cancelled)
 | 
						|
        throw new IOException("Stream has been cancelled");
 | 
						|
    }
 | 
						|
 | 
						|
    void cancel()
 | 
						|
    {
 | 
						|
      cancelled = true;
 | 
						|
    }
 | 
						|
 | 
						|
    public int read()
 | 
						|
      throws IOException
 | 
						|
    {
 | 
						|
      checkCancelled();
 | 
						|
      return super.read();
 | 
						|
    }
 | 
						|
 | 
						|
    public int read(byte[] b, int off, int len)
 | 
						|
      throws IOException
 | 
						|
    {
 | 
						|
      checkCancelled();
 | 
						|
      return super.read(b, off, len);
 | 
						|
    }
 | 
						|
 | 
						|
    public long skip(long n)
 | 
						|
      throws IOException
 | 
						|
    {
 | 
						|
      checkCancelled();
 | 
						|
      return super.skip(n);
 | 
						|
    }
 | 
						|
 | 
						|
    public int available()
 | 
						|
      throws IOException
 | 
						|
    {
 | 
						|
      checkCancelled();
 | 
						|
      return super.available();
 | 
						|
    }
 | 
						|
 | 
						|
    public void reset()
 | 
						|
      throws IOException
 | 
						|
    {
 | 
						|
      checkCancelled();
 | 
						|
      super.reset();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The thread that loads documents asynchronously.
 | 
						|
   */
 | 
						|
  private class PageLoader
 | 
						|
    implements Runnable
 | 
						|
  {
 | 
						|
    private Document doc;
 | 
						|
    private PageStream in;
 | 
						|
    private URL old;
 | 
						|
    URL page;
 | 
						|
    PageLoader(Document doc, InputStream in, URL old, URL page)
 | 
						|
    {
 | 
						|
      this.doc = doc;
 | 
						|
      this.in = new PageStream(in);
 | 
						|
      this.old = old;
 | 
						|
      this.page = page;
 | 
						|
    }
 | 
						|
 | 
						|
    public void run()
 | 
						|
    {
 | 
						|
      try
 | 
						|
        {
 | 
						|
          read(in, doc);
 | 
						|
        }
 | 
						|
      catch (IOException ex)
 | 
						|
        {
 | 
						|
          UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this);
 | 
						|
        }
 | 
						|
      finally
 | 
						|
        {
 | 
						|
          if (SwingUtilities.isEventDispatchThread())
 | 
						|
            firePropertyChange("page", old, page);
 | 
						|
          else
 | 
						|
            {
 | 
						|
              SwingUtilities.invokeLater(new Runnable()
 | 
						|
              {
 | 
						|
                public void run()
 | 
						|
                {
 | 
						|
                  firePropertyChange("page", old, page);
 | 
						|
                }
 | 
						|
              });
 | 
						|
            }
 | 
						|
         }
 | 
						|
     }
 | 
						|
 | 
						|
     void cancel()
 | 
						|
     {
 | 
						|
       in.cancel();
 | 
						|
     }
 | 
						|
  }
 | 
						|
 | 
						|
  private static final long serialVersionUID = 3140472492599046285L;
 | 
						|
 | 
						|
  private EditorKit editorKit;
 | 
						|
 | 
						|
  boolean focus_root;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Maps content-types to editor kit instances.
 | 
						|
   */
 | 
						|
  static HashMap editorKits;
 | 
						|
 | 
						|
  // A mapping between content types and registered EditorKit types
 | 
						|
  static HashMap registerMap;
 | 
						|
 | 
						|
  static
 | 
						|
  {
 | 
						|
    registerMap = new HashMap();
 | 
						|
    editorKits = new HashMap();
 | 
						|
    registerEditorKitForContentType("application/rtf",
 | 
						|
                                    "javax.swing.text.rtf.RTFEditorKit");
 | 
						|
    registerEditorKitForContentType("text/plain",
 | 
						|
                                    "javax.swing.JEditorPane$PlainEditorKit");
 | 
						|
    registerEditorKitForContentType("text/html",
 | 
						|
                                    "javax.swing.text.html.HTMLEditorKit");
 | 
						|
    registerEditorKitForContentType("text/rtf",
 | 
						|
                                    "javax.swing.text.rtf.RTFEditorKit");
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  // A mapping between content types and used EditorKits
 | 
						|
  HashMap editorMap;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The currently loading stream, if any.
 | 
						|
   */
 | 
						|
  private PageLoader loader;
 | 
						|
 | 
						|
  public JEditorPane()
 | 
						|
  {
 | 
						|
    init();
 | 
						|
    setEditorKit(createDefaultEditorKit());
 | 
						|
  }
 | 
						|
 | 
						|
  public JEditorPane(String url) throws IOException
 | 
						|
  {
 | 
						|
    this(new URL(url));
 | 
						|
  }
 | 
						|
 | 
						|
  public JEditorPane(String type, String text)
 | 
						|
  {
 | 
						|
    init();
 | 
						|
    setEditorKit(createEditorKitForContentType(type));
 | 
						|
    setText(text);
 | 
						|
  }
 | 
						|
 | 
						|
  public JEditorPane(URL url) throws IOException
 | 
						|
  {
 | 
						|
    init();
 | 
						|
    setEditorKit(createEditorKitForContentType("text/html"));
 | 
						|
    setPage(url);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Called by the constructors to set up the default bindings for content
 | 
						|
   * types and EditorKits.
 | 
						|
   */
 | 
						|
  void init()
 | 
						|
  {
 | 
						|
    editorMap = new HashMap();
 | 
						|
  }
 | 
						|
 | 
						|
  protected EditorKit createDefaultEditorKit()
 | 
						|
  {
 | 
						|
    return new PlainEditorKit();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates and returns an EditorKit that is appropriate for the given
 | 
						|
   * content type.  This is created using the default recognized types
 | 
						|
   * plus any EditorKit types that have been registered.
 | 
						|
   *
 | 
						|
   * @see #registerEditorKitForContentType(String, String)
 | 
						|
   * @see #registerEditorKitForContentType(String, String, ClassLoader)
 | 
						|
   * @param type the content type
 | 
						|
   * @return an EditorKit for use with the given content type
 | 
						|
   */
 | 
						|
  public static EditorKit createEditorKitForContentType(String type)
 | 
						|
  {
 | 
						|
    // Try cached instance.
 | 
						|
    EditorKit e = (EditorKit) editorKits.get(type);
 | 
						|
    if (e == null)
 | 
						|
      {
 | 
						|
        EditorKitMapping m = (EditorKitMapping) registerMap.get(type);
 | 
						|
        if (m != null)
 | 
						|
          {
 | 
						|
            String className = m.className;
 | 
						|
            ClassLoader loader = m.classLoader;
 | 
						|
            try
 | 
						|
              {
 | 
						|
                e = (EditorKit) loader.loadClass(className).newInstance();
 | 
						|
              }
 | 
						|
            catch (Exception e2)
 | 
						|
              {
 | 
						|
                // The reference implementation returns null when class is not
 | 
						|
                // loadable or instantiatable.
 | 
						|
              }
 | 
						|
          }
 | 
						|
        // Cache this for later retrieval.
 | 
						|
        if (e != null)
 | 
						|
          editorKits.put(type, e);
 | 
						|
      }
 | 
						|
    return e;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sends a given <code>HyperlinkEvent</code> to all registered listeners.
 | 
						|
   *
 | 
						|
   * @param event the event to send
 | 
						|
   */
 | 
						|
  public void fireHyperlinkUpdate(HyperlinkEvent event)
 | 
						|
  {
 | 
						|
    HyperlinkListener[] listeners = getHyperlinkListeners();
 | 
						|
 | 
						|
    for (int index = 0; index < listeners.length; ++index)
 | 
						|
       listeners[index].hyperlinkUpdate(event);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the accessible context associated with this editor pane.
 | 
						|
   *
 | 
						|
   * @return the accessible context associated with this editor pane
 | 
						|
   */
 | 
						|
  public AccessibleContext getAccessibleContext()
 | 
						|
  {
 | 
						|
    if (accessibleContext == null)
 | 
						|
      {
 | 
						|
        if (getEditorKit() instanceof HTMLEditorKit)
 | 
						|
          accessibleContext = new AccessibleJEditorPaneHTML();
 | 
						|
        else
 | 
						|
          accessibleContext = new AccessibleJEditorPane();
 | 
						|
      }
 | 
						|
    return accessibleContext;
 | 
						|
  }
 | 
						|
 | 
						|
  public final String getContentType()
 | 
						|
  {
 | 
						|
    return getEditorKit().getContentType();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the EditorKit. If there is no EditorKit set this method
 | 
						|
   * calls createDefaultEditorKit() and setEditorKit() first.
 | 
						|
   */
 | 
						|
  public EditorKit getEditorKit()
 | 
						|
  {
 | 
						|
    if (editorKit == null)
 | 
						|
      setEditorKit(createDefaultEditorKit());
 | 
						|
    return editorKit;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the class name of the EditorKit associated with the given
 | 
						|
   * content type.
 | 
						|
   *
 | 
						|
   * @since 1.3
 | 
						|
   * @param type the content type
 | 
						|
   * @return the class name of the EditorKit associated with this content type
 | 
						|
   */
 | 
						|
  public static String getEditorKitClassNameForContentType(String type)
 | 
						|
  {
 | 
						|
    EditorKitMapping m = (EditorKitMapping) registerMap.get(type);
 | 
						|
    String kitName = m != null ? m.className : null;
 | 
						|
    return kitName;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the EditorKit to use for the given content type.  If an
 | 
						|
   * EditorKit has been explicitly set via
 | 
						|
   * <code>setEditorKitForContentType</code>
 | 
						|
   * then it will be returned.  Otherwise an attempt will be made to create
 | 
						|
   * an EditorKit from the default recognzied content types or any
 | 
						|
   * EditorKits that have been registered.  If none can be created, a
 | 
						|
   * PlainEditorKit is created.
 | 
						|
   *
 | 
						|
   * @see #registerEditorKitForContentType(String, String)
 | 
						|
   * @see #registerEditorKitForContentType(String, String, ClassLoader)
 | 
						|
   * @param type the content type
 | 
						|
   * @return an appropriate EditorKit for the given content type
 | 
						|
   */
 | 
						|
  public EditorKit getEditorKitForContentType(String type)
 | 
						|
  {
 | 
						|
    // First check if an EditorKit has been explicitly set.
 | 
						|
    EditorKit e = (EditorKit) editorMap.get(type);
 | 
						|
    // Then check to see if we can create one.
 | 
						|
    if (e == null)
 | 
						|
      {
 | 
						|
        e = createEditorKitForContentType(type);
 | 
						|
        if (e != null)
 | 
						|
          setEditorKitForContentType(type, e);
 | 
						|
      }
 | 
						|
    // Otherwise default to PlainEditorKit.
 | 
						|
    if (e == null)
 | 
						|
      e = createDefaultEditorKit();
 | 
						|
    return e;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the preferred size for the JEditorPane. This is implemented to
 | 
						|
   * return the super's preferred size, unless one of
 | 
						|
   * {@link #getScrollableTracksViewportHeight()} or
 | 
						|
   * {@link #getScrollableTracksViewportWidth()} returns <code>true</code>,
 | 
						|
   * in which case the preferred width and/or height is replaced by the UI's
 | 
						|
   * minimum size.
 | 
						|
   *
 | 
						|
   * @return the preferred size for the JEditorPane
 | 
						|
   */
 | 
						|
  public Dimension getPreferredSize()
 | 
						|
  {
 | 
						|
    Dimension pref = super.getPreferredSize();
 | 
						|
    Container parent = getParent();
 | 
						|
    if (parent instanceof JViewport)
 | 
						|
      {
 | 
						|
        JViewport vp = (JViewport) getParent();
 | 
						|
        TextUI ui = getUI();
 | 
						|
        Dimension min = null;
 | 
						|
        if (! getScrollableTracksViewportWidth())
 | 
						|
          {
 | 
						|
            min = ui.getMinimumSize(this);
 | 
						|
            int vpWidth = vp.getWidth();
 | 
						|
            if (vpWidth != 0 && vpWidth < min.width)
 | 
						|
              pref.width = min.width;
 | 
						|
          }
 | 
						|
        if (! getScrollableTracksViewportHeight())
 | 
						|
          {
 | 
						|
            if (min == null)
 | 
						|
              min = ui.getMinimumSize(this);
 | 
						|
            int vpHeight = vp.getHeight();
 | 
						|
            if (vpHeight != 0 && vpHeight < min.height)
 | 
						|
              pref.height = min.height;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    return pref;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns <code>true</code> when a Viewport should force the height of
 | 
						|
   * this component to match the viewport height. This is implemented to return
 | 
						|
   * <code>true</code> when  the parent is an instance of JViewport and
 | 
						|
   * the viewport height > the UI's minimum height.
 | 
						|
   *
 | 
						|
   * @return <code>true</code> when a Viewport should force the height of
 | 
						|
   *         this component to match the viewport height
 | 
						|
   */
 | 
						|
  public boolean getScrollableTracksViewportHeight()
 | 
						|
  {
 | 
						|
    // Tests show that this returns true when the parent is a JViewport
 | 
						|
    // and has a height > minimum UI height.
 | 
						|
    Container parent = getParent();
 | 
						|
    int height = parent.getHeight();
 | 
						|
    TextUI ui = getUI();
 | 
						|
    return parent instanceof JViewport
 | 
						|
           && height >= ui.getMinimumSize(this).height
 | 
						|
           && height <= ui.getMaximumSize(this).height;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns <code>true</code> when a Viewport should force the width of
 | 
						|
   * this component to match the viewport width. This is implemented to return
 | 
						|
   * <code>true</code> when  the parent is an instance of JViewport and
 | 
						|
   * the viewport width > the UI's minimum width.
 | 
						|
   *
 | 
						|
   * @return <code>true</code> when a Viewport should force the width of
 | 
						|
   *         this component to match the viewport width
 | 
						|
   */
 | 
						|
  public boolean getScrollableTracksViewportWidth()
 | 
						|
  {
 | 
						|
    // Tests show that this returns true when the parent is a JViewport
 | 
						|
    // and has a width > minimum UI width.
 | 
						|
    Container parent = getParent();
 | 
						|
    return parent != null && parent instanceof JViewport
 | 
						|
           && parent.getWidth() > getUI().getMinimumSize(this).width;
 | 
						|
  }
 | 
						|
 | 
						|
  public URL getPage()
 | 
						|
  {
 | 
						|
    return loader != null ? loader.page : null;
 | 
						|
  }
 | 
						|
 | 
						|
  protected InputStream getStream(URL page)
 | 
						|
    throws IOException
 | 
						|
  {
 | 
						|
    URLConnection conn = page.openConnection();
 | 
						|
    // Try to detect the content type of the stream data.
 | 
						|
    String type = conn.getContentType();
 | 
						|
    if (type != null)
 | 
						|
      setContentType(type);
 | 
						|
    InputStream stream = conn.getInputStream();
 | 
						|
    return new BufferedInputStream(stream);
 | 
						|
  }
 | 
						|
 | 
						|
  public String getText()
 | 
						|
  {
 | 
						|
    return super.getText();
 | 
						|
  }
 | 
						|
 | 
						|
  public String getUIClassID()
 | 
						|
  {
 | 
						|
    return "EditorPaneUI";
 | 
						|
  }
 | 
						|
 | 
						|
  public boolean isFocusCycleRoot()
 | 
						|
  {
 | 
						|
    return focus_root;
 | 
						|
  }
 | 
						|
 | 
						|
  protected String paramString()
 | 
						|
  {
 | 
						|
    return "JEditorPane";
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This method initializes from a stream.
 | 
						|
   */
 | 
						|
  public void read(InputStream in, Object desc) throws IOException
 | 
						|
  {
 | 
						|
    EditorKit kit = getEditorKit();
 | 
						|
    if (kit instanceof HTMLEditorKit && desc instanceof HTMLDocument)
 | 
						|
      {
 | 
						|
        HTMLDocument doc = (HTMLDocument) desc;
 | 
						|
        setDocument(doc);
 | 
						|
        try
 | 
						|
          {
 | 
						|
            InputStreamReader reader = new InputStreamReader(in);
 | 
						|
            kit.read(reader, doc, 0);
 | 
						|
          }
 | 
						|
        catch (BadLocationException ex)
 | 
						|
          {
 | 
						|
            assert false : "BadLocationException must not be thrown here.";
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else
 | 
						|
      {
 | 
						|
        Reader inRead = new InputStreamReader(in);
 | 
						|
        super.read(inRead, desc);
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Establishes a binding between type and classname.  This enables
 | 
						|
   * us to create an EditorKit later for the given content type.
 | 
						|
   *
 | 
						|
   * @param type the content type
 | 
						|
   * @param classname the name of the class that is associated with this
 | 
						|
   * content type
 | 
						|
   */
 | 
						|
  public static void registerEditorKitForContentType(String type,
 | 
						|
                                                     String classname)
 | 
						|
  {
 | 
						|
    registerEditorKitForContentType(type, classname,
 | 
						|
                               Thread.currentThread().getContextClassLoader());
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Establishes the default bindings of type to classname.
 | 
						|
   */
 | 
						|
  public static void registerEditorKitForContentType(String type,
 | 
						|
                                                     String classname,
 | 
						|
                                                     ClassLoader loader)
 | 
						|
  {
 | 
						|
    registerMap.put(type, new EditorKitMapping(classname, loader));
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Replaces the currently selected content with new content represented
 | 
						|
   * by the given string.
 | 
						|
   */
 | 
						|
  public void replaceSelection(String content)
 | 
						|
  {
 | 
						|
    // TODO: Implement this properly.
 | 
						|
    super.replaceSelection(content);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Scrolls the view to the given reference location (that is, the value
 | 
						|
   * returned by the UL.getRef method for the URL being displayed).
 | 
						|
   */
 | 
						|
  public void scrollToReference(String reference)
 | 
						|
  {
 | 
						|
    // TODO: Implement this properly.
 | 
						|
  }
 | 
						|
 | 
						|
  public final void setContentType(String type)
 | 
						|
  {
 | 
						|
    // Strip off content type parameters.
 | 
						|
    int paramIndex = type.indexOf(';');
 | 
						|
    if (paramIndex > -1)
 | 
						|
      {
 | 
						|
        // TODO: Handle character encoding.
 | 
						|
        type = type.substring(0, paramIndex).trim();
 | 
						|
      }
 | 
						|
    if (editorKit != null
 | 
						|
        && editorKit.getContentType().equals(type))
 | 
						|
      return;
 | 
						|
 | 
						|
    EditorKit kit = getEditorKitForContentType(type);
 | 
						|
 | 
						|
    if (kit != null)
 | 
						|
      setEditorKit(kit);
 | 
						|
  }
 | 
						|
 | 
						|
  public void setEditorKit(EditorKit newValue)
 | 
						|
  {
 | 
						|
    if (editorKit == newValue)
 | 
						|
      return;
 | 
						|
 | 
						|
    if (editorKit != null)
 | 
						|
      editorKit.deinstall(this);
 | 
						|
 | 
						|
    EditorKit oldValue = editorKit;
 | 
						|
    editorKit = newValue;
 | 
						|
 | 
						|
    if (editorKit != null)
 | 
						|
      {
 | 
						|
        editorKit.install(this);
 | 
						|
        setDocument(editorKit.createDefaultDocument());
 | 
						|
      }
 | 
						|
 | 
						|
    firePropertyChange("editorKit", oldValue, newValue);
 | 
						|
    invalidate();
 | 
						|
    repaint();
 | 
						|
    // Reset the accessibleContext since this depends on the editorKit.
 | 
						|
    accessibleContext = null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Explicitly sets an EditorKit to be used for the given content type.
 | 
						|
   * @param type the content type
 | 
						|
   * @param k the EditorKit to use for the given content type
 | 
						|
   */
 | 
						|
  public void setEditorKitForContentType(String type, EditorKit k)
 | 
						|
  {
 | 
						|
    editorMap.put(type, k);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the current URL being displayed.
 | 
						|
   */
 | 
						|
  public void setPage(String url) throws IOException
 | 
						|
  {
 | 
						|
    setPage(new URL(url));
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the current URL being displayed.
 | 
						|
   */
 | 
						|
  public void setPage(URL page) throws IOException
 | 
						|
  {
 | 
						|
    if (page == null)
 | 
						|
      throw new IOException("invalid url");
 | 
						|
 | 
						|
    URL old = getPage();
 | 
						|
    // Only reload if the URL doesn't point to the same file.
 | 
						|
    // This is not the same as equals because there might be different
 | 
						|
    // URLs on the same file with different anchors.
 | 
						|
    if (old == null || ! old.sameFile(page))
 | 
						|
      {
 | 
						|
        InputStream in = getStream(page);
 | 
						|
        if (editorKit != null)
 | 
						|
          {
 | 
						|
            Document doc = editorKit.createDefaultDocument();
 | 
						|
            doc.putProperty(Document.StreamDescriptionProperty, page);
 | 
						|
 | 
						|
            if (loader != null)
 | 
						|
              loader.cancel();
 | 
						|
            loader = new PageLoader(doc, in, old, page);
 | 
						|
 | 
						|
            int prio = -1;
 | 
						|
            if (doc instanceof AbstractDocument)
 | 
						|
              {
 | 
						|
                AbstractDocument aDoc = (AbstractDocument) doc;
 | 
						|
                prio = aDoc.getAsynchronousLoadPriority();
 | 
						|
              }
 | 
						|
            if (prio >= 0)
 | 
						|
              {
 | 
						|
                // Load asynchronously.
 | 
						|
                setDocument(doc);
 | 
						|
                Thread loadThread = new Thread(loader,
 | 
						|
                                               "JEditorPane.PageLoader");
 | 
						|
                loadThread.setDaemon(true);
 | 
						|
                loadThread.setPriority(prio);
 | 
						|
                loadThread.start();
 | 
						|
              }
 | 
						|
            else
 | 
						|
              {
 | 
						|
                // Load synchronously.
 | 
						|
                loader.run();
 | 
						|
                setDocument(doc);
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the text of the JEditorPane.  The argument <code>t</code>
 | 
						|
   * is expected to be in the format of the current EditorKit.  This removes
 | 
						|
   * the content of the current document and uses the EditorKit to read in the
 | 
						|
   * new text.  This allows the EditorKit to handle the String rather than just
 | 
						|
   * inserting in plain text.
 | 
						|
   *
 | 
						|
   * @param t the text to display in this JEditorPane
 | 
						|
   */
 | 
						|
  public void setText(String t)
 | 
						|
  {
 | 
						|
    try
 | 
						|
    {
 | 
						|
      // Remove the current content.
 | 
						|
      Document doc = getDocument();
 | 
						|
      doc.remove(0, doc.getLength());
 | 
						|
      if (t == null || t.equals(""))
 | 
						|
        return;
 | 
						|
 | 
						|
      // Let the EditorKit read the text into the Document.
 | 
						|
      getEditorKit().read(new StringReader(t), doc, 0);
 | 
						|
    }
 | 
						|
    catch (BadLocationException ble)
 | 
						|
    {
 | 
						|
      // TODO: Don't know what to do here.
 | 
						|
    }
 | 
						|
    catch (IOException ioe)
 | 
						|
    {
 | 
						|
      // TODO: Don't know what to do here.
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Add a <code>HyperlinkListener</code> object to this editor pane.
 | 
						|
   *
 | 
						|
   * @param listener the listener to add
 | 
						|
   */
 | 
						|
  public void addHyperlinkListener(HyperlinkListener listener)
 | 
						|
  {
 | 
						|
    listenerList.add(HyperlinkListener.class, listener);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Removes a <code>HyperlinkListener</code> object to this editor pane.
 | 
						|
   *
 | 
						|
   * @param listener the listener to remove
 | 
						|
   */
 | 
						|
  public void removeHyperlinkListener(HyperlinkListener listener)
 | 
						|
  {
 | 
						|
    listenerList.remove(HyperlinkListener.class, listener);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns all added <code>HyperlinkListener</code> objects.
 | 
						|
   *
 | 
						|
   * @return array of listeners
 | 
						|
   *
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public HyperlinkListener[] getHyperlinkListeners()
 | 
						|
  {
 | 
						|
    return (HyperlinkListener[]) getListeners(HyperlinkListener.class);
 | 
						|
  }
 | 
						|
}
 |