1 7 package javax.swing; 8 9 import java.awt.*; 10 import java.awt.event.*; 11 import java.net.*; 12 import java.util.*; 13 import java.io.*; 14 import java.util.*; 15 16 import javax.swing.plaf.*; 17 import javax.swing.text.*; 18 import javax.swing.event.*; 19 import javax.swing.text.html.*; 20 import javax.accessibility.*; 21 22 166 public class JEditorPane extends JTextComponent { 167 168 172 public JEditorPane() { 173 super(); 174 setFocusCycleRoot(true); 175 setFocusTraversalPolicy(new LayoutFocusTraversalPolicy () { 176 public Component getComponentAfter(Container focusCycleRoot, 177 Component aComponent) { 178 if (focusCycleRoot != JEditorPane.this || 179 (!isEditable() && getComponentCount() > 0)) { 180 return super.getComponentAfter(focusCycleRoot, 181 aComponent); 182 } else { 183 Container rootAncestor = getFocusCycleRootAncestor(); 184 return (rootAncestor != null) 185 ? rootAncestor.getFocusTraversalPolicy(). 186 getComponentAfter(rootAncestor, 187 JEditorPane.this) 188 : null; 189 } 190 } 191 public Component getComponentBefore(Container focusCycleRoot, 192 Component aComponent) { 193 if (focusCycleRoot != JEditorPane.this || 194 (!isEditable() && getComponentCount() > 0)) { 195 return super.getComponentBefore(focusCycleRoot, 196 aComponent); 197 } else { 198 Container rootAncestor = getFocusCycleRootAncestor(); 199 return (rootAncestor != null) 200 ? rootAncestor.getFocusTraversalPolicy(). 201 getComponentBefore(rootAncestor, 202 JEditorPane.this) 203 : null; 204 } 205 } 206 public Component getDefaultComponent(Container focusCycleRoot) 207 { 208 return (focusCycleRoot != JEditorPane.this || 209 (!isEditable() && getComponentCount() > 0)) 210 ? super.getDefaultComponent(focusCycleRoot) 211 : null; 212 } 213 protected boolean accept(Component aComponent) { 214 return (aComponent != JEditorPane.this) 215 ? super.accept(aComponent) 216 : false; 217 } 218 }); 219 LookAndFeel.installProperty(this, 220 "focusTraversalKeysForward", 221 JComponent. 222 getManagingFocusForwardTraversalKeys()); 223 LookAndFeel.installProperty(this, 224 "focusTraversalKeysBackward", 225 JComponent. 226 getManagingFocusBackwardTraversalKeys()); 227 } 228 229 236 public JEditorPane(URL initialPage) throws IOException { 237 this(); 238 setPage(initialPage); 239 } 240 241 249 public JEditorPane(String url) throws IOException { 250 this(); 251 setPage(url); 252 } 253 254 264 public JEditorPane(String type, String text) { 265 this(); 266 setContentType(type); 267 setText(text); 268 } 269 270 276 public synchronized void addHyperlinkListener(HyperlinkListener listener) { 277 listenerList.add(HyperlinkListener.class, listener); 278 } 279 280 285 public synchronized void removeHyperlinkListener(HyperlinkListener listener) { 286 listenerList.remove(HyperlinkListener.class, listener); 287 } 288 289 297 public synchronized HyperlinkListener[] getHyperlinkListeners() { 298 return (HyperlinkListener[])listenerList.getListeners( 299 HyperlinkListener.class); 300 } 301 302 313 public void fireHyperlinkUpdate(HyperlinkEvent e) { 314 Object [] listeners = listenerList.getListenerList(); 316 for (int i = listeners.length-2; i>=0; i-=2) { 319 if (listeners[i]==HyperlinkListener.class) { 320 ((HyperlinkListener)listeners[i+1]).hyperlinkUpdate(e); 321 } 322 } 323 } 324 325 326 391 public void setPage(URL page) throws IOException { 392 if (page == null) { 393 throw new IOException("invalid url"); 394 } 395 URL loaded = getPage(); 396 397 398 if (!page.equals(loaded) && page.getRef() == null) { 400 scrollRectToVisible(new Rectangle(0,0,1,1)); 401 } 402 boolean reloaded = false; 403 if ((loaded == null) || (! loaded.sameFile(page))) { 404 405 InputStream in = getStream(page); 407 if (kit != null) { 408 Document doc = kit.createDefaultDocument(); 409 if (pageProperties != null) { 410 for (Enumeration e = pageProperties.keys(); e.hasMoreElements() ;) { 413 Object key = e.nextElement(); 414 doc.putProperty(key, pageProperties.get(key)); 415 } 416 pageProperties.clear(); 417 } 418 if (doc.getProperty(Document.StreamDescriptionProperty) == null) { 419 doc.putProperty(Document.StreamDescriptionProperty, page); 420 } 421 422 synchronized(this) { 427 if (loading != null) { 428 loading.cancel(); 431 loading = null; 432 } 433 } 434 if (doc instanceof AbstractDocument) { 435 AbstractDocument adoc = (AbstractDocument) doc; 436 int p = adoc.getAsynchronousLoadPriority(); 437 if (p >= 0) { 438 setDocument(doc); 440 synchronized(this) { 441 loading = new PageStream(in); 442 Thread pl = new PageLoader(doc, loading, p, loaded, page); 443 pl.start(); 444 } 445 return; 446 } 447 } 448 read(in, doc); 449 setDocument(doc); 450 reloaded = true; 451 } 452 } 453 final String reference = page.getRef(); 454 if (reference != null) { 455 if (!reloaded) { 456 scrollToReference(reference); 457 } 458 else { 459 SwingUtilities.invokeLater(new Runnable () { 461 public void run() { 462 scrollToReference(reference); 463 } 464 }); 465 } 466 getDocument().putProperty(Document.StreamDescriptionProperty, page); 467 } 468 firePropertyChange("page", loaded, page); 469 } 470 471 472 487 public void read(InputStream in, Object desc) throws IOException { 488 489 if (desc instanceof HTMLDocument && 490 kit instanceof HTMLEditorKit) { 491 HTMLDocument hdoc = (HTMLDocument) desc; 492 setDocument(hdoc); 493 read(in, hdoc); 494 } else { 495 String charset = (String ) getClientProperty("charset"); 496 Reader r = (charset != null) ? new InputStreamReader(in, charset) : 497 new InputStreamReader(in); 498 super.read(r, desc); 499 } 500 } 501 502 503 514 void read(InputStream in, Document doc) throws IOException { 515 try { 516 String charset = (String ) getClientProperty("charset"); 517 Reader r = (charset != null) ? new InputStreamReader(in, charset) : 518 new InputStreamReader(in); 519 kit.read(r, doc, 0); 520 } catch (BadLocationException e) { 521 throw new IOException(e.getMessage()); 522 } catch (ChangedCharSetException e1) { 523 String charSetSpec = e1.getCharSetSpec(); 524 if (e1.keyEqualsCharSet()) { 525 putClientProperty("charset", charSetSpec); 526 } else { 527 setCharsetFromContentTypeParameters(charSetSpec); 528 } 529 in.close(); 530 URL url = (URL)doc.getProperty(Document.StreamDescriptionProperty); 531 URLConnection conn = url.openConnection(); 532 in = conn.getInputStream(); 533 try { 534 doc.remove(0, doc.getLength()); 535 } catch (BadLocationException e) {} 536 doc.putProperty("IgnoreCharsetDirective", Boolean.valueOf(true)); 537 read(in, doc); 538 } 539 } 540 541 542 545 class PageLoader extends Thread { 546 547 550 PageLoader(Document doc, InputStream in, int priority, URL old, 551 URL page) { 552 setPriority(priority); 553 this.in = in; 554 this.old = old; 555 this.page = page; 556 this.doc = doc; 557 } 558 559 564 public void run() { 565 try { 566 read(in, doc); 567 synchronized(JEditorPane.this) { 568 loading = null; 569 } 570 URL page = (URL) doc.getProperty(Document.StreamDescriptionProperty); 571 String reference = page.getRef(); 572 if (reference != null) { 573 Runnable callScrollToReference = new Runnable () { 577 public void run() { 578 URL u = (URL) getDocument().getProperty 579 (Document.StreamDescriptionProperty); 580 String ref = u.getRef(); 581 scrollToReference(ref); 582 } 583 }; 584 SwingUtilities.invokeLater(callScrollToReference); 585 } 586 } catch (IOException ioe) { 587 UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this); 588 } finally { 589 SwingUtilities.invokeLater(new Runnable () { 590 public void run() { 591 firePropertyChange("page", old, page); 592 } 593 }); 594 } 595 } 596 597 600 InputStream in; 601 602 605 URL old; 606 607 610 URL page; 611 612 617 Document doc; 618 } 619 620 static class PageStream extends FilterInputStream { 621 622 boolean canceled; 623 624 public PageStream(InputStream i) { 625 super(i); 626 canceled = false; 627 } 628 629 633 public synchronized void cancel() { 634 canceled = true; 635 } 636 637 protected synchronized void checkCanceled() throws IOException { 638 if (canceled) { 639 throw new IOException("page canceled"); 640 } 641 } 642 643 public int read() throws IOException { 644 checkCanceled(); 645 return super.read(); 646 } 647 648 public long skip(long n) throws IOException { 649 checkCanceled(); 650 return super.skip(n); 651 } 652 653 public int available() throws IOException { 654 checkCanceled(); 655 return super.available(); 656 } 657 658 public void reset() throws IOException { 659 checkCanceled(); 660 super.reset(); 661 } 662 663 } 664 665 684 protected InputStream getStream(URL page) throws IOException { 685 URLConnection conn = page.openConnection(); 686 if (conn instanceof HttpURLConnection) { 687 HttpURLConnection hconn = (HttpURLConnection) conn; 688 hconn.setInstanceFollowRedirects(false); 689 int response = hconn.getResponseCode(); 690 boolean redirect = (response >= 300 && response <= 399); 691 692 696 if (redirect) { 697 String loc = conn.getHeaderField("Location"); 698 if (loc.startsWith("http", 0)) { 699 page = new URL(loc); 700 } else { 701 page = new URL(page, loc); 702 } 703 return getStream(page); 704 } 705 } 706 if (pageProperties == null) { 707 pageProperties = new Hashtable(); 708 } 709 String type = conn.getContentType(); 710 if (type != null) { 711 setContentType(type); 712 pageProperties.put("content-type", type); 713 } 714 pageProperties.put(Document.StreamDescriptionProperty, page); 715 String enc = conn.getContentEncoding(); 716 if (enc != null) { 717 pageProperties.put("content-encoding", enc); 718 } 719 InputStream in = conn.getInputStream(); 720 return in; 721 } 722 723 738 public void scrollToReference(String reference) { 739 Document d = getDocument(); 740 if (d instanceof HTMLDocument) { 741 HTMLDocument doc = (HTMLDocument) d; 742 HTMLDocument.Iterator iter = doc.getIterator(HTML.Tag.A); 743 for (; iter.isValid(); iter.next()) { 744 AttributeSet a = iter.getAttributes(); 745 String nm = (String ) a.getAttribute(HTML.Attribute.NAME); 746 if ((nm != null) && nm.equals(reference)) { 747 try { 749 Rectangle r = modelToView(iter.getStartOffset()); 750 if (r != null) { 751 Rectangle vis = getVisibleRect(); 754 r.height = vis.height; 756 scrollRectToVisible(r); 757 } 758 } catch (BadLocationException ble) { 759 UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this); 760 } 761 } 762 } 763 } 764 } 765 766 774 public URL getPage() { 775 return (URL) getDocument().getProperty(Document.StreamDescriptionProperty); 776 } 777 778 785 public void setPage(String url) throws IOException { 786 if (url == null) { 787 throw new IOException("invalid url"); 788 } 789 URL page = new URL(url); 790 setPage(page); 791 } 792 793 800 public String getUIClassID() { 801 return uiClassID; 802 } 803 804 810 protected EditorKit createDefaultEditorKit() { 811 return new PlainEditorKit(); 812 } 813 814 821 public EditorKit getEditorKit() { 822 if (kit == null) { 823 kit = createDefaultEditorKit(); 824 } 825 return kit; 826 } 827 828 836 public final String getContentType() { 837 return (kit != null) ? kit.getContentType() : null; 838 } 839 840 869 public final void setContentType(String type) { 870 int parm = type.indexOf(";"); 874 if (parm > -1) { 875 String paramList = type.substring(parm); 877 type = type.substring(0, parm).trim(); 879 if (type.toLowerCase().startsWith("text/")) { 880 setCharsetFromContentTypeParameters(paramList); 881 } 882 } 883 if ((kit == null) || (! type.equals(kit.getContentType()))) { 884 EditorKit k = getEditorKitForContentType(type); 885 if (k != null) { 886 setEditorKit(k); 887 } 888 } 889 } 890 891 895 private void setCharsetFromContentTypeParameters(String paramlist) { 896 String charset = null; 897 try { 898 int semi = paramlist.indexOf(';'); 900 if (semi > -1 && semi < paramlist.length()-1) { 901 paramlist = paramlist.substring(semi + 1); 902 } 903 904 if (paramlist.length() > 0) { 905 HeaderParser hdrParser = new HeaderParser(paramlist); 908 charset = hdrParser.findValue("charset"); 909 if (charset != null) { 910 putClientProperty("charset", charset); 911 } 912 } 913 } 914 catch (IndexOutOfBoundsException e) { 915 } 917 catch (NullPointerException e) { 918 } 920 catch (Exception e) { 921 System.err.println("JEditorPane.getCharsetFromContentTypeParameters failed on: " + paramlist); 923 e.printStackTrace(); 924 } 925 } 926 927 928 952 public void setEditorKit(EditorKit kit) { 953 EditorKit old = this.kit; 954 if (old != null) { 955 old.deinstall(this); 956 } 957 this.kit = kit; 958 if (this.kit != null) { 959 this.kit.install(this); 960 setDocument(this.kit.createDefaultDocument()); 961 } 962 firePropertyChange("editorKit", old, kit); 963 } 964 965 984 public EditorKit getEditorKitForContentType(String type) { 985 if (typeHandlers == null) { 986 typeHandlers = new Hashtable(3); 987 } 988 EditorKit k = (EditorKit) typeHandlers.get(type); 989 if (k == null) { 990 k = createEditorKitForContentType(type); 991 if (k != null) { 992 setEditorKitForContentType(type, k); 993 } 994 } 995 if (k == null) { 996 k = createDefaultEditorKit(); 997 } 998 return k; 999 } 1000 1001 1010 public void setEditorKitForContentType(String type, EditorKit k) { 1011 if (typeHandlers == null) { 1012 typeHandlers = new Hashtable(3); 1013 } 1014 typeHandlers.put(type, k); 1015 } 1016 1017 1035 public void replaceSelection(String content) { 1036 if (! isEditable()) { 1037 UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this); 1038 return; 1039 } 1040 EditorKit kit = getEditorKit(); 1041 if(kit instanceof StyledEditorKit) { 1042 try { 1043 Document doc = getDocument(); 1044 Caret caret = getCaret(); 1045 int p0 = Math.min(caret.getDot(), caret.getMark()); 1046 int p1 = Math.max(caret.getDot(), caret.getMark()); 1047 if (doc instanceof AbstractDocument) { 1048 ((AbstractDocument)doc).replace(p0, p1 - p0, content, 1049 ((StyledEditorKit)kit).getInputAttributes()); 1050 } 1051 else { 1052 if (p0 != p1) { 1053 doc.remove(p0, p1 - p0); 1054 } 1055 if (content != null && content.length() > 0) { 1056 doc.insertString(p0, content, ((StyledEditorKit)kit). 1057 getInputAttributes()); 1058 } 1059 } 1060 } catch (BadLocationException e) { 1061 UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this); 1062 } 1063 } 1064 else { 1065 super.replaceSelection(content); 1066 } 1067 } 1068 1069 1086 public static EditorKit createEditorKitForContentType(String type) { 1087 EditorKit k = null; 1088 Hashtable kitRegistry = getKitRegisty(); 1089 k = (EditorKit) kitRegistry.get(type); 1090 if (k == null) { 1091 String classname = (String ) getKitTypeRegistry().get(type); 1093 ClassLoader loader = (ClassLoader ) getKitLoaderRegistry().get(type); 1094 try { 1095 Class c; 1096 if (loader != null) { 1097 c = loader.loadClass(classname); 1098 } else { 1099 c = Class.forName(classname, true, Thread.currentThread(). 1102 getContextClassLoader()); 1103 } 1104 k = (EditorKit) c.newInstance(); 1105 kitRegistry.put(type, k); 1106 } catch (Throwable e) { 1107 k = null; 1108 } 1109 } 1110 1111 if (k != null) { 1114 return (EditorKit) k.clone(); 1115 } 1116 return null; 1117 } 1118 1119 1131 public static void registerEditorKitForContentType(String type, String classname) { 1132 registerEditorKitForContentType(type, classname,Thread.currentThread(). 1133 getContextClassLoader()); 1134 } 1135 1136 1148 public static void registerEditorKitForContentType(String type, String classname, ClassLoader loader) { 1149 getKitTypeRegistry().put(type, classname); 1150 getKitLoaderRegistry().put(type, loader); 1151 getKitRegisty().remove(type); 1152 } 1153 1154 1162 public static String getEditorKitClassNameForContentType(String type) { 1163 return (String )getKitTypeRegistry().get(type); 1164 } 1165 1166 private static Hashtable getKitTypeRegistry() { 1167 loadDefaultKitsIfNecessary(); 1168 return (Hashtable)SwingUtilities.appContextGet(kitTypeRegistryKey); 1169 } 1170 1171 private static Hashtable getKitLoaderRegistry() { 1172 loadDefaultKitsIfNecessary(); 1173 return (Hashtable)SwingUtilities.appContextGet(kitLoaderRegistryKey); 1174 } 1175 1176 private static Hashtable getKitRegisty() { 1177 Hashtable ht = (Hashtable)SwingUtilities.appContextGet(kitRegistryKey); 1178 if (ht == null) { 1179 ht = new Hashtable(3); 1180 SwingUtilities.appContextPut(kitRegistryKey, ht); 1181 } 1182 return ht; 1183 } 1184 1185 1191 private static void loadDefaultKitsIfNecessary() { 1192 if (SwingUtilities.appContextGet(kitTypeRegistryKey) == null) { 1193 Hashtable ht = new Hashtable(); 1194 SwingUtilities.appContextPut(kitTypeRegistryKey, ht); 1195 ht = new Hashtable(); 1196 SwingUtilities.appContextPut(kitLoaderRegistryKey, ht); 1197 registerEditorKitForContentType("text/plain", 1198 "javax.swing.JEditorPane$PlainEditorKit"); 1199 registerEditorKitForContentType("text/html", 1200 "javax.swing.text.html.HTMLEditorKit"); 1201 registerEditorKitForContentType("text/rtf", 1202 "javax.swing.text.rtf.RTFEditorKit"); 1203 registerEditorKitForContentType("application/rtf", 1204 "javax.swing.text.rtf.RTFEditorKit"); 1205 } 1206 } 1207 1208 1210 1226 public Dimension getPreferredSize() { 1227 Dimension d = super.getPreferredSize(); 1228 if (getParent() instanceof JViewport ) { 1229 JViewport port = (JViewport )getParent(); 1230 TextUI ui = getUI(); 1231 int prefWidth = d.width; 1232 int prefHeight = d.height; 1233 if (! getScrollableTracksViewportWidth()) { 1234 int w = port.getWidth(); 1235 Dimension min = ui.getMinimumSize(this); 1236 if (w != 0 && w < min.width) { 1237 prefWidth = min.width; 1239 } 1240 } 1241 if (! getScrollableTracksViewportHeight()) { 1242 int h = port.getHeight(); 1243 Dimension min = ui.getMinimumSize(this); 1244 if (h != 0 && h < min.height) { 1245 prefHeight = min.height; 1247 } 1248 } 1249 if (prefWidth != d.width || prefHeight != d.height) { 1250 d = new Dimension(prefWidth, prefHeight); 1251 } 1252 } 1253 return d; 1254 } 1255 1256 1258 1305 public void setText(String t) { 1306 try { 1307 Document doc = getDocument(); 1308 doc.remove(0, doc.getLength()); 1309 if (t == null || t.equals("")) { 1310 return; 1311 } 1312 Reader r = new StringReader(t); 1313 EditorKit kit = getEditorKit(); 1314 kit.read(r, doc, 0); 1315 } catch (IOException ioe) { 1316 UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this); 1317 } catch (BadLocationException ble) { 1318 UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this); 1319 } 1320 } 1321 1322 1333 public String getText() { 1334 String txt; 1335 try { 1336 StringWriter buf = new StringWriter(); 1337 write(buf); 1338 txt = buf.toString(); 1339 } catch (IOException ioe) { 1340 txt = null; 1341 } 1342 return txt; 1343 } 1344 1345 1347 1354 public boolean getScrollableTracksViewportWidth() { 1355 if (getParent() instanceof JViewport ) { 1356 JViewport port = (JViewport )getParent(); 1357 TextUI ui = getUI(); 1358 int w = port.getWidth(); 1359 Dimension min = ui.getMinimumSize(this); 1360 Dimension max = ui.getMaximumSize(this); 1361 if ((w >= min.width) && (w <= max.width)) { 1362 return true; 1363 } 1364 } 1365 return false; 1366 } 1367 1368 1376 public boolean getScrollableTracksViewportHeight() { 1377 if (getParent() instanceof JViewport ) { 1378 JViewport port = (JViewport )getParent(); 1379 TextUI ui = getUI(); 1380 int h = port.getHeight(); 1381 Dimension min = ui.getMinimumSize(this); 1382 if (h >= min.height) { 1383 Dimension max = ui.getMaximumSize(this); 1384 if (h <= max.height) { 1385 return true; 1386 } 1387 } 1388 } 1389 return false; 1390 } 1391 1392 1394 1399 private void writeObject(ObjectOutputStream s) throws IOException { 1400 s.defaultWriteObject(); 1401 if (getUIClassID().equals(uiClassID)) { 1402 byte count = JComponent.getWriteObjCounter(this); 1403 JComponent.setWriteObjCounter(this, --count); 1404 if (count == 0 && ui != null) { 1405 ui.installUI(this); 1406 } 1407 } 1408 } 1409 1410 1412 1416 PageStream loading; 1417 1418 1421 private EditorKit kit; 1422 1423 private Hashtable pageProperties; 1424 1425 1428 private Hashtable typeHandlers; 1429 1430 1433 private static final Object kitRegistryKey = 1434 new StringBuffer ("JEditorPane.kitRegistry"); 1435 private static final Object kitTypeRegistryKey = 1436 new StringBuffer ("JEditorPane.kitTypeRegistry"); 1437 private static final Object kitLoaderRegistryKey = 1438 new StringBuffer ("JEditorPane.kitLoaderRegistry"); 1439 1440 1444 private static final String uiClassID = "EditorPaneUI"; 1445 1446 1447 1458 public static final String W3C_LENGTH_UNITS = "JEditorPane.w3cLengthUnits"; 1459 1460 1472 public static final String HONOR_DISPLAY_PROPERTIES = "JEditorPane.honorDisplayProperties"; 1473 1474 1484 protected String paramString() { 1485 String kitString = (kit != null ? 1486 kit.toString() : ""); 1487 String typeHandlersString = (typeHandlers != null ? 1488 typeHandlers.toString() : ""); 1489 1490 return super.paramString() + 1491 ",kit=" + kitString + 1492 ",typeHandlers=" + typeHandlersString; 1493 } 1494 1495 1496 1500 1501 1510 public AccessibleContext getAccessibleContext() { 1511 if (accessibleContext == null) { 1512 if (JEditorPane.this.getEditorKit() instanceof HTMLEditorKit) { 1513 accessibleContext = new AccessibleJEditorPaneHTML(); 1514 } else { 1515 accessibleContext = new AccessibleJEditorPane(); 1516 } 1517 } 1518 return accessibleContext; 1519 } 1520 1521 1536 protected class AccessibleJEditorPane extends AccessibleJTextComponent { 1537 1538 1548 public String getAccessibleDescription() { 1549 if (accessibleDescription != null) { 1550 return accessibleDescription; 1551 } else { 1552 return JEditorPane.this.getContentType(); 1553 } 1554 } 1555 1556 1563 public AccessibleStateSet getAccessibleStateSet() { 1564 AccessibleStateSet states = super.getAccessibleStateSet(); 1565 states.add(AccessibleState.MULTI_LINE); 1566 return states; 1567 } 1568 } 1569 1570 1585 protected class AccessibleJEditorPaneHTML extends AccessibleJEditorPane { 1586 1587 private AccessibleContext accessibleContext; 1588 1589 public AccessibleText getAccessibleText() { 1590 return new JEditorPaneAccessibleHypertextSupport(); 1591 } 1592 1593 protected AccessibleJEditorPaneHTML () { 1594 HTMLEditorKit kit = (HTMLEditorKit)JEditorPane.this.getEditorKit(); 1595 accessibleContext = kit.getAccessibleContext(); 1596 } 1597 1598 1603 public int getAccessibleChildrenCount() { 1604 if (accessibleContext != null) { 1605 return accessibleContext.getAccessibleChildrenCount(); 1606 } else { 1607 return 0; 1608 } 1609 } 1610 1611 1621 public Accessible getAccessibleChild(int i) { 1622 if (accessibleContext != null) { 1623 return accessibleContext.getAccessibleChild(i); 1624 } else { 1625 return null; 1626 } 1627 } 1628 1629 1637 public Accessible getAccessibleAt(Point p) { 1638 if (accessibleContext != null && p != null) { 1639 try { 1640 AccessibleComponent acomp = 1641 accessibleContext.getAccessibleComponent(); 1642 if (acomp != null) { 1643 return acomp.getAccessibleAt(p); 1644 } else { 1645 return null; 1646 } 1647 } catch (IllegalComponentStateException e) { 1648 return null; 1649 } 1650 } else { 1651 return null; 1652 } 1653 } 1654 } 1655 1656 1665 protected class JEditorPaneAccessibleHypertextSupport 1666 extends AccessibleJEditorPane implements AccessibleHypertext { 1667 1668 public class HTMLLink extends AccessibleHyperlink { 1669 Element element; 1670 1671 public HTMLLink(Element e) { 1672 element = e; 1673 } 1674 1675 1683 public boolean isValid() { 1684 return JEditorPaneAccessibleHypertextSupport.this.linksValid; 1685 } 1686 1687 1695 public int getAccessibleActionCount() { 1696 return 1; 1697 } 1698 1699 1706 public boolean doAccessibleAction(int i) { 1707 if (i == 0 && isValid() == true) { 1708 URL u = (URL) getAccessibleActionObject(i); 1709 if (u != null) { 1710 HyperlinkEvent linkEvent = 1711 new HyperlinkEvent(JEditorPane.this, HyperlinkEvent.EventType.ACTIVATED, u); 1712 JEditorPane.this.fireHyperlinkUpdate(linkEvent); 1713 return true; 1714 } 1715 } 1716 return false; } 1718 1719 1729 public String getAccessibleActionDescription(int i) { 1730 if (i == 0 && isValid() == true) { 1731 Document d = JEditorPane.this.getDocument(); 1732 if (d != null) { 1733 try { 1734 return d.getText(getStartIndex(), 1735 getEndIndex() - getStartIndex()); 1736 } catch (BadLocationException exception) { 1737 return null; 1738 } 1739 } 1740 } 1741 return null; 1742 } 1743 1744 1751 public Object getAccessibleActionObject(int i) { 1752 if (i == 0 && isValid() == true) { 1753 AttributeSet as = element.getAttributes(); 1754 AttributeSet anchor = 1755 (AttributeSet) as.getAttribute(HTML.Tag.A); 1756 String href = (anchor != null) ? 1757 (String ) anchor.getAttribute(HTML.Attribute.HREF) : null; 1758 if (href != null) { 1759 URL u; 1760 try { 1761 u = new URL(JEditorPane.this.getPage(), href); 1762 } catch (MalformedURLException m) { 1763 u = null; 1764 } 1765 return u; 1766 } 1767 } 1768 return null; } 1770 1771 1786 public Object getAccessibleActionAnchor(int i) { 1787 return getAccessibleActionDescription(i); 1788 } 1789 1790 1791 1797 public int getStartIndex() { 1798 return element.getStartOffset(); 1799 } 1800 1801 1807 public int getEndIndex() { 1808 return element.getEndOffset(); 1809 } 1810 } 1811 1812 private class LinkVector extends Vector { 1813 public int baseElementIndex(Element e) { 1814 HTMLLink l; 1815 for (int i = 0; i < elementCount; i++) { 1816 l = (HTMLLink) elementAt(i); 1817 if (l.element == e) { 1818 return i; 1819 } 1820 } 1821 return -1; 1822 } 1823 } 1824 1825 LinkVector hyperlinks; 1826 boolean linksValid = false; 1827 1828 1831 private void buildLinkTable() { 1832 hyperlinks.removeAllElements(); 1833 Document d = JEditorPane.this.getDocument(); 1834 if (d != null) { 1835 ElementIterator ei = new ElementIterator(d); 1836 Element e; 1837 AttributeSet as; 1838 AttributeSet anchor; 1839 String href; 1840 while ((e = ei.next()) != null) { 1841 if (e.isLeaf()) { 1842 as = e.getAttributes(); 1843 anchor = (AttributeSet) as.getAttribute(HTML.Tag.A); 1844 href = (anchor != null) ? 1845 (String ) anchor.getAttribute(HTML.Attribute.HREF) : null; 1846 if (href != null) { 1847 hyperlinks.addElement(new HTMLLink(e)); 1848 } 1849 } 1850 } 1851 } 1852 linksValid = true; 1853 } 1854 1855 1858 public JEditorPaneAccessibleHypertextSupport() { 1859 hyperlinks = new LinkVector(); 1860 Document d = JEditorPane.this.getDocument(); 1861 if (d != null) { 1862 d.addDocumentListener(new DocumentListener() { 1863 public void changedUpdate(DocumentEvent theEvent) { 1864 linksValid = false; 1865 } 1866 public void insertUpdate(DocumentEvent theEvent) { 1867 linksValid = false; 1868 } 1869 public void removeUpdate(DocumentEvent theEvent) { 1870 linksValid = false; 1871 } 1872 }); 1873 } 1874 } 1875 1876 1881 public int getLinkCount() { 1882 if (linksValid == false) { 1883 buildLinkTable(); 1884 } 1885 return hyperlinks.size(); 1886 } 1887 1888 1896 public int getLinkIndex(int charIndex) { 1897 if (linksValid == false) { 1898 buildLinkTable(); 1899 } 1900 Element e = null; 1901 Document doc = JEditorPane.this.getDocument(); 1902 if (doc != null) { 1903 for (e = doc.getDefaultRootElement(); ! e.isLeaf(); ) { 1904 int index = e.getElementIndex(charIndex); 1905 e = e.getElement(index); 1906 } 1907 } 1908 1909 return hyperlinks.baseElementIndex(e); 1913 } 1914 1915 1923 public AccessibleHyperlink getLink(int linkIndex) { 1924 if (linksValid == false) { 1925 buildLinkTable(); 1926 } 1927 if (linkIndex >= 0 && linkIndex < hyperlinks.size()) { 1928 return (AccessibleHyperlink) hyperlinks.elementAt(linkIndex); 1929 } else { 1930 return null; 1931 } 1932 } 1933 1934 1941 public String getLinkText(int linkIndex) { 1942 if (linksValid == false) { 1943 buildLinkTable(); 1944 } 1945 Element e = (Element) hyperlinks.elementAt(linkIndex); 1946 if (e != null) { 1947 Document d = JEditorPane.this.getDocument(); 1948 if (d != null) { 1949 try { 1950 return d.getText(e.getStartOffset(), 1951 e.getEndOffset() - e.getStartOffset()); 1952 } catch (BadLocationException exception) { 1953 return null; 1954 } 1955 } 1956 } 1957 return null; 1958 } 1959 } 1960 1961 static class PlainEditorKit extends DefaultEditorKit implements ViewFactory { 1962 1963 1971 public ViewFactory getViewFactory() { 1972 return this; 1973 } 1974 1975 1983 public View create(Element elem) { 1984 Document doc = elem.getDocument(); 1985 Object i18nFlag 1986 = doc.getProperty("i18n"); 1987 if ((i18nFlag != null) && i18nFlag.equals(Boolean.TRUE)) { 1988 return createI18N(elem); 1990 } else { 1991 return new WrappedPlainView(elem); 1992 } 1993 } 1994 1995 View createI18N(Element elem) { 1996 String kind = elem.getName(); 1997 if (kind != null) { 1998 if (kind.equals(AbstractDocument.ContentElementName)) { 1999 return new PlainParagraph(elem); 2000 } else if (kind.equals(AbstractDocument.ParagraphElementName)){ 2001 return new BoxView(elem, View.Y_AXIS); 2002 } 2003 } 2004 return null; 2005 } 2006 2007 2011 static class PlainParagraph extends javax.swing.text.ParagraphView { 2012 2013 PlainParagraph(Element elem) { 2014 super(elem); 2015 layoutPool = new LogicalView(elem); 2016 layoutPool.setParent(this); 2017 } 2018 2019 protected void setPropertiesFromAttributes() { 2020 Component c = getContainer(); 2021 if ((c != null) 2022 && (! c.getComponentOrientation().isLeftToRight())) 2023 { 2024 setJustification(StyleConstants.ALIGN_RIGHT); 2025 } else { 2026 setJustification(StyleConstants.ALIGN_LEFT); 2027 } 2028 } 2029 2030 2034 public int getFlowSpan(int index) { 2035 Component c = getContainer(); 2036 if (c instanceof JTextArea ) { 2037 JTextArea area = (JTextArea ) c; 2038 if (! area.getLineWrap()) { 2039 return Integer.MAX_VALUE; 2041 } 2042 } 2043 return super.getFlowSpan(index); 2044 } 2045 2046 protected SizeRequirements calculateMinorAxisRequirements(int axis, 2047 SizeRequirements r) 2048 { 2049 SizeRequirements req 2050 = super.calculateMinorAxisRequirements(axis, r); 2051 Component c = getContainer(); 2052 if (c instanceof JTextArea ) { 2053 JTextArea area = (JTextArea ) c; 2054 if (! area.getLineWrap()) { 2055 req.minimum = req.preferred; 2057 } 2058 } 2059 return req; 2060 } 2061 2062 2069 static class LogicalView extends CompositeView { 2070 2071 LogicalView(Element elem) { 2072 super(elem); 2073 } 2074 2075 protected int getViewIndexAtPosition(int pos) { 2076 Element elem = getElement(); 2077 if (elem.getElementCount() > 0) { 2078 return elem.getElementIndex(pos); 2079 } 2080 return 0; 2081 } 2082 2083 protected boolean 2084 updateChildren(DocumentEvent.ElementChange ec, 2085 DocumentEvent e, ViewFactory f) 2086 { 2087 return false; 2088 } 2089 2090 protected void loadChildren(ViewFactory f) { 2091 Element elem = getElement(); 2092 if (elem.getElementCount() > 0) { 2093 super.loadChildren(f); 2094 } else { 2095 View v = new GlyphView(elem); 2096 append(v); 2097 } 2098 } 2099 2100 public float getPreferredSpan(int axis) { 2101 if( getViewCount() != 1 ) 2102 throw new Error ("One child view is assumed."); 2103 2104 View v = getView(0); 2105 return v.getPreferredSpan(axis); 2107 } 2108 2109 2124 protected void forwardUpdateToView(View v, DocumentEvent e, 2125 Shape a, ViewFactory f) { 2126 v.setParent(this); 2127 super.forwardUpdateToView(v, e, a, f); 2128 } 2129 2130 2133 public void paint(Graphics g, Shape allocation) { 2134 } 2135 2136 protected boolean isBefore(int x, int y, Rectangle alloc) { 2137 return false; 2138 } 2139 2140 protected boolean isAfter(int x, int y, Rectangle alloc) { 2141 return false; 2142 } 2143 2144 protected View getViewAtPoint(int x, int y, Rectangle alloc) { 2145 return null; 2146 } 2147 2148 protected void childAllocation(int index, Rectangle a) { 2149 } 2150 } 2151 } 2152 } 2153 2154 2171 2172 2173static class HeaderParser { 2174 2175 2176 String raw; 2177 String [][] tab; 2178 2179 public HeaderParser(String raw) { 2180 this.raw = raw; 2181 tab = new String [10][2]; 2182 parse(); 2183 } 2184 2185 private void parse() { 2186 2187 if (raw != null) { 2188 raw = raw.trim(); 2189 char[] ca = raw.toCharArray(); 2190 int beg = 0, end = 0, i = 0; 2191 boolean inKey = true; 2192 boolean inQuote = false; 2193 int len = ca.length; 2194 while (end < len) { 2195 char c = ca[end]; 2196 if (c == '=') { tab[i][0] = new String (ca, beg, end-beg).toLowerCase(); 2198 inKey = false; 2199 end++; 2200 beg = end; 2201 } else if (c == '\"') { 2202 if (inQuote) { 2203 tab[i++][1]= new String (ca, beg, end-beg); 2204 inQuote=false; 2205 do { 2206 end++; 2207 } while (end < len && (ca[end] == ' ' || ca[end] == ',')); 2208 inKey=true; 2209 beg=end; 2210 } else { 2211 inQuote=true; 2212 end++; 2213 beg=end; 2214 } 2215 } else if (c == ' ' || c == ',') { if (inQuote) { 2217 end++; 2218 continue; 2219 } else if (inKey) { 2220 tab[i++][0] = (new String (ca, beg, end-beg)).toLowerCase(); 2221 } else { 2222 tab[i++][1] = (new String (ca, beg, end-beg)); 2223 } 2224 while (end < len && (ca[end] == ' ' || ca[end] == ',')) { 2225 end++; 2226 } 2227 inKey = true; 2228 beg = end; 2229 } else { 2230 end++; 2231 } 2232 } 2233 if (--end > beg) { 2235 if (!inKey) { 2236 if (ca[end] == '\"') { 2237 tab[i++][1] = (new String (ca, beg, end-beg)); 2238 } else { 2239 tab[i++][1] = (new String (ca, beg, end-beg+1)); 2240 } 2241 } else { 2242 tab[i][0] = (new String (ca, beg, end-beg+1)).toLowerCase(); 2243 } 2244 } else if (end == beg) { 2245 if (!inKey) { 2246 if (ca[end] == '\"') { 2247 tab[i++][1] = String.valueOf(ca[end-1]); 2248 } else { 2249 tab[i++][1] = String.valueOf(ca[end]); 2250 } 2251 } else { 2252 tab[i][0] = String.valueOf(ca[end]).toLowerCase(); 2253 } 2254 } 2255 } 2256 2257 } 2258 2259 public String findKey(int i) { 2260 if (i < 0 || i > 10) 2261 return null; 2262 return tab[i][0]; 2263 } 2264 2265 public String findValue(int i) { 2266 if (i < 0 || i > 10) 2267 return null; 2268 return tab[i][1]; 2269 } 2270 2271 public String findValue(String key) { 2272 return findValue(key, null); 2273 } 2274 2275 public String findValue(String k, String Default) { 2276 if (k == null) 2277 return Default; 2278 k = k.toLowerCase(); 2279 for (int i = 0; i < 10; ++i) { 2280 if (tab[i][0] == null) { 2281 return Default; 2282 } else if (k.equals(tab[i][0])) { 2283 return tab[i][1]; 2284 } 2285 } 2286 return Default; 2287 } 2288 2289 public int findInt(String k, int Default) { 2290 try { 2291 return Integer.parseInt(findValue(k, String.valueOf(Default))); 2292 } catch (Throwable t) { 2293 return Default; 2294 } 2295 } 2296 } 2297 2298} 2299 2300 | Popular Tags |