From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libjava/classpath/javax/swing/JEditorPane.java | 1222 ++++++++++++++++++++++++ 1 file changed, 1222 insertions(+) create mode 100644 libjava/classpath/javax/swing/JEditorPane.java (limited to 'libjava/classpath/javax/swing/JEditorPane.java') diff --git a/libjava/classpath/javax/swing/JEditorPane.java b/libjava/classpath/javax/swing/JEditorPane.java new file mode 100644 index 000000000..8ad1095ee --- /dev/null +++ b/libjava/classpath/javax/swing/JEditorPane.java @@ -0,0 +1,1222 @@ +/* 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: + * + * + * @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 JEditorPane. + * + * @author Roman Kennke (kennke@aicas.com) + */ + protected class AccessibleJEditorPane extends AccessibleJTextComponent + { + + /** + * Creates a new AccessibleJEditorPane object. + */ + protected AccessibleJEditorPane() + { + super(); + } + + /** + * Returns a description of this AccessibleJEditorPane. 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 AccessibleJEditorPane. + * + * @return the accessible state of this AccessibleJEditorPane + */ + 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 JEditorPanes, 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 JEditorPane. This will + * be an instance of + * {@link JEditorPaneAccessibleHypertextSupport}. + * + * @return the accessible text of the JEditorPane + */ + 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 HTMLLink. + * + * @param el the link element + */ + public HTMLLink(Element el) + { + this.element = el; + } + + /** + * Returns true if this HTMLLink is still + * valid. A HTMLLink can become invalid when the document + * changes. + * + * @return true if this HTMLLink 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 true if the action has been performed + * successfully, false 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 i. + * 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 i + */ + 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 i. + * + * @param i the action index + * + * @return an {@link URL} object, that represents the action at action + * index i + */ + 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 String object is + * returned, if the link encloses an <img> tag, then an + * ImageIcon 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 i-th hyperlink in the document or + * null if there is no hyperlink with the specified index. + * + * @param i the index of the hyperlink to return + * + * @return the i-th hyperlink in the document or + * null 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 + * c within the document, or -1 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 + * c within the document, or -1 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 i, or + * null, 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 i, or + * null, 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 HyperlinkEvent 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 + * setEditorKitForContentType + * 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 true, + * 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 true when a Viewport should force the height of + * this component to match the viewport height. This is implemented to return + * true when the parent is an instance of JViewport and + * the viewport height > the UI's minimum height. + * + * @return true 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 true when a Viewport should force the width of + * this component to match the viewport width. This is implemented to return + * true when the parent is an instance of JViewport and + * the viewport width > the UI's minimum width. + * + * @return true 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 t + * 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 HyperlinkListener object to this editor pane. + * + * @param listener the listener to add + */ + public void addHyperlinkListener(HyperlinkListener listener) + { + listenerList.add(HyperlinkListener.class, listener); + } + + /** + * Removes a HyperlinkListener object to this editor pane. + * + * @param listener the listener to remove + */ + public void removeHyperlinkListener(HyperlinkListener listener) + { + listenerList.remove(HyperlinkListener.class, listener); + } + + /** + * Returns all added HyperlinkListener objects. + * + * @return array of listeners + * + * @since 1.4 + */ + public HyperlinkListener[] getHyperlinkListeners() + { + return (HyperlinkListener[]) getListeners(HyperlinkListener.class); + } +} -- cgit v1.2.3