2015-05-05 Yvan Roux <yvan.roux@linaro.org>
[official-gcc.git] / libjava / classpath / javax / swing / JEditorPane.java
blob8ad1095eedf4c3743f9edfab280e579df97dd15f
1 /* JEditorPane.java --
2 Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing;
41 import java.awt.Container;
42 import java.awt.Dimension;
43 import java.io.BufferedInputStream;
44 import java.io.FilterInputStream;
45 import java.io.IOException;
46 import java.io.InputStream;
47 import java.io.InputStreamReader;
48 import java.io.Reader;
49 import java.io.StringReader;
50 import java.net.MalformedURLException;
51 import java.net.URL;
52 import java.net.URLConnection;
53 import java.util.HashMap;
55 import javax.accessibility.AccessibleContext;
56 import javax.accessibility.AccessibleHyperlink;
57 import javax.accessibility.AccessibleHypertext;
58 import javax.accessibility.AccessibleStateSet;
59 import javax.accessibility.AccessibleText;
60 import javax.swing.event.HyperlinkEvent;
61 import javax.swing.event.HyperlinkListener;
62 import javax.swing.plaf.TextUI;
63 import javax.swing.text.AbstractDocument;
64 import javax.swing.text.BadLocationException;
65 import javax.swing.text.DefaultEditorKit;
66 import javax.swing.text.Document;
67 import javax.swing.text.EditorKit;
68 import javax.swing.text.Element;
69 import javax.swing.text.JTextComponent;
70 import javax.swing.text.View;
71 import javax.swing.text.ViewFactory;
72 import javax.swing.text.WrappedPlainView;
73 import javax.swing.text.html.HTML;
74 import javax.swing.text.html.HTMLDocument;
75 import javax.swing.text.html.HTMLEditorKit;
77 /**
78 * A powerful text editor component that can handle different types of
79 * content.
81 * The JEditorPane text component is driven by an instance of
82 * {@link EditorKit}. The editor kit is responsible for providing
83 * a default {@link Document} implementation, a mechanism for loading
84 * and saving documents of its supported content type and providing
85 * a set of {@link Action}s for manipulating the content.
87 * By default the following content types are supported:
88 * <ul>
89 * <li><code>text/plain</code>: Plain text, handled by
90 * {@link javax.swing.text.DefaultEditorKit}.</li>
91 * <li><code>text/html</code>: HTML 4.0 styled text, handled by
92 * {@link javax.swing.text.html.HTMLEditorKit}.</li>
93 * <li><code>text/rtf</code>: RTF text, handled by
94 * {@link javax.swing.text.rtf.RTFEditorKit}.</li>
95 * </ul>
97 * @author original author unknown
98 * @author Roman Kennke (roman@kennke.org)
99 * @author Anthony Balkissoon abalkiss at redhat dot com
101 public class JEditorPane extends JTextComponent
104 * Provides accessibility support for <code>JEditorPane</code>.
106 * @author Roman Kennke (kennke@aicas.com)
108 protected class AccessibleJEditorPane extends AccessibleJTextComponent
112 * Creates a new <code>AccessibleJEditorPane</code> object.
114 protected AccessibleJEditorPane()
116 super();
120 * Returns a description of this <code>AccessibleJEditorPane</code>. If
121 * this property is not set, then this returns the content-type of the
122 * editor pane.
124 * @return a description of this AccessibleJEditorPane
126 public String getAccessibleDescription()
128 String descr = super.getAccessibleDescription();
129 if (descr == null)
130 return getContentType();
131 else
132 return descr;
136 * Returns the accessible state of this <code>AccessibleJEditorPane</code>.
138 * @return the accessible state of this <code>AccessibleJEditorPane</code>
140 public AccessibleStateSet getAccessibleStateSet()
142 AccessibleStateSet state = super.getAccessibleStateSet();
143 // TODO: Figure out what state must be added here to the super's state.
144 return state;
149 * Provides accessibility support for <code>JEditorPane</code>s, when the
150 * editor kit is an instance of {@link HTMLEditorKit}.
152 * @author Roman Kennke (kennke@aicas.com)
154 protected class AccessibleJEditorPaneHTML extends AccessibleJEditorPane
157 * Returns the accessible text of the <code>JEditorPane</code>. This will
158 * be an instance of
159 * {@link JEditorPaneAccessibleHypertextSupport}.
161 * @return the accessible text of the <code>JEditorPane</code>
163 public AccessibleText getAccessibleText()
165 return new JEditorPaneAccessibleHypertextSupport();
170 * This is the accessible text that is returned by
171 * {@link AccessibleJEditorPaneHTML#getAccessibleText()}.
173 * @author Roman Kennke (kennke@aicas.com)
175 protected class JEditorPaneAccessibleHypertextSupport
176 extends AccessibleJEditorPane implements AccessibleHypertext
180 * Creates a new JEditorPaneAccessibleHypertextSupport object.
182 public JEditorPaneAccessibleHypertextSupport()
184 super();
188 * The accessible representation of a HTML link.
190 * @author Roman Kennke (kennke@aicas.com)
192 public class HTMLLink extends AccessibleHyperlink
196 * The element in the document that represents the link.
198 Element element;
201 * Creates a new <code>HTMLLink</code>.
203 * @param el the link element
205 public HTMLLink(Element el)
207 this.element = el;
211 * Returns <code>true</code> if this <code>HTMLLink</code> is still
212 * valid. A <code>HTMLLink</code> can become invalid when the document
213 * changes.
215 * @return <code>true</code> if this <code>HTMLLink</code> is still
216 * valid
218 public boolean isValid()
220 // I test here if the element at our element's start offset is the
221 // same as the element in the document at this offset. If this is true,
222 // I consider the link valid, if not, then this link no longer
223 // represented by this HTMLLink and therefor invalid.
224 HTMLDocument doc = (HTMLDocument) getDocument();
225 return doc.getCharacterElement(element.getStartOffset()) == element;
229 * Returns the number of AccessibleActions in this link object. In
230 * general, link have 1 AccessibleAction associated with them. There are
231 * special cases where links can have multiple actions associated, like
232 * in image maps.
234 * @return the number of AccessibleActions in this link object
236 public int getAccessibleActionCount()
238 // TODO: Implement the special cases.
239 return 1;
243 * Performs the specified action on the link object. This ususally means
244 * activating the link.
246 * @return <code>true</code> if the action has been performed
247 * successfully, <code>false</code> otherwise
249 public boolean doAccessibleAction(int i)
251 String href = (String) element.getAttributes().getAttribute("href");
252 HTMLDocument doc = (HTMLDocument) getDocument();
255 URL url = new URL(doc.getBase(), href);
256 setPage(url);
257 String desc = doc.getText(element.getStartOffset(),
258 element.getEndOffset() - element.getStartOffset());
259 HyperlinkEvent ev =
260 new HyperlinkEvent(JEditorPane.this,
261 HyperlinkEvent.EventType.ACTIVATED, url, desc,
262 element);
263 fireHyperlinkUpdate(ev);
264 return true;
266 catch (Exception ex)
268 return false;
273 * Returns the description of the action at action index <code>i</code>.
274 * This method returns the text within the element associated with this
275 * link.
277 * @param i the action index
279 * @return the description of the action at action index <code>i</code>
281 public String getAccessibleActionDescription(int i)
283 HTMLDocument doc = (HTMLDocument) getDocument();
286 return doc.getText(element.getStartOffset(),
287 element.getEndOffset() - element.getStartOffset());
289 catch (BadLocationException ex)
291 throw (AssertionError)
292 new AssertionError("BadLocationException must not be thrown "
293 + "here.")
294 .initCause(ex);
299 * Returns an {@link URL} object, that represents the action at action
300 * index <code>i</code>.
302 * @param i the action index
304 * @return an {@link URL} object, that represents the action at action
305 * index <code>i</code>
307 public Object getAccessibleActionObject(int i)
309 String href = (String) element.getAttributes().getAttribute("href");
310 HTMLDocument doc = (HTMLDocument) getDocument();
313 URL url = new URL(doc.getBase(), href);
314 return url;
316 catch (MalformedURLException ex)
318 return null;
323 * Returns an object that represents the link anchor. For examples, if
324 * the link encloses a string, then a <code>String</code> object is
325 * returned, if the link encloses an &lt;img&gt; tag, then an
326 * <code>ImageIcon</code> object is returned.
328 * @return an object that represents the link anchor
330 public Object getAccessibleActionAnchor(int i)
332 // TODO: This is only the String case. Implement all cases.
333 return getAccessibleActionDescription(i);
337 * Returns the start index of the hyperlink element.
339 * @return the start index of the hyperlink element
341 public int getStartIndex()
343 return element.getStartOffset();
347 * Returns the end index of the hyperlink element.
349 * @return the end index of the hyperlink element
351 public int getEndIndex()
353 return element.getEndOffset();
359 * Returns the number of hyperlinks in the document.
361 * @return the number of hyperlinks in the document
363 public int getLinkCount()
365 HTMLDocument doc = (HTMLDocument) getDocument();
366 HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
367 int count = 0;
368 while (linkIter.isValid())
370 count++;
371 linkIter.next();
373 return count;
377 * Returns the <code>i</code>-th hyperlink in the document or
378 * <code>null</code> if there is no hyperlink with the specified index.
380 * @param i the index of the hyperlink to return
382 * @return the <code>i</code>-th hyperlink in the document or
383 * <code>null</code> if there is no hyperlink with the specified
384 * index
386 public AccessibleHyperlink getLink(int i)
388 HTMLDocument doc = (HTMLDocument) getDocument();
389 HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
390 int count = 0;
391 while (linkIter.isValid())
393 count++;
394 if (count == i)
395 break;
396 linkIter.next();
398 if (linkIter.isValid())
400 int offset = linkIter.getStartOffset();
401 // TODO: I fetch the element for the link via getCharacterElement().
402 // I am not sure that this is correct, maybe we must use
403 // getParagraphElement()?
404 Element el = doc.getCharacterElement(offset);
405 HTMLLink link = new HTMLLink(el);
406 return link;
408 else
409 return null;
413 * Returns the index of the link element at the character position
414 * <code>c</code> within the document, or <code>-1</code> if there is no
415 * link at the specified position.
417 * @param c the character index from which to fetch the link index
419 * @return the index of the link element at the character position
420 * <code>c</code> within the document, or <code>-1</code> if there
421 * is no link at the specified position
423 public int getLinkIndex(int c)
425 HTMLDocument doc = (HTMLDocument) getDocument();
426 HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
427 int count = 0;
428 while (linkIter.isValid())
430 if (linkIter.getStartOffset() <= c && linkIter.getEndOffset() > c)
431 break;
432 count++;
433 linkIter.next();
435 if (linkIter.isValid())
436 return count;
437 else
438 return -1;
442 * Returns the link text of the link at index <code>i</code>, or
443 * <code>null</code>, if there is no link at the specified position.
445 * @param i the index of the link
447 * @return the link text of the link at index <code>i</code>, or
448 * <code>null</code>, if there is no link at the specified
449 * position
451 public String getLinkText(int i)
453 HTMLDocument doc = (HTMLDocument) getDocument();
454 HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
455 int count = 0;
456 while (linkIter.isValid())
458 count++;
459 if (count == i)
460 break;
461 linkIter.next();
463 if (linkIter.isValid())
465 int offset = linkIter.getStartOffset();
466 // TODO: I fetch the element for the link via getCharacterElement().
467 // I am not sure that this is correct, maybe we must use
468 // getParagraphElement()?
469 Element el = doc.getCharacterElement(offset);
472 String text = doc.getText(el.getStartOffset(),
473 el.getEndOffset() - el.getStartOffset());
474 return text;
476 catch (BadLocationException ex)
478 throw (AssertionError)
479 new AssertionError("BadLocationException must not be thrown "
480 + "here.")
481 .initCause(ex);
484 else
485 return null;
490 * Used to store a mapping for content-type to editor kit class.
492 private static class EditorKitMapping
495 * The classname of the editor kit.
497 String className;
500 * The classloader with which the kit is to be loaded.
502 ClassLoader classLoader;
505 * Creates a new EditorKitMapping object.
507 * @param cn the classname
508 * @param cl the classloader
510 EditorKitMapping(String cn, ClassLoader cl)
512 className = cn;
513 classLoader = cl;
518 * An EditorKit used for plain text. This is the default editor kit for
519 * JEditorPanes.
521 * @author Roman Kennke (kennke@aicas.com)
523 private static class PlainEditorKit extends DefaultEditorKit
527 * Returns a ViewFactory that supplies WrappedPlainViews.
529 public ViewFactory getViewFactory()
531 return new ViewFactory()
533 public View create(Element el)
535 return new WrappedPlainView(el);
542 * A special stream that can be cancelled.
544 private class PageStream
545 extends FilterInputStream
548 * True when the stream has been cancelled, false otherwise.
550 private boolean cancelled;
552 protected PageStream(InputStream in)
554 super(in);
555 cancelled = false;
558 private void checkCancelled()
559 throws IOException
561 if (cancelled)
562 throw new IOException("Stream has been cancelled");
565 void cancel()
567 cancelled = true;
570 public int read()
571 throws IOException
573 checkCancelled();
574 return super.read();
577 public int read(byte[] b, int off, int len)
578 throws IOException
580 checkCancelled();
581 return super.read(b, off, len);
584 public long skip(long n)
585 throws IOException
587 checkCancelled();
588 return super.skip(n);
591 public int available()
592 throws IOException
594 checkCancelled();
595 return super.available();
598 public void reset()
599 throws IOException
601 checkCancelled();
602 super.reset();
607 * The thread that loads documents asynchronously.
609 private class PageLoader
610 implements Runnable
612 private Document doc;
613 private PageStream in;
614 private URL old;
615 URL page;
616 PageLoader(Document doc, InputStream in, URL old, URL page)
618 this.doc = doc;
619 this.in = new PageStream(in);
620 this.old = old;
621 this.page = page;
624 public void run()
628 read(in, doc);
630 catch (IOException ex)
632 UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this);
634 finally
636 if (SwingUtilities.isEventDispatchThread())
637 firePropertyChange("page", old, page);
638 else
640 SwingUtilities.invokeLater(new Runnable()
642 public void run()
644 firePropertyChange("page", old, page);
651 void cancel()
653 in.cancel();
657 private static final long serialVersionUID = 3140472492599046285L;
659 private EditorKit editorKit;
661 boolean focus_root;
664 * Maps content-types to editor kit instances.
666 static HashMap editorKits;
668 // A mapping between content types and registered EditorKit types
669 static HashMap registerMap;
671 static
673 registerMap = new HashMap();
674 editorKits = new HashMap();
675 registerEditorKitForContentType("application/rtf",
676 "javax.swing.text.rtf.RTFEditorKit");
677 registerEditorKitForContentType("text/plain",
678 "javax.swing.JEditorPane$PlainEditorKit");
679 registerEditorKitForContentType("text/html",
680 "javax.swing.text.html.HTMLEditorKit");
681 registerEditorKitForContentType("text/rtf",
682 "javax.swing.text.rtf.RTFEditorKit");
686 // A mapping between content types and used EditorKits
687 HashMap editorMap;
690 * The currently loading stream, if any.
692 private PageLoader loader;
694 public JEditorPane()
696 init();
697 setEditorKit(createDefaultEditorKit());
700 public JEditorPane(String url) throws IOException
702 this(new URL(url));
705 public JEditorPane(String type, String text)
707 init();
708 setEditorKit(createEditorKitForContentType(type));
709 setText(text);
712 public JEditorPane(URL url) throws IOException
714 init();
715 setEditorKit(createEditorKitForContentType("text/html"));
716 setPage(url);
720 * Called by the constructors to set up the default bindings for content
721 * types and EditorKits.
723 void init()
725 editorMap = new HashMap();
728 protected EditorKit createDefaultEditorKit()
730 return new PlainEditorKit();
734 * Creates and returns an EditorKit that is appropriate for the given
735 * content type. This is created using the default recognized types
736 * plus any EditorKit types that have been registered.
738 * @see #registerEditorKitForContentType(String, String)
739 * @see #registerEditorKitForContentType(String, String, ClassLoader)
740 * @param type the content type
741 * @return an EditorKit for use with the given content type
743 public static EditorKit createEditorKitForContentType(String type)
745 // Try cached instance.
746 EditorKit e = (EditorKit) editorKits.get(type);
747 if (e == null)
749 EditorKitMapping m = (EditorKitMapping) registerMap.get(type);
750 if (m != null)
752 String className = m.className;
753 ClassLoader loader = m.classLoader;
756 e = (EditorKit) loader.loadClass(className).newInstance();
758 catch (Exception e2)
760 // The reference implementation returns null when class is not
761 // loadable or instantiatable.
764 // Cache this for later retrieval.
765 if (e != null)
766 editorKits.put(type, e);
768 return e;
772 * Sends a given <code>HyperlinkEvent</code> to all registered listeners.
774 * @param event the event to send
776 public void fireHyperlinkUpdate(HyperlinkEvent event)
778 HyperlinkListener[] listeners = getHyperlinkListeners();
780 for (int index = 0; index < listeners.length; ++index)
781 listeners[index].hyperlinkUpdate(event);
785 * Returns the accessible context associated with this editor pane.
787 * @return the accessible context associated with this editor pane
789 public AccessibleContext getAccessibleContext()
791 if (accessibleContext == null)
793 if (getEditorKit() instanceof HTMLEditorKit)
794 accessibleContext = new AccessibleJEditorPaneHTML();
795 else
796 accessibleContext = new AccessibleJEditorPane();
798 return accessibleContext;
801 public final String getContentType()
803 return getEditorKit().getContentType();
807 * Returns the EditorKit. If there is no EditorKit set this method
808 * calls createDefaultEditorKit() and setEditorKit() first.
810 public EditorKit getEditorKit()
812 if (editorKit == null)
813 setEditorKit(createDefaultEditorKit());
814 return editorKit;
818 * Returns the class name of the EditorKit associated with the given
819 * content type.
821 * @since 1.3
822 * @param type the content type
823 * @return the class name of the EditorKit associated with this content type
825 public static String getEditorKitClassNameForContentType(String type)
827 EditorKitMapping m = (EditorKitMapping) registerMap.get(type);
828 String kitName = m != null ? m.className : null;
829 return kitName;
833 * Returns the EditorKit to use for the given content type. If an
834 * EditorKit has been explicitly set via
835 * <code>setEditorKitForContentType</code>
836 * then it will be returned. Otherwise an attempt will be made to create
837 * an EditorKit from the default recognzied content types or any
838 * EditorKits that have been registered. If none can be created, a
839 * PlainEditorKit is created.
841 * @see #registerEditorKitForContentType(String, String)
842 * @see #registerEditorKitForContentType(String, String, ClassLoader)
843 * @param type the content type
844 * @return an appropriate EditorKit for the given content type
846 public EditorKit getEditorKitForContentType(String type)
848 // First check if an EditorKit has been explicitly set.
849 EditorKit e = (EditorKit) editorMap.get(type);
850 // Then check to see if we can create one.
851 if (e == null)
853 e = createEditorKitForContentType(type);
854 if (e != null)
855 setEditorKitForContentType(type, e);
857 // Otherwise default to PlainEditorKit.
858 if (e == null)
859 e = createDefaultEditorKit();
860 return e;
864 * Returns the preferred size for the JEditorPane. This is implemented to
865 * return the super's preferred size, unless one of
866 * {@link #getScrollableTracksViewportHeight()} or
867 * {@link #getScrollableTracksViewportWidth()} returns <code>true</code>,
868 * in which case the preferred width and/or height is replaced by the UI's
869 * minimum size.
871 * @return the preferred size for the JEditorPane
873 public Dimension getPreferredSize()
875 Dimension pref = super.getPreferredSize();
876 Container parent = getParent();
877 if (parent instanceof JViewport)
879 JViewport vp = (JViewport) getParent();
880 TextUI ui = getUI();
881 Dimension min = null;
882 if (! getScrollableTracksViewportWidth())
884 min = ui.getMinimumSize(this);
885 int vpWidth = vp.getWidth();
886 if (vpWidth != 0 && vpWidth < min.width)
887 pref.width = min.width;
889 if (! getScrollableTracksViewportHeight())
891 if (min == null)
892 min = ui.getMinimumSize(this);
893 int vpHeight = vp.getHeight();
894 if (vpHeight != 0 && vpHeight < min.height)
895 pref.height = min.height;
898 return pref;
902 * Returns <code>true</code> when a Viewport should force the height of
903 * this component to match the viewport height. This is implemented to return
904 * <code>true</code> when the parent is an instance of JViewport and
905 * the viewport height > the UI's minimum height.
907 * @return <code>true</code> when a Viewport should force the height of
908 * this component to match the viewport height
910 public boolean getScrollableTracksViewportHeight()
912 // Tests show that this returns true when the parent is a JViewport
913 // and has a height > minimum UI height.
914 Container parent = getParent();
915 int height = parent.getHeight();
916 TextUI ui = getUI();
917 return parent instanceof JViewport
918 && height >= ui.getMinimumSize(this).height
919 && height <= ui.getMaximumSize(this).height;
923 * Returns <code>true</code> when a Viewport should force the width of
924 * this component to match the viewport width. This is implemented to return
925 * <code>true</code> when the parent is an instance of JViewport and
926 * the viewport width > the UI's minimum width.
928 * @return <code>true</code> when a Viewport should force the width of
929 * this component to match the viewport width
931 public boolean getScrollableTracksViewportWidth()
933 // Tests show that this returns true when the parent is a JViewport
934 // and has a width > minimum UI width.
935 Container parent = getParent();
936 return parent != null && parent instanceof JViewport
937 && parent.getWidth() > getUI().getMinimumSize(this).width;
940 public URL getPage()
942 return loader != null ? loader.page : null;
945 protected InputStream getStream(URL page)
946 throws IOException
948 URLConnection conn = page.openConnection();
949 // Try to detect the content type of the stream data.
950 String type = conn.getContentType();
951 if (type != null)
952 setContentType(type);
953 InputStream stream = conn.getInputStream();
954 return new BufferedInputStream(stream);
957 public String getText()
959 return super.getText();
962 public String getUIClassID()
964 return "EditorPaneUI";
967 public boolean isFocusCycleRoot()
969 return focus_root;
972 protected String paramString()
974 return "JEditorPane";
978 * This method initializes from a stream.
980 public void read(InputStream in, Object desc) throws IOException
982 EditorKit kit = getEditorKit();
983 if (kit instanceof HTMLEditorKit && desc instanceof HTMLDocument)
985 HTMLDocument doc = (HTMLDocument) desc;
986 setDocument(doc);
989 InputStreamReader reader = new InputStreamReader(in);
990 kit.read(reader, doc, 0);
992 catch (BadLocationException ex)
994 assert false : "BadLocationException must not be thrown here.";
997 else
999 Reader inRead = new InputStreamReader(in);
1000 super.read(inRead, desc);
1005 * Establishes a binding between type and classname. This enables
1006 * us to create an EditorKit later for the given content type.
1008 * @param type the content type
1009 * @param classname the name of the class that is associated with this
1010 * content type
1012 public static void registerEditorKitForContentType(String type,
1013 String classname)
1015 registerEditorKitForContentType(type, classname,
1016 Thread.currentThread().getContextClassLoader());
1020 * Establishes the default bindings of type to classname.
1022 public static void registerEditorKitForContentType(String type,
1023 String classname,
1024 ClassLoader loader)
1026 registerMap.put(type, new EditorKitMapping(classname, loader));
1030 * Replaces the currently selected content with new content represented
1031 * by the given string.
1033 public void replaceSelection(String content)
1035 // TODO: Implement this properly.
1036 super.replaceSelection(content);
1040 * Scrolls the view to the given reference location (that is, the value
1041 * returned by the UL.getRef method for the URL being displayed).
1043 public void scrollToReference(String reference)
1045 // TODO: Implement this properly.
1048 public final void setContentType(String type)
1050 // Strip off content type parameters.
1051 int paramIndex = type.indexOf(';');
1052 if (paramIndex > -1)
1054 // TODO: Handle character encoding.
1055 type = type.substring(0, paramIndex).trim();
1057 if (editorKit != null
1058 && editorKit.getContentType().equals(type))
1059 return;
1061 EditorKit kit = getEditorKitForContentType(type);
1063 if (kit != null)
1064 setEditorKit(kit);
1067 public void setEditorKit(EditorKit newValue)
1069 if (editorKit == newValue)
1070 return;
1072 if (editorKit != null)
1073 editorKit.deinstall(this);
1075 EditorKit oldValue = editorKit;
1076 editorKit = newValue;
1078 if (editorKit != null)
1080 editorKit.install(this);
1081 setDocument(editorKit.createDefaultDocument());
1084 firePropertyChange("editorKit", oldValue, newValue);
1085 invalidate();
1086 repaint();
1087 // Reset the accessibleContext since this depends on the editorKit.
1088 accessibleContext = null;
1092 * Explicitly sets an EditorKit to be used for the given content type.
1093 * @param type the content type
1094 * @param k the EditorKit to use for the given content type
1096 public void setEditorKitForContentType(String type, EditorKit k)
1098 editorMap.put(type, k);
1102 * Sets the current URL being displayed.
1104 public void setPage(String url) throws IOException
1106 setPage(new URL(url));
1110 * Sets the current URL being displayed.
1112 public void setPage(URL page) throws IOException
1114 if (page == null)
1115 throw new IOException("invalid url");
1117 URL old = getPage();
1118 // Only reload if the URL doesn't point to the same file.
1119 // This is not the same as equals because there might be different
1120 // URLs on the same file with different anchors.
1121 if (old == null || ! old.sameFile(page))
1123 InputStream in = getStream(page);
1124 if (editorKit != null)
1126 Document doc = editorKit.createDefaultDocument();
1127 doc.putProperty(Document.StreamDescriptionProperty, page);
1129 if (loader != null)
1130 loader.cancel();
1131 loader = new PageLoader(doc, in, old, page);
1133 int prio = -1;
1134 if (doc instanceof AbstractDocument)
1136 AbstractDocument aDoc = (AbstractDocument) doc;
1137 prio = aDoc.getAsynchronousLoadPriority();
1139 if (prio >= 0)
1141 // Load asynchronously.
1142 setDocument(doc);
1143 Thread loadThread = new Thread(loader,
1144 "JEditorPane.PageLoader");
1145 loadThread.setDaemon(true);
1146 loadThread.setPriority(prio);
1147 loadThread.start();
1149 else
1151 // Load synchronously.
1152 loader.run();
1153 setDocument(doc);
1160 * Sets the text of the JEditorPane. The argument <code>t</code>
1161 * is expected to be in the format of the current EditorKit. This removes
1162 * the content of the current document and uses the EditorKit to read in the
1163 * new text. This allows the EditorKit to handle the String rather than just
1164 * inserting in plain text.
1166 * @param t the text to display in this JEditorPane
1168 public void setText(String t)
1172 // Remove the current content.
1173 Document doc = getDocument();
1174 doc.remove(0, doc.getLength());
1175 if (t == null || t.equals(""))
1176 return;
1178 // Let the EditorKit read the text into the Document.
1179 getEditorKit().read(new StringReader(t), doc, 0);
1181 catch (BadLocationException ble)
1183 // TODO: Don't know what to do here.
1185 catch (IOException ioe)
1187 // TODO: Don't know what to do here.
1192 * Add a <code>HyperlinkListener</code> object to this editor pane.
1194 * @param listener the listener to add
1196 public void addHyperlinkListener(HyperlinkListener listener)
1198 listenerList.add(HyperlinkListener.class, listener);
1202 * Removes a <code>HyperlinkListener</code> object to this editor pane.
1204 * @param listener the listener to remove
1206 public void removeHyperlinkListener(HyperlinkListener listener)
1208 listenerList.remove(HyperlinkListener.class, listener);
1212 * Returns all added <code>HyperlinkListener</code> objects.
1214 * @return array of listeners
1216 * @since 1.4
1218 public HyperlinkListener[] getHyperlinkListeners()
1220 return (HyperlinkListener[]) getListeners(HyperlinkListener.class);