1 19 20 package org.openide.awt; 21 22 import java.awt.BorderLayout ; 23 import java.awt.Component ; 24 import java.awt.GridBagConstraints ; 25 import java.awt.GridBagLayout ; 26 import java.awt.Insets ; 27 import java.awt.event.ActionEvent ; 28 import java.awt.event.ActionListener ; 29 import java.beans.PropertyChangeEvent ; 30 import java.beans.PropertyChangeListener ; 31 import java.io.IOException ; 32 import java.net.MalformedURLException ; 33 import java.net.URL ; 34 import java.util.logging.Logger ; 35 import javax.accessibility.Accessible ; 36 import javax.accessibility.AccessibleContext ; 37 import javax.imageio.ImageIO ; 38 import javax.swing.Icon ; 39 import javax.swing.JButton ; 40 import javax.swing.JComboBox ; 41 import javax.swing.JComponent ; 42 import javax.swing.JFrame ; 43 import javax.swing.JLabel ; 44 import javax.swing.JPanel ; 45 import javax.swing.JScrollPane ; 46 import javax.swing.JToolBar ; 47 import javax.swing.ListModel ; 48 import javax.swing.SwingUtilities ; 49 import javax.swing.WindowConstants ; 50 import org.openide.util.Exceptions; 51 import org.openide.util.Lookup; 52 import org.openide.util.NbBundle; 53 import org.openide.util.RequestProcessor; 54 55 67 public class HtmlBrowser extends JPanel { 68 70 71 private static final long serialVersionUID = 2912844785502987960L; 72 73 74 public static final int DEFAULT_WIDTH = 400; 75 76 77 public static final int DEFAULT_HEIGHT = 600; 78 79 80 private static Factory browserFactory; 81 82 83 private static String homePage = null; 84 85 86 private Icon iBack; 87 private Icon iForward; 88 private Icon iHome; 89 private Icon iReload; 90 private Icon iStop; 91 private Icon iHistory; 92 93 95 96 final Impl browserImpl; 97 98 99 private boolean everythinkIListenInCheckBoxIsUnimportant = false; 100 101 102 private boolean toolbarVisible = false; 103 104 105 private boolean statusLineVisible = false; 106 107 109 private BrowserListener browserListener; 110 111 private JButton bBack; 113 114 private JButton bForward; 116 117 private JButton bHome; 119 120 private JButton bReload; 122 123 private JButton bStop; 125 126 private JButton bHistory; 128 129 130 private JComboBox cbLocation; 131 private JLabel cbLabel; 132 private JLabel lStatusLine; 133 final Component browserComponent; 134 private JPanel head; 135 private RequestProcessor rp = new RequestProcessor(); 136 137 139 142 public HtmlBrowser() { 143 this(true, true); 144 } 145 146 152 public HtmlBrowser(boolean toolbar, boolean statusLine) { 153 this(null, toolbar, statusLine); 154 } 155 156 164 public HtmlBrowser(Factory fact, boolean toolbar, boolean statusLine) { 165 init(); 166 167 Impl impl = null; 168 Component comp = null; 169 170 try { 171 if (fact == null) { 172 Impl[] arr = new Impl[1]; 173 comp = findComponent(arr); 174 impl = arr[0]; 175 } else { 176 try { 177 impl = fact.createHtmlBrowserImpl(); 178 comp = impl.getComponent(); 179 } catch (UnsupportedOperationException ex) { 180 Exceptions.printStackTrace(ex); 181 impl = new SwingBrowserImpl(); 182 comp = impl.getComponent(); 183 } 184 } 185 } catch (RuntimeException e) { 186 Exceptions.attachLocalizedMessage(e, 188 NbBundle.getMessage(HtmlBrowser.class, 189 "EXC_Module")); 190 Exceptions.printStackTrace(e); 191 } 192 193 browserImpl = impl; 194 browserComponent = comp; 195 196 setLayout(new BorderLayout (0, 2)); 197 198 add((browserComponent != null) ? new JScrollPane (browserComponent) : new JScrollPane (), "Center"); 200 browserListener = new BrowserListener(); 201 202 if (toolbar) { 203 initToolbar(); 204 } 205 206 if (statusLine) { 207 initStatusLine(); 208 } 209 210 browserImpl.addPropertyChangeListener(browserListener); 211 212 getAccessibleContext().setAccessibleName(NbBundle.getMessage(HtmlBrowser.class, "ACS_HtmlBrowser")); 213 getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(HtmlBrowser.class, "ACSD_HtmlBrowser")); 214 } 215 216 219 public static void setHomePage(String u) { 220 homePage = u; 221 } 222 223 226 public static String getHomePage() { 227 if (homePage == null) { 228 return NbBundle.getMessage(HtmlBrowser.class, "PROP_HomePage"); 229 } 230 231 return homePage; 232 } 233 234 239 public static void setFactory(Factory brFactory) { 240 browserFactory = brFactory; 241 } 242 243 256 private static Component findComponent(Impl[] handle) { 257 Lookup.Result<Factory> r = Lookup.getDefault().lookup(new Lookup.Template<Factory>(Factory.class)); 258 for (Factory f: r.allInstances()) { 259 260 try { 261 Impl impl = f.createHtmlBrowserImpl(); 262 Component c = (impl != null) ? impl.getComponent() : null; 263 264 if (c != null) { 265 handle[0] = impl; 266 267 return c; 268 } 269 } catch (UnsupportedOperationException ex) { 270 } 272 } 273 274 Factory f = browserFactory; 276 277 if (f != null) { 278 try { 279 handle[0] = f.createHtmlBrowserImpl(); 280 281 return handle[0].getComponent(); 282 } catch (UnsupportedOperationException ex) { 283 } 285 } 286 287 handle[0] = new SwingBrowserImpl(); 289 290 return handle[0].getComponent(); 291 } 292 293 296 private void init() { 297 try { 298 if (iBack != null) { 299 return; 300 } 301 iBack = new javax.swing.ImageIcon (ImageIO.read(org.openide.awt.HtmlBrowser.class.getResource("/org/openide/resources/html/back.gif"))); iForward = new javax.swing.ImageIcon (ImageIO.read(org.openide.awt.HtmlBrowser.class.getResource("/org/openide/resources/html/forward.gif"))); iHome = new javax.swing.ImageIcon (ImageIO.read(org.openide.awt.HtmlBrowser.class.getResource("/org/openide/resources/html/home.gif"))); iReload = new javax.swing.ImageIcon (ImageIO.read(org.openide.awt.HtmlBrowser.class.getResource("/org/openide/resources/html/refresh.gif"))); iStop = new javax.swing.ImageIcon (ImageIO.read(org.openide.awt.HtmlBrowser.class.getResource("/org/openide/resources/html/stop.gif"))); iHistory = new javax.swing.ImageIcon (ImageIO.read(org.openide.awt.HtmlBrowser.class.getResource("/org/openide/resources/html/history.gif"))); } 308 catch (IOException ex) { 309 Logger.getLogger(HtmlBrowser.class.getName()).log(java.util.logging.Level.SEVERE, 310 ex.getMessage(), ex); 311 } 312 } 313 314 317 private void initToolbar() { 318 toolbarVisible = true; 319 320 head = new JPanel (); 322 head.setLayout(new BorderLayout (11, 0)); 323 324 JPanel p = new JPanel (new GridBagLayout ()); 325 p.add(bBack = new JButton (iBack)); 326 bBack.setToolTipText(NbBundle.getMessage(HtmlBrowser.class, "CTL_Back")); 327 328 GridBagConstraints gbc = new GridBagConstraints (); 329 gbc.insets = new Insets (0, 0, 0, 5); 330 p.add(bForward = new JButton (iForward), gbc); 331 bForward.setToolTipText(NbBundle.getMessage(HtmlBrowser.class, "CTL_Forward")); 332 p.add(bStop = new JButton (iStop)); 333 bStop.setToolTipText(NbBundle.getMessage(HtmlBrowser.class, "CTL_Stop")); 334 gbc = new GridBagConstraints (); 335 gbc.insets = new Insets (0, 0, 0, 5); 336 p.add(bReload = new JButton (iReload), gbc); 337 bReload.setToolTipText(NbBundle.getMessage(HtmlBrowser.class, "CTL_Reload")); 338 p.add(bHome = new JButton (iHome)); 339 bHome.setToolTipText(NbBundle.getMessage(HtmlBrowser.class, "CTL_Home")); 340 gbc = new GridBagConstraints (); 341 gbc.insets = new Insets (0, 0, 0, 5); 342 p.add(bHistory = new JButton (iHistory), gbc); 343 bHistory.setToolTipText(NbBundle.getMessage(HtmlBrowser.class, "CTL_History")); 344 345 if (browserImpl != null) { 346 bBack.setEnabled(browserImpl.isBackward()); 347 bForward.setEnabled(browserImpl.isForward()); 348 bHistory.setEnabled(browserImpl.isHistory()); 349 } 350 351 JToolBar.Separator ts = new JToolBar.Separator (); 352 gbc = new GridBagConstraints (); 353 gbc.insets = new Insets (0, 0, 0, 5); 354 p.add(ts, gbc); 355 ts.updateUI(); 356 p.add(cbLabel = new JLabel ()); 357 Mnemonics.setLocalizedText(cbLabel, NbBundle.getMessage(HtmlBrowser.class, "CTL_Location")); head.add("West", p); 360 head.add("Center", cbLocation = new JComboBox ()); cbLocation.setEditable(true); 362 cbLabel.setLabelFor(cbLocation); 363 add(head, "North"); 365 cbLocation.addActionListener(browserListener); 367 bHistory.addActionListener(browserListener); 368 bBack.addActionListener(browserListener); 369 bForward.addActionListener(browserListener); 370 bReload.addActionListener(browserListener); 371 bHome.addActionListener(browserListener); 372 bStop.addActionListener(browserListener); 373 374 bHistory.getAccessibleContext().setAccessibleName(bHistory.getToolTipText()); 375 bBack.getAccessibleContext().setAccessibleName(bBack.getToolTipText()); 376 bForward.getAccessibleContext().setAccessibleName(bForward.getToolTipText()); 377 bReload.getAccessibleContext().setAccessibleName(bReload.getToolTipText()); 378 bHome.getAccessibleContext().setAccessibleName(bHome.getToolTipText()); 379 bStop.getAccessibleContext().setAccessibleName(bStop.getToolTipText()); 380 cbLocation.getAccessibleContext().setAccessibleDescription( 381 NbBundle.getMessage(HtmlBrowser.class, "ACSD_HtmlBrowser_Location") 382 ); 383 } 384 385 388 private void destroyToolbar() { 389 remove(head); 390 head = null; 391 toolbarVisible = false; 392 } 393 394 397 private void initStatusLine() { 398 statusLineVisible = true; 399 add(lStatusLine = new JLabel (NbBundle.getMessage(HtmlBrowser.class, "CTL_Loading")), "South" ); 401 lStatusLine.setLabelFor(this); 402 } 403 404 407 private void destroyStatusLine() { 408 remove(lStatusLine); 409 lStatusLine = null; 410 statusLineVisible = false; 411 } 412 413 415 420 public void setURL(String str) { 421 URL URL; 422 423 try { 424 URL = new URL (str); 425 } catch (MalformedURLException ee) { 426 try { 427 URL = new URL ("http://" + str); } catch (MalformedURLException e) { 429 if (browserImpl instanceof SwingBrowserImpl) { 430 ((SwingBrowserImpl) browserImpl).setStatusText( 431 NbBundle.getMessage(SwingBrowserImpl.class, "FMT_InvalidURL", new Object [] { str }) 432 ); 433 } else { 434 Exceptions.printStackTrace(ee); 435 } 436 437 return; 438 } 439 } 440 441 setURL(URL); 442 } 443 444 449 public void setURL(final URL url) { 450 if (url == null) { 451 return; 452 } 453 454 class URLSetter implements Runnable { 455 private boolean sameHosts = false; 456 457 public void run() { 458 if (!SwingUtilities.isEventDispatchThread()) { 459 if ("nbfs".equals(url.getProtocol())) { sameHosts = true; 461 } else { 462 sameHosts = (url.getHost() != null) && (browserImpl.getURL() != null) && 463 (url.getHost().equals(browserImpl.getURL().getHost())); 464 } 465 466 SwingUtilities.invokeLater(this); 467 } else { 468 if (url.equals(browserImpl.getURL()) && sameHosts) { browserImpl.reloadDocument(); 470 } else { 471 browserImpl.setURL(url); 472 } 473 } 474 } 475 } 476 rp.getDefault().post(new URLSetter()); 477 } 478 479 482 public final URL getDocumentURL() { 483 return browserImpl.getURL(); 484 } 485 486 489 public final void setEnableHome(boolean b) { 490 bHome.setEnabled(b); 491 bHome.setVisible(b); 492 } 493 494 497 public final void setEnableLocation(boolean b) { 498 cbLocation.setEditable(b); 499 cbLocation.setVisible(b); 500 cbLabel.setVisible(b); 501 } 502 503 506 public boolean isStatusLineVisible() { 507 return statusLineVisible; 508 } 509 510 513 public void setStatusLineVisible(boolean v) { 514 if (v == statusLineVisible) { 515 return; 516 } 517 518 if (v) { 519 initStatusLine(); 520 } else { 521 destroyStatusLine(); 522 } 523 } 524 525 528 public boolean isToolbarVisible() { 529 return toolbarVisible; 530 } 531 532 535 public void setToolbarVisible(boolean v) { 536 if (v == toolbarVisible) { 537 return; 538 } 539 540 if (v) { 541 initToolbar(); 542 } else { 543 destroyToolbar(); 544 } 545 } 546 547 552 public final Impl getBrowserImpl() { 553 return browserImpl; 554 } 555 556 561 public final Component getBrowserComponent() { 562 return browserComponent; 563 } 564 565 567 570 public java.awt.Dimension getPreferredSize() { 571 java.awt.Dimension superPref = super.getPreferredSize(); 572 573 return new java.awt.Dimension ( 574 Math.max(DEFAULT_WIDTH, superPref.width), Math.max(DEFAULT_HEIGHT, superPref.height) 575 ); 576 } 577 578 581 private void updateLocationBar() { 582 if (toolbarVisible) { 583 everythinkIListenInCheckBoxIsUnimportant = true; 584 585 URL url = browserImpl.getURL(); 586 587 if (url != null) { 588 cbLocation.setSelectedItem(url.toString()); 589 } 590 591 everythinkIListenInCheckBoxIsUnimportant = false; 592 } 593 } 594 595 public void requestFocus() { 597 if (browserComponent != null) { 598 boolean ownerFound = false; 599 600 if (browserComponent instanceof JComponent ) { 601 ownerFound = ((JComponent ) browserComponent).requestDefaultFocus(); 602 } 603 604 if (!ownerFound) { 605 browserComponent.requestFocus(); 606 } 607 } else { 608 super.requestFocus(); 609 } 610 } 611 612 public boolean requestFocusInWindow() { 613 if (browserComponent != null) { 614 boolean ownerFound = false; 615 616 if (browserComponent instanceof JComponent ) { 617 ownerFound = ((JComponent ) browserComponent).requestDefaultFocus(); 618 } 619 620 if (!ownerFound) { 621 return browserComponent.requestFocusInWindow(); 622 } else { 623 return true; 624 } 625 } else { 626 return super.requestFocusInWindow(); 627 } 628 } 629 630 public AccessibleContext getAccessibleContext() { 631 if (accessibleContext == null) { 632 accessibleContext = new AccessibleHtmlBrowser(); 633 } 634 635 return accessibleContext; 636 } 637 638 643 public interface Factory { 644 647 public Impl createHtmlBrowserImpl(); 648 } 649 650 652 655 private class BrowserListener implements ActionListener , PropertyChangeListener { 656 BrowserListener() { 657 } 658 659 662 public void propertyChange(PropertyChangeEvent evt) { 663 String property = evt.getPropertyName(); 664 665 if (property == null) { 666 return; 667 } 668 669 if (property.equals(Impl.PROP_URL) || property.equals(Impl.PROP_TITLE)) { 670 HtmlBrowser.this.firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); 671 } 672 673 if (property.equals(Impl.PROP_URL)) { 674 updateLocationBar(); 675 } else if (property.equals(Impl.PROP_STATUS_MESSAGE)) { 676 String s = browserImpl.getStatusMessage(); 677 678 if ((s == null) || (s.length() < 1)) { 679 s = NbBundle.getMessage(HtmlBrowser.class, "CTL_Document_done"); 680 } 681 682 if (lStatusLine != null) { 683 lStatusLine.setText(s); 684 } 685 } else if (property.equals(Impl.PROP_FORWARD) && (bForward != null)) { 686 bForward.setEnabled(browserImpl.isForward()); 687 } else if (property.equals(Impl.PROP_BACKWARD) && (bBack != null)) { 688 bBack.setEnabled(browserImpl.isBackward()); 689 } else if (property.equals(Impl.PROP_HISTORY) && (bHistory != null)) { 690 bHistory.setEnabled(browserImpl.isHistory()); 691 } 692 } 693 694 697 public void actionPerformed(ActionEvent e) { 698 if (e.getSource() == cbLocation) { 699 if (everythinkIListenInCheckBoxIsUnimportant) { 701 return; 702 } 703 704 JComboBox cb = (JComboBox ) e.getSource(); 705 Object o = cb.getSelectedItem(); 706 707 if (o == null) { 709 return; 710 } 711 712 setURL((String ) o); 713 714 ListModel lm = cb.getModel(); 715 int i; 716 int k = lm.getSize(); 717 718 for (i = 0; i < k; i++) 719 if (o.equals(lm.getElementAt(i))) { 720 break; 721 } 722 723 if (i != k) { 724 return; 725 } 726 727 if (k == 20) { 728 cb.removeItem(lm.getElementAt(k - 1)); 729 } 730 731 cb.insertItemAt(o, 0); 732 } else 733 if (e.getSource() == bHistory) { 734 browserImpl.showHistory(); 735 } else 736 if (e.getSource() == bBack) { 737 browserImpl.backward(); 738 } else 739 if (e.getSource() == bForward) { 740 browserImpl.forward(); 741 } else 742 if (e.getSource() == bReload) { 743 updateLocationBar(); 744 browserImpl.reloadDocument(); 745 } else 746 if (e.getSource() == bHome) { 747 setURL(getHomePage()); 748 } else 749 if (e.getSource() == bStop) { 750 browserImpl.stopLoading(); 751 } 752 } 753 } 754 755 759 public static abstract class Impl { 760 761 static final long serialVersionUID = 2912844785502962114L; 762 763 764 public static final String PROP_STATUS_MESSAGE = "statusMessage"; 766 767 public static final String PROP_URL = "url"; 769 770 public static final String PROP_TITLE = "title"; 772 773 public static final String PROP_FORWARD = "forward"; 775 776 public static final String PROP_BACKWARD = "backward"; 778 779 public static final String PROP_HISTORY = "history"; 781 786 public abstract java.awt.Component getComponent(); 787 788 791 public abstract void reloadDocument(); 792 793 796 public abstract void stopLoading(); 797 798 803 public abstract void setURL(URL url); 804 805 810 public abstract URL getURL(); 811 812 817 public abstract String getStatusMessage(); 818 819 822 public abstract String getTitle(); 823 824 827 public abstract boolean isForward(); 828 829 831 public abstract void forward(); 832 833 836 public abstract boolean isBackward(); 837 838 840 public abstract void backward(); 841 842 845 public abstract boolean isHistory(); 846 847 849 public abstract void showHistory(); 850 851 856 public abstract void addPropertyChangeListener(PropertyChangeListener l); 857 858 863 public abstract void removePropertyChangeListener(PropertyChangeListener l); 864 } 865 866 871 public static abstract class URLDisplayer { 872 873 protected URLDisplayer() { 874 } 875 876 879 public static URLDisplayer getDefault() { 880 URLDisplayer dflt = (URLDisplayer) Lookup.getDefault().lookup(URLDisplayer.class); 881 882 if (dflt == null) { 883 dflt = new TrivialURLDisplayer(); 885 } 886 887 return dflt; 888 } 889 890 903 public abstract void showURL(URL u); 904 } 905 906 private static final class TrivialURLDisplayer extends URLDisplayer { 907 public TrivialURLDisplayer() { 908 } 909 910 public void showURL(URL u) { 911 HtmlBrowser browser = new HtmlBrowser(); 912 browser.setURL(u); 913 914 JFrame frame = new JFrame (); 915 frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 916 frame.getContentPane().add(browser); 917 frame.pack(); 918 frame.setVisible(true); 919 } 920 } 921 922 private class AccessibleHtmlBrowser extends JPanel.AccessibleJPanel { 923 AccessibleHtmlBrowser() { 924 } 925 926 public void setAccessibleName(String name) { 927 super.setAccessibleName(name); 928 929 if (browserComponent instanceof Accessible ) { 930 browserComponent.getAccessibleContext().setAccessibleName(name); 931 } 932 } 933 934 public void setAccessibleDescription(String desc) { 935 super.setAccessibleDescription(desc); 936 937 if (browserComponent instanceof Accessible ) { 938 browserComponent.getAccessibleContext().setAccessibleDescription(desc); 939 } 940 } 941 } 942 } 943 | Popular Tags |