GNU Classpath (0.20) | |
Frames | No Frames |
1: /* JEditorPane.java -- 2: Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 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. 10: 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. 15: 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. 20: 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. 25: 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. */ 37: 38: 39: package javax.swing; 40: 41: import java.awt.Dimension; 42: import java.io.IOException; 43: import java.io.InputStream; 44: import java.io.InputStreamReader; 45: import java.io.Reader; 46: import java.io.StringReader; 47: import java.net.MalformedURLException; 48: import java.net.URL; 49: import java.util.HashMap; 50: 51: import javax.accessibility.AccessibleContext; 52: import javax.accessibility.AccessibleHyperlink; 53: import javax.accessibility.AccessibleHypertext; 54: import javax.accessibility.AccessibleStateSet; 55: import javax.accessibility.AccessibleText; 56: import javax.swing.event.HyperlinkEvent; 57: import javax.swing.event.HyperlinkListener; 58: import javax.swing.text.BadLocationException; 59: import javax.swing.text.DefaultEditorKit; 60: import javax.swing.text.Document; 61: import javax.swing.text.EditorKit; 62: import javax.swing.text.Element; 63: import javax.swing.text.JTextComponent; 64: import javax.swing.text.View; 65: import javax.swing.text.ViewFactory; 66: import javax.swing.text.WrappedPlainView; 67: import javax.swing.text.html.HTML; 68: import javax.swing.text.html.HTMLDocument; 69: import javax.swing.text.html.HTMLEditorKit; 70: 71: /** 72: * A powerful text editor component that can handle different types of 73: * content. 74: * 75: * The JEditorPane text component is driven by an instance of 76: * {@link EditorKit}. The editor kit is responsible for providing 77: * a default {@link Document} implementation, a mechanism for loading 78: * and saving documents of its supported content type and providing 79: * a set of {@link Action}s for manipulating the content. 80: * 81: * By default the following content types are supported: 82: * <ul> 83: * <li><code>text/plain</code>: Plain text, handled by 84: * {@link javax.swing.text.DefaultEditorKit}.</li> 85: * <li><code>text/html</code>: HTML 4.0 styled text, handled by 86: * {@link javax.swing.text.html.HTMLEditorKit}.</li> 87: * <li><code>text/rtf</code>: RTF text, handled by 88: * {@link javax.swing.text.rtf.RTFEditorKit}.</li> 89: * </ul> 90: * 91: * @author original author unknown 92: * @author Roman Kennke (roman@kennke.org) 93: * @author Anthony Balkissoon abalkiss at redhat dot com 94: */ 95: public class JEditorPane extends JTextComponent 96: { 97: /** 98: * Provides accessibility support for <code>JEditorPane</code>. 99: * 100: * @author Roman Kennke (kennke@aicas.com) 101: */ 102: protected class AccessibleJEditorPane extends AccessibleJTextComponent 103: { 104: 105: /** 106: * Creates a new <code>AccessibleJEditorPane</code> object. 107: */ 108: protected AccessibleJEditorPane() 109: { 110: super(); 111: } 112: 113: /** 114: * Returns a description of this <code>AccessibleJEditorPane</code>. If 115: * this property is not set, then this returns the content-type of the 116: * editor pane. 117: * 118: * @return a description of this AccessibleJEditorPane 119: */ 120: public String getAccessibleDescription() 121: { 122: String descr = super.getAccessibleDescription(); 123: if (descr == null) 124: return getContentType(); 125: else 126: return descr; 127: } 128: 129: /** 130: * Returns the accessible state of this <code>AccessibleJEditorPane</code>. 131: * 132: * @return the accessible state of this <code>AccessibleJEditorPane</code> 133: */ 134: public AccessibleStateSet getAccessibleStateSet() 135: { 136: AccessibleStateSet state = super.getAccessibleStateSet(); 137: // TODO: Figure out what state must be added here to the super's state. 138: return state; 139: } 140: } 141: 142: /** 143: * Provides accessibility support for <code>JEditorPane</code>s, when the 144: * editor kit is an instance of {@link HTMLEditorKit}. 145: * 146: * @author Roman Kennke (kennke@aicas.com) 147: */ 148: protected class AccessibleJEditorPaneHTML extends AccessibleJEditorPane 149: { 150: /** 151: * Returns the accessible text of the <code>JEditorPane</code>. This will 152: * be an instance of 153: * {@link JEditorPaneAccessibleHypertextSupport}. 154: * 155: * @return the accessible text of the <code>JEditorPane</code> 156: */ 157: public AccessibleText getAccessibleText() 158: { 159: return new JEditorPaneAccessibleHypertextSupport(); 160: } 161: } 162: 163: /** 164: * This is the accessible text that is returned by 165: * {@link AccessibleJEditorPaneHTML#getAccessibleText()}. 166: * 167: * @author Roman Kennke (kennke@aicas.com) 168: */ 169: protected class JEditorPaneAccessibleHypertextSupport 170: extends AccessibleJEditorPane implements AccessibleHypertext 171: { 172: 173: /** 174: * Creates a new JEditorPaneAccessibleHypertextSupport object. 175: */ 176: public JEditorPaneAccessibleHypertextSupport() 177: { 178: super(); 179: } 180: 181: /** 182: * The accessible representation of a HTML link. 183: * 184: * @author Roman Kennke (kennke@aicas.com) 185: */ 186: public class HTMLLink extends AccessibleHyperlink 187: { 188: 189: /** 190: * The element in the document that represents the link. 191: */ 192: Element element; 193: 194: /** 195: * Creates a new <code>HTMLLink</code>. 196: * 197: * @param el the link element 198: */ 199: public HTMLLink(Element el) 200: { 201: this.element = el; 202: } 203: 204: /** 205: * Returns <code>true</code> if this <code>HTMLLink</code> is still 206: * valid. A <code>HTMLLink</code> can become invalid when the document 207: * changes. 208: * 209: * @return <code>true</code> if this <code>HTMLLink</code> is still 210: * valid 211: */ 212: public boolean isValid() 213: { 214: // I test here if the element at our element's start offset is the 215: // same as the element in the document at this offset. If this is true, 216: // I consider the link valid, if not, then this link no longer 217: // represented by this HTMLLink and therefor invalid. 218: HTMLDocument doc = (HTMLDocument) getDocument(); 219: return doc.getCharacterElement(element.getStartOffset()) == element; 220: } 221: 222: /** 223: * Returns the number of AccessibleActions in this link object. In 224: * general, link have 1 AccessibleAction associated with them. There are 225: * special cases where links can have multiple actions associated, like 226: * in image maps. 227: * 228: * @return the number of AccessibleActions in this link object 229: */ 230: public int getAccessibleActionCount() 231: { 232: // TODO: Implement the special cases. 233: return 1; 234: } 235: 236: /** 237: * Performs the specified action on the link object. This ususally means 238: * activating the link. 239: * 240: * @return <code>true</code> if the action has been performed 241: * successfully, <code>false</code> otherwise 242: */ 243: public boolean doAccessibleAction(int i) 244: { 245: String href = (String) element.getAttributes().getAttribute("href"); 246: HTMLDocument doc = (HTMLDocument) getDocument(); 247: try 248: { 249: URL url = new URL(doc.getBase(), href); 250: setPage(url); 251: String desc = doc.getText(element.getStartOffset(), 252: element.getEndOffset() - element.getStartOffset()); 253: HyperlinkEvent ev = 254: new HyperlinkEvent(JEditorPane.this, 255: HyperlinkEvent.EventType.ACTIVATED, url, desc, 256: element); 257: fireHyperlinkUpdate(ev); 258: return true; 259: } 260: catch (Exception ex) 261: { 262: return false; 263: } 264: } 265: 266: /** 267: * Returns the description of the action at action index <code>i</code>. 268: * This method returns the text within the element associated with this 269: * link. 270: * 271: * @param i the action index 272: * 273: * @return the description of the action at action index <code>i</code> 274: */ 275: public String getAccessibleActionDescription(int i) 276: { 277: HTMLDocument doc = (HTMLDocument) getDocument(); 278: try 279: { 280: return doc.getText(element.getStartOffset(), 281: element.getEndOffset() - element.getStartOffset()); 282: } 283: catch (BadLocationException ex) 284: { 285: throw (AssertionError) 286: new AssertionError("BadLocationException must not be thrown " 287: + "here.") 288: .initCause(ex); 289: } 290: } 291: 292: /** 293: * Returns an {@link URL} object, that represents the action at action 294: * index <code>i</code>. 295: * 296: * @param i the action index 297: * 298: * @return an {@link URL} object, that represents the action at action 299: * index <code>i</code> 300: */ 301: public Object getAccessibleActionObject(int i) 302: { 303: String href = (String) element.getAttributes().getAttribute("href"); 304: HTMLDocument doc = (HTMLDocument) getDocument(); 305: try 306: { 307: URL url = new URL(doc.getBase(), href); 308: return url; 309: } 310: catch (MalformedURLException ex) 311: { 312: return null; 313: } 314: } 315: 316: /** 317: * Returns an object that represents the link anchor. For examples, if 318: * the link encloses a string, then a <code>String</code> object is 319: * returned, if the link encloses an <img> tag, then an 320: * <code>ImageIcon</code> object is returned. 321: * 322: * @return an object that represents the link anchor 323: */ 324: public Object getAccessibleActionAnchor(int i) 325: { 326: // TODO: This is only the String case. Implement all cases. 327: return getAccessibleActionDescription(i); 328: } 329: 330: /** 331: * Returns the start index of the hyperlink element. 332: * 333: * @return the start index of the hyperlink element 334: */ 335: public int getStartIndex() 336: { 337: return element.getStartOffset(); 338: } 339: 340: /** 341: * Returns the end index of the hyperlink element. 342: * 343: * @return the end index of the hyperlink element 344: */ 345: public int getEndIndex() 346: { 347: return element.getEndOffset(); 348: } 349: 350: } 351: 352: /** 353: * Returns the number of hyperlinks in the document. 354: * 355: * @return the number of hyperlinks in the document 356: */ 357: public int getLinkCount() 358: { 359: HTMLDocument doc = (HTMLDocument) getDocument(); 360: HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A); 361: int count = 0; 362: while (linkIter.isValid()) 363: { 364: count++; 365: linkIter.next(); 366: } 367: return count; 368: } 369: 370: /** 371: * Returns the <code>i</code>-th hyperlink in the document or 372: * <code>null</code> if there is no hyperlink with the specified index. 373: * 374: * @param i the index of the hyperlink to return 375: * 376: * @return the <code>i</code>-th hyperlink in the document or 377: * <code>null</code> if there is no hyperlink with the specified 378: * index 379: */ 380: public AccessibleHyperlink getLink(int i) 381: { 382: HTMLDocument doc = (HTMLDocument) getDocument(); 383: HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A); 384: int count = 0; 385: while (linkIter.isValid()) 386: { 387: count++; 388: if (count == i) 389: break; 390: linkIter.next(); 391: } 392: if (linkIter.isValid()) 393: { 394: int offset = linkIter.getStartOffset(); 395: // TODO: I fetch the element for the link via getCharacterElement(). 396: // I am not sure that this is correct, maybe we must use 397: // getParagraphElement()? 398: Element el = doc.getCharacterElement(offset); 399: HTMLLink link = new HTMLLink(el); 400: return link; 401: } 402: else 403: return null; 404: } 405: 406: /** 407: * Returns the index of the link element at the character position 408: * <code>c</code> within the document, or <code>-1</code> if there is no 409: * link at the specified position. 410: * 411: * @param c the character index from which to fetch the link index 412: * 413: * @return the index of the link element at the character position 414: * <code>c</code> within the document, or <code>-1</code> if there 415: * is no link at the specified position 416: */ 417: public int getLinkIndex(int c) 418: { 419: HTMLDocument doc = (HTMLDocument) getDocument(); 420: HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A); 421: int count = 0; 422: while (linkIter.isValid()) 423: { 424: if (linkIter.getStartOffset() <= c && linkIter.getEndOffset() > c) 425: break; 426: count++; 427: linkIter.next(); 428: } 429: if (linkIter.isValid()) 430: return count; 431: else 432: return -1; 433: } 434: 435: /** 436: * Returns the link text of the link at index <code>i</code>, or 437: * <code>null</code>, if there is no link at the specified position. 438: * 439: * @param i the index of the link 440: * 441: * @return the link text of the link at index <code>i</code>, or 442: * <code>null</code>, if there is no link at the specified 443: * position 444: */ 445: public String getLinkText(int i) 446: { 447: HTMLDocument doc = (HTMLDocument) getDocument(); 448: HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A); 449: int count = 0; 450: while (linkIter.isValid()) 451: { 452: count++; 453: if (count == i) 454: break; 455: linkIter.next(); 456: } 457: if (linkIter.isValid()) 458: { 459: int offset = linkIter.getStartOffset(); 460: // TODO: I fetch the element for the link via getCharacterElement(). 461: // I am not sure that this is correct, maybe we must use 462: // getParagraphElement()? 463: Element el = doc.getCharacterElement(offset); 464: try 465: { 466: String text = doc.getText(el.getStartOffset(), 467: el.getEndOffset() - el.getStartOffset()); 468: return text; 469: } 470: catch (BadLocationException ex) 471: { 472: throw (AssertionError) 473: new AssertionError("BadLocationException must not be thrown " 474: + "here.") 475: .initCause(ex); 476: } 477: } 478: else 479: return null; 480: } 481: } 482: 483: /** 484: * An EditorKit used for plain text. This is the default editor kit for 485: * JEditorPanes. 486: * 487: * @author Roman Kennke (kennke@aicas.com) 488: */ 489: private static class PlainEditorKit extends DefaultEditorKit 490: { 491: 492: /** 493: * Returns a ViewFactory that supplies WrappedPlainViews. 494: */ 495: public ViewFactory getViewFactory() 496: { 497: return new ViewFactory() 498: { 499: public View create(Element el) 500: { 501: return new WrappedPlainView(el); 502: } 503: }; 504: } 505: } 506: 507: private static final long serialVersionUID = 3140472492599046285L; 508: 509: private URL page; 510: private EditorKit editorKit; 511: 512: boolean focus_root; 513: 514: // A mapping between content types and registered EditorKit types 515: static HashMap registerMap; 516: 517: // A mapping between content types and used EditorKits 518: HashMap editorMap; 519: 520: public JEditorPane() 521: { 522: init(); 523: setEditorKit(createDefaultEditorKit()); 524: } 525: 526: public JEditorPane(String url) throws IOException 527: { 528: this(new URL(url)); 529: } 530: 531: public JEditorPane(String type, String text) 532: { 533: init(); 534: setEditorKit(createEditorKitForContentType(type)); 535: setText(text); 536: } 537: 538: public JEditorPane(URL url) throws IOException 539: { 540: init (); 541: setEditorKit (createEditorKitForContentType("text/html"));; 542: setPage(url); 543: } 544: 545: /** 546: * Called by the constructors to set up the default bindings for content 547: * types and EditorKits. 548: */ 549: void init() 550: { 551: editorMap = new HashMap(); 552: registerMap = new HashMap(); 553: registerEditorKitForContentType("application/rtf", 554: "javax.swing.text.rtf.RTFEditorKit"); 555: registerEditorKitForContentType("text/plain", 556: "javax.swing.JEditorPane$PlainEditorKit"); 557: registerEditorKitForContentType("text/html", 558: "javax.swing.text.html.HTMLEditorKit"); 559: registerEditorKitForContentType("text/rtf", 560: "javax.swing.text.rtf.RTFEditorKit"); 561: } 562: 563: protected EditorKit createDefaultEditorKit() 564: { 565: return new PlainEditorKit(); 566: } 567: 568: /** 569: * Creates and returns an EditorKit that is appropriate for the given 570: * content type. This is created using the default recognized types 571: * plus any EditorKit types that have been registered. 572: * 573: * @see #registerEditorKitForContentType(String, String) 574: * @see #registerEditorKitForContentType(String, String, ClassLoader) 575: * @param type the content type 576: * @return an EditorKit for use with the given content type 577: */ 578: public static EditorKit createEditorKitForContentType(String type) 579: { 580: // TODO: Have to handle the case where a ClassLoader was specified 581: // when the EditorKit was registered 582: EditorKit e = null; 583: String className = (String)registerMap.get(type); 584: if (className != null) 585: { 586: try 587: { 588: e = (EditorKit) Class.forName(className).newInstance(); 589: } 590: catch (Exception e2) 591: { 592: // TODO: Not sure what to do here. 593: } 594: } 595: return e; 596: } 597: 598: /** 599: * Sends a given <code>HyperlinkEvent</code> to all registered listeners. 600: * 601: * @param event the event to send 602: */ 603: public void fireHyperlinkUpdate(HyperlinkEvent event) 604: { 605: HyperlinkListener[] listeners = getHyperlinkListeners(); 606: 607: for (int index = 0; index < listeners.length; ++index) 608: listeners[index].hyperlinkUpdate(event); 609: } 610: 611: /** 612: * Returns the accessible context associated with this editor pane. 613: * 614: * @return the accessible context associated with this editor pane 615: */ 616: public AccessibleContext getAccessibleContext() 617: { 618: if (accessibleContext == null) 619: { 620: if (getEditorKit() instanceof HTMLEditorKit) 621: accessibleContext = new AccessibleJEditorPaneHTML(); 622: else 623: accessibleContext = new AccessibleJEditorPane(); 624: } 625: return accessibleContext; 626: } 627: 628: public final String getContentType() 629: { 630: return getEditorKit().getContentType(); 631: } 632: 633: /** 634: * Returns the EditorKit. If there is no EditorKit set this method 635: * calls createDefaultEditorKit() and setEditorKit() first. 636: */ 637: public EditorKit getEditorKit() 638: { 639: if (editorKit == null) 640: setEditorKit(createDefaultEditorKit()); 641: return editorKit; 642: } 643: 644: /** 645: * Returns the class name of the EditorKit associated with the given 646: * content type. 647: * 648: * @since 1.3 649: * @param type the content type 650: * @return the class name of the EditorKit associated with this content type 651: */ 652: public static String getEditorKitClassNameForContentType(String type) 653: { 654: return (String) registerMap.get(type); 655: } 656: 657: /** 658: * Returns the EditorKit to use for the given content type. If an 659: * EditorKit has been explicitly set via 660: * <code>setEditorKitForContentType</code> 661: * then it will be returned. Otherwise an attempt will be made to create 662: * an EditorKit from the default recognzied content types or any 663: * EditorKits that have been registered. If none can be created, a 664: * PlainEditorKit is created. 665: * 666: * @see #registerEditorKitForContentType(String, String) 667: * @see #registerEditorKitForContentType(String, String, ClassLoader) 668: * @param type the content type 669: * @return an appropriate EditorKit for the given content type 670: */ 671: public EditorKit getEditorKitForContentType(String type) 672: { 673: // First check if an EditorKit has been explicitly set. 674: EditorKit e = (EditorKit) editorMap.get(type); 675: // Then check to see if we can create one. 676: if (e == null) 677: e = createEditorKitForContentType(type); 678: // Otherwise default to PlainEditorKit. 679: if (e == null) 680: e = new PlainEditorKit(); 681: return e; 682: } 683: 684: /** 685: * Returns the preferred size for the JEditorPane. 686: */ 687: public Dimension getPreferredSize() 688: { 689: return super.getPreferredSize(); 690: } 691: 692: public boolean getScrollableTracksViewportHeight() 693: { 694: /* Container parent = getParent(); 695: return (parent instanceof JViewport && 696: parent.isValid());*/ 697: return isValid(); 698: } 699: 700: public boolean getScrollableTracksViewportWidth() 701: { 702: /*Container parent = getParent(); 703: return (parent instanceof JViewport && 704: parent.isValid());*/ 705: return isValid(); 706: } 707: 708: public URL getPage() 709: { 710: return page; 711: } 712: 713: protected InputStream getStream(URL page) 714: throws IOException 715: { 716: return page.openStream(); 717: } 718: 719: public String getText() 720: { 721: return super.getText(); 722: } 723: 724: public String getUIClassID() 725: { 726: return "EditorPaneUI"; 727: } 728: 729: public boolean isFocusCycleRoot() 730: { 731: return focus_root; 732: } 733: 734: protected String paramString() 735: { 736: return "JEditorPane"; 737: } 738: 739: /** 740: * This method initializes from a stream. 741: */ 742: public void read(InputStream in, Object desc) throws IOException 743: { 744: EditorKit kit = getEditorKit(); 745: if (kit instanceof HTMLEditorKit && desc instanceof HTMLDocument) 746: { 747: Document doc = (Document) desc; 748: try 749: { 750: kit.read(in, doc, 0); 751: } 752: catch (BadLocationException ex) 753: { 754: assert false : "BadLocationException must not be thrown here."; 755: } 756: } 757: else 758: { 759: Reader inRead = new InputStreamReader(in); 760: super.read(inRead, desc); 761: } 762: } 763: 764: /** 765: * Establishes a binding between type and classname. This enables 766: * us to create an EditorKit later for the given content type. 767: * 768: * @param type the content type 769: * @param classname the name of the class that is associated with this 770: * content type 771: */ 772: public static void registerEditorKitForContentType(String type, 773: String classname) 774: { 775: registerMap.put(type, classname); 776: } 777: 778: /** 779: * Establishes the default bindings of type to classname. 780: */ 781: public static void registerEditorKitForContentType(String type, 782: String classname, 783: ClassLoader loader) 784: { 785: // TODO: Implement this properly. 786: } 787: 788: /** 789: * Replaces the currently selected content with new content represented 790: * by the given string. 791: */ 792: public void replaceSelection(String content) 793: { 794: // TODO: Implement this properly. 795: super.replaceSelection(content); 796: } 797: 798: /** 799: * Scrolls the view to the given reference location (that is, the value 800: * returned by the UL.getRef method for the URL being displayed). 801: */ 802: public void scrollToReference(String reference) 803: { 804: // TODO: Implement this properly. 805: } 806: 807: public final void setContentType(String type) 808: { 809: if (editorKit != null 810: && editorKit.getContentType().equals(type)) 811: return; 812: 813: EditorKit kit = getEditorKitForContentType(type); 814: 815: if (kit != null) 816: setEditorKit(kit); 817: } 818: 819: public void setEditorKit(EditorKit newValue) 820: { 821: if (editorKit == newValue) 822: return; 823: 824: if (editorKit != null) 825: editorKit.deinstall(this); 826: 827: EditorKit oldValue = editorKit; 828: editorKit = newValue; 829: 830: if (editorKit != null) 831: { 832: editorKit.install(this); 833: setDocument(editorKit.createDefaultDocument()); 834: } 835: 836: firePropertyChange("editorKit", oldValue, newValue); 837: invalidate(); 838: repaint(); 839: // Reset the accessibleContext since this depends on the editorKit. 840: accessibleContext = null; 841: } 842: 843: /** 844: * Explicitly sets an EditorKit to be used for the given content type. 845: * @param type the content type 846: * @param k the EditorKit to use for the given content type 847: */ 848: public void setEditorKitForContentType(String type, EditorKit k) 849: { 850: editorMap.put(type, k); 851: } 852: 853: /** 854: * Sets the current URL being displayed. 855: */ 856: public void setPage(String url) throws IOException 857: { 858: setPage(new URL(url)); 859: } 860: 861: /** 862: * Sets the current URL being displayed. 863: */ 864: public void setPage(URL page) throws IOException 865: { 866: if (page == null) 867: throw new IOException("invalid url"); 868: 869: try 870: { 871: this.page = page; 872: getEditorKit().read(page.openStream(), getDocument(), 0); 873: } 874: catch (BadLocationException e) 875: { 876: // Ignored. '0' is always a valid offset. 877: } 878: } 879: 880: /** 881: * Sets the text of the JEditorPane. The argument <code>t</code> 882: * is expected to be in the format of the current EditorKit. This removes 883: * the content of the current document and uses the EditorKit to read in the 884: * new text. This allows the EditorKit to handle the String rather than just 885: * inserting in plain text. 886: * 887: * @param t the text to display in this JEditorPane 888: */ 889: public void setText(String t) 890: { 891: try 892: { 893: // Remove the current content. 894: Document doc = getDocument(); 895: doc.remove(0, doc.getLength()); 896: if (t == null || t == "") 897: return; 898: 899: // Let the EditorKit read the text into the Document. 900: getEditorKit().read(new StringReader(t), doc, 0); 901: } 902: catch (BadLocationException ble) 903: { 904: // TODO: Don't know what to do here. 905: } 906: catch (IOException ioe) 907: { 908: // TODO: Don't know what to do here. 909: } 910: } 911: 912: /** 913: * Add a <code>HyperlinkListener</code> object to this editor pane. 914: * 915: * @param listener the listener to add 916: */ 917: public void addHyperlinkListener(HyperlinkListener listener) 918: { 919: listenerList.add(HyperlinkListener.class, listener); 920: } 921: 922: /** 923: * Removes a <code>HyperlinkListener</code> object to this editor pane. 924: * 925: * @param listener the listener to remove 926: */ 927: public void removeHyperlinkListener(HyperlinkListener listener) 928: { 929: listenerList.remove(HyperlinkListener.class, listener); 930: } 931: 932: /** 933: * Returns all added <code>HyperlinkListener</code> objects. 934: * 935: * @return array of listeners 936: * 937: * @since 1.4 938: */ 939: public HyperlinkListener[] getHyperlinkListeners() 940: { 941: return (HyperlinkListener[]) getListeners(HyperlinkListener.class); 942: } 943: }
GNU Classpath (0.20) |