package org.jscience.net; import org.jscience.util.Settings; import org.jscience.util.gui.CloseButton; import org.jscience.util.gui.ImageViewer; import org.jscience.util.gui.JMainFrame; import org.jscience.util.gui.Menus; import javax.swing.*; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import java.awt.*; import java.awt.event.*; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Stack; /** * A very plain Web Browser with minimal functionality; but still cool. * <p/> * Unfortunately, the caching doesn't work for the main display, yet. <p> * Check out the multiple right-mouse-click options. :-) <p> * At this point, the implementation is completely transient, i.e. * nothing is written to disk other than what you explicitly save; * so your homepage settings, cache and favorites are reset when you * restart the browser. <p> * No support for cookies (that may be the good news ;-), JavaScript, * forms, etc. at this point. <p> * There are several other limitations as this implementation is just based * on the javax.swing.JEditorPane at this point. * However, there are also some features that your average browser does NOT have, * such as the display of the server information in the view menu. * <p/> * To use a customized HTTP Agent when connecting to a web-server, you need to * set the system property <dfn>http.agent</dfn> accordingly before using this * class. * * @author Holger Antelmann * @see JSpider * @see javax.swing.JEditorPane */ public class JWebBrowser extends JMainFrame { static final long serialVersionUID = 8894203216788969688L; URL home; URLCache current; HashMap<URL, URLCache> cache; Stack<URLCache> history; Stack<URLCache> forwards; Stack<URL> favorites; JMenu favMenu; JButton stopButton; URLCache nowLoading; JURLCachePane textPane; JTextField textUrlField; JFileChooser fchooser; URL hyperlinkHoover; volatile boolean busy; /** * needed for the @#$*@#$ JEditorPane to reload the page in refresh() */ static URLCache blankPage = new URLCache(Settings.getResource("org/jscience/blank_page.htm")); String[] favoriteDefaults = new String[]{ Settings.getProperty("application.vendor.url"), Settings.getProperty("application.documentation.url"), "http://www.gnu.org/", "http://java.sun.com/", "http://localhost/" }; /** * initializes with a blank page */ public JWebBrowser() { this(blankPage); } public JWebBrowser(String urlHomeSpec) throws IOException { this(new URL(urlHomeSpec)); } public JWebBrowser(URL homeURL) { this(new URLCache(homeURL)); } public JWebBrowser(URLCache homeURLCache) { super("Holger's Java Browser", false, true); home = homeURLCache.getURL(); textUrlField = new JTextField(home.toString()); fchooser = new JFileChooser(); history = new Stack<URLCache>(); forwards = new Stack<URLCache>(); favorites = new Stack<URL>(); cache = new HashMap<URL, URLCache>(); textPane = new JURLCachePane(cache); textPane.setContentType("text/html"); textPane.setEditable(false); textPane.addHyperlinkListener(new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { if (!busy) setPage(e.getURL()); } else if (e.getEventType() == HyperlinkEvent.EventType.ENTERED) { hyperlinkHoover = e.getURL(); if (!busy) updateStatusText(e.getURL().toString()); } else if (e.getEventType() == HyperlinkEvent.EventType.EXITED) { hyperlinkHoover = null; if (!busy) updateStatusText(" "); } } }); textPane.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { popup(e); } public void mouseReleased(MouseEvent e) { popup(e); } void popup(MouseEvent e) { if (e.isPopupTrigger()) { JPopupMenu menu = getPopupMenu(); if (hyperlinkHoover != null) { JMenuItem item = new JMenuItem("open in new window"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { URL url = hyperlinkHoover; if (url == null) return; JWebBrowser jwb = new JWebBrowser(url); jwb.setDefaultCloseOperation(DISPOSE_ON_CLOSE); jwb.setVisible(true); } }); menu.insert(item, 0); item = new JMenuItem("save link"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { download(hyperlinkHoover); } }); menu.insert(item, 0); } menu.show(e.getComponent(), e.getX(), e.getY()); } } }); JScrollPane scrollPane = new JScrollPane(textPane); Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); screen.setSize((int) screen.getWidth() / 2, (int) screen.getHeight() / 2); scrollPane.setPreferredSize(screen); getContentPane().add(scrollPane, BorderLayout.CENTER); getContentPane().add(getToolBar(), BorderLayout.NORTH); setJMenuBar(getMenu()); current = homeURLCache; cache.put(current.getURL(), current); setPage(current.getURL()); pack(); } JMenuBar getMenu() { JMenuBar menuBar = new JMenuBar(); JMenuItem item; JMenu fileMenu = new JMenu("File"); fileMenu.setMnemonic(KeyEvent.VK_F); menuBar.add(fileMenu); { item = new JMenuItem("Save page as .."); item.setMnemonic(KeyEvent.VK_S); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { download(current); } }); fileMenu.add(item); item = new JMenuItem("Close"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { dispose(); } }); item.setMnemonic(KeyEvent.VK_C); fileMenu.add(item); item = new JMenuItem("Exit"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); item.setMnemonic(KeyEvent.VK_X); fileMenu.add(item); } JMenu viewMenu = new JMenu("View"); viewMenu.setMnemonic(KeyEvent.VK_V); menuBar.add(viewMenu); { item = new JMenuItem("show header info"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { final JDialog dialog = new JDialog(JWebBrowser.this, "header info", true); dialog.getContentPane().setLayout(new BorderLayout()); String s = "cannot access header"; try { s = new Spider(current.getURL()).fullHeaderAsString(); } catch (IOException ex) { } JTextArea pane = new JTextArea(s); pane.setEditable(false); dialog.getContentPane().add(pane, BorderLayout.CENTER); dialog.getContentPane().add(new CloseButton(dialog), BorderLayout.SOUTH); dialog.pack(); dialog.setLocationRelativeTo(JWebBrowser.this); dialog.setVisible(true); } }); viewMenu.add(item); item = new JMenuItem("show Whois registration info"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { final JDialog dialog = new JDialog(JWebBrowser.this, "Whois registration info", true); dialog.getContentPane().setLayout(new BorderLayout()); String s = null; try { s = new Spider(current.getURL()).whois(); } catch (IOException ex) { } if (s == null) s = "cannot access Whois registration info"; JTextArea pane = new JTextArea(s); pane.setEditable(false); dialog.getContentPane().add(new JScrollPane(pane), BorderLayout.CENTER); dialog.getContentPane().add(new CloseButton(dialog), BorderLayout.SOUTH); dialog.pack(); dialog.setLocationRelativeTo(JWebBrowser.this); dialog.setVisible(true); } }); viewMenu.add(item); MenuElement[] elements = getPopupMenu().getSubElements(); for (int i = 0; i < elements.length; i++) { viewMenu.add((Component) elements[i]); } } favMenu = new JMenu("Favorites"); favMenu.setMnemonic(KeyEvent.VK_A); menuBar.add(favMenu); { item = new JMenuItem("add to favorites"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { final URLCache uc = current; favorites.add(uc.getURL()); JMenuItem nf = new JMenuItem(uc.getURL().toString()); nf.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { setPage(uc.getURL()); } }); favMenu.add(nf); } }); item.setMnemonic(KeyEvent.VK_A); favMenu.add(item); JMenu defaults = new JMenu("defaults"); { for (int i = 0; i < favoriteDefaults.length; i++) { item = new JMenuItem(favoriteDefaults[i]); final int n = i; item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { try { setPage(new URL(favoriteDefaults[n])); } catch (IOException e) { } } }); defaults.add(item); } } favMenu.add(defaults); favMenu.addSeparator(); } JMenu toolsMenu = new JMenu("Tools"); toolsMenu.setMnemonic(KeyEvent.VK_T); menuBar.add(toolsMenu); { item = new JMenuItem("Messenger"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { JMessenger js = new JMessenger(); js.setDefaultCloseOperation(DISPOSE_ON_CLOSE); js.setVisible(true); } catch (IOException ex) { JOptionPane.showMessageDialog(JWebBrowser.this, ex.getMessage(), "Messenger failed to start", JOptionPane.ERROR_MESSAGE); } } }); item.setMnemonic(KeyEvent.VK_U); toolsMenu.add(item); item = new JMenuItem("Chat client"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JChat js = new JChat(); js.setDefaultCloseOperation(DISPOSE_ON_CLOSE); js.setVisible(true); } }); item.setMnemonic(KeyEvent.VK_U); toolsMenu.add(item); item = new JMenuItem("URL tree"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JSpider js = new JSpider(current.getURL()); js.setDefaultCloseOperation(DISPOSE_ON_CLOSE); js.setVisible(true); } }); item.setMnemonic(KeyEvent.VK_U); toolsMenu.add(item); } JMenu optionMenu = new JMenu("Options"); optionMenu.setMnemonic(KeyEvent.VK_O); menuBar.add(optionMenu); { item = new JMenuItem("set current page as home"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setHome(current.getURL()); } }); item.setMnemonic(KeyEvent.VK_S); optionMenu.add(item); item = new JMenuItem("set HTTP agent"); item.setToolTipText("this determines how the browser identifies itself"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String p = JOptionPane.showInputDialog(JWebBrowser.this, "enter HTTP agent identification:", System.getProperty("http.agent", "Java1.4.0")); if (p != null) System.setProperty("http.agent", p); } }); item.setMnemonic(KeyEvent.VK_S); optionMenu.add(item); item = new JMenuItem("validate links in page"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { validateLinks(current); } }); item.setMnemonic(KeyEvent.VK_V); optionMenu.add(item); item = new JMenuItem("clear cache"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { synchronized (cache) { Iterator i = cache.keySet().iterator(); while (i.hasNext()) { ((URLCache) cache.get((URL) i.next())).clearCache(); } } } }); item.setMnemonic(KeyEvent.VK_V); optionMenu.add(item); } JMenu winMenu = new JMenu("Window"); winMenu.setMnemonic(KeyEvent.VK_W); menuBar.add(winMenu); { winMenu.add(Menus.createLookAndFeelMenu(this)); } JMenu helpMenu = new JMenu("Help"); helpMenu.setMnemonic(KeyEvent.VK_H); helpMenu.add(Menus.createAboutDialogMenuItem(this)); menuBar.add(helpMenu); return menuBar; } JPopupMenu getPopupMenu() { JPopupMenu miniMenu = new JPopupMenu(); JMenuItem item; item = new JMenuItem("HTML code"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { viewHTML(); } }); item.setMnemonic(KeyEvent.VK_H); miniMenu.add(item); item = new JMenuItem("plain text"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { viewTextOnly(); } }); item.setMnemonic(KeyEvent.VK_T); miniMenu.add(item); item = new JMenuItem("links"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { viewLinkList(); } }); item.setMnemonic(KeyEvent.VK_L); miniMenu.add(item); item = new JMenuItem("embedded images"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { viewImageList(); } }); item.setMnemonic(KeyEvent.VK_I); miniMenu.add(item); return miniMenu; } JToolBar getToolBar() { JToolBar tools = new JToolBar(); tools.setRollover(true); //tools.setMargin(new Insets(1, 1, 1, 1)); ImageIcon icon = new ImageIcon(Settings.getResource("org/jscience/awt/icons/navigation/Back16.gif")); JButton button = new JButton(icon); button.setToolTipText("Back"); button.setMnemonic(KeyEvent.VK_B); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { back(); } }); tools.add(button); icon = new ImageIcon(Settings.getResource("org/jscience/awt/icons/navigation/Forward16.gif")); button = new JButton(icon); button.setToolTipText("Forward"); button.setMnemonic(KeyEvent.VK_R); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { forward(); } }); tools.add(button); icon = new ImageIcon(Settings.getResource("org/jscience/awt/icons/navigation/Home16.gif")); button = new JButton(icon); button.setToolTipText("Home"); button.setMnemonic(KeyEvent.VK_M); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setPage(home); } }); tools.add(button); icon = new ImageIcon(Settings.getResource("org/jscience/awt/icons/general/Refresh16.gif")); button = new JButton(icon); button.setToolTipText("Refresh"); button.setMnemonic(KeyEvent.VK_R); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { refresh(); } }); tools.add(button); icon = new ImageIcon(Settings.getResource("org/jscience/awt/icons/general/Stop16.gif")); stopButton = new JButton(icon); stopButton.setToolTipText("Stop"); stopButton.setMnemonic(KeyEvent.VK_S); stopButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { stopLoading(); } }); stopButton.setEnabled(false); tools.add(stopButton); tools.addSeparator(); textUrlField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { setPage(new URL(textUrlField.getText())); } catch (MalformedURLException ex) { try { setPage(new URL("http://" + textUrlField.getText())); } catch (MalformedURLException exc) { updateStatusText("entered URL invalid"); } } } }); tools.add(textUrlField); return tools; } /** * shows a window with only the text stripped from the HTML */ protected void viewTextOnly() { try { JTextArea text = new JTextArea(current.stripText()); final JDialog dialog = new JDialog(this, "plain text", true); dialog.getContentPane().setLayout(new BorderLayout()); JScrollPane pane = new JScrollPane(text); Dimension d = new Dimension((int) getSize().getWidth(), (int) (getSize().getHeight() * 0.7)); pane.setPreferredSize(d); dialog.getContentPane().add(pane, BorderLayout.CENTER); dialog.getContentPane().add(new CloseButton(dialog), BorderLayout.SOUTH); dialog.pack(); dialog.setLocationRelativeTo(this); dialog.setVisible(true); } catch (IOException e) { updateStatusText("could not load text"); return; } } /** * shows a window with the HTML code */ protected void viewHTML() { try { JTextArea text = new JTextArea(current.getContentAsString()); final JDialog dialog = new JDialog(this, "HTML code", true); dialog.getContentPane().setLayout(new BorderLayout()); JScrollPane pane = new JScrollPane(text); Dimension d = new Dimension((int) getSize().getWidth(), (int) (getSize().getHeight() * 0.7)); pane.setPreferredSize(d); dialog.getContentPane().add(pane, BorderLayout.CENTER); dialog.getContentPane().add(new CloseButton(dialog), BorderLayout.SOUTH); dialog.pack(); dialog.setLocationRelativeTo(this); dialog.setVisible(true); } catch (IOException e) { updateStatusText("could not HTML code"); return; } } /** * shows a window with the embedded images from the current page */ protected void viewImageList() { final JDialog dialog = new JDialog(this, "embedded images", false); dialog.getContentPane().setLayout(new BorderLayout()); final Stack<ImageViewer> viewers = new Stack<ImageViewer>(); final JList list; try { list = new JList(URLSorter.sort(current.getImages())); } catch (IOException e) { JOptionPane.showMessageDialog(this, e.getMessage(), "cannot retrieve images", JOptionPane.ERROR_MESSAGE); //updateStatusText(" "); return; } list.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { URL url = (URL) list.getSelectedValue(); ImageIcon icon = new ImageIcon(url); ImageViewer v = new ImageViewer(icon, url.toString()); viewers.add(v); v.setVisible(true); } } public void mousePressed(MouseEvent e) { popup(e); } public void mouseReleased(MouseEvent e) { popup(e); } void popup(MouseEvent e) { if (e.isPopupTrigger()) { JPopupMenu menu = new JPopupMenu(); JMenuItem item = new JMenuItem("save image"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { URL url = (URL) list.getSelectedValue(); if (url == null) { JOptionPane.showMessageDialog(dialog, "no image selected"); } else { download(url); } } }); menu.add(item); menu.show(e.getComponent(), e.getX(), e.getY()); } } }); dialog.getContentPane().add(new JScrollPane(list), BorderLayout.CENTER); JButton button = new JButton("Close"); button.setMnemonic(KeyEvent.VK_C); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { for (int i = 0; i < viewers.size(); i++) { ((ImageViewer) viewers.get(i)).setVisible(false); ((ImageViewer) viewers.get(i)).dispose(); } dialog.setVisible(false); } }); dialog.getContentPane().add(button, BorderLayout.SOUTH); dialog.pack(); dialog.setLocationRelativeTo(this); dialog.setVisible(true); //updateStatusText(" "); } /** * shows a window with the links from the given page * (as probably not all links are accessible via hyperlink from the * JEditorPane) */ protected void viewLinkList() { final JDialog dialog = new JDialog(this, "link list", true); dialog.getContentPane().setLayout(new BorderLayout()); final JList list; try { list = new JList(URLSorter.sort(current.getLinks())); } catch (IOException e) { JOptionPane.showMessageDialog(this, e.getMessage(), "cannot retrieve links", JOptionPane.ERROR_MESSAGE); //updateStatusText(" "); return; } list.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { setPage((URL) list.getSelectedValue()); } } public void mousePressed(MouseEvent e) { popup(e); } public void mouseReleased(MouseEvent e) { popup(e); } void popup(MouseEvent e) { if (e.isPopupTrigger()) { JPopupMenu menu = new JPopupMenu(); JMenuItem item = new JMenuItem("save link"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { URL url = (URL) list.getSelectedValue(); if (url == null) { JOptionPane.showMessageDialog(dialog, "no link selected"); } else { download(url); } } }); menu.add(item); item = new JMenuItem("open in new window"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { URL url = (URL) list.getSelectedValue(); if (url == null) return; JWebBrowser jwb = new JWebBrowser(url); jwb.setDefaultCloseOperation(DISPOSE_ON_CLOSE); jwb.setVisible(true); } }); menu.add(item); menu.show(e.getComponent(), e.getX(), e.getY()); } } }); dialog.getContentPane().add(new JScrollPane(list), BorderLayout.CENTER); dialog.getContentPane().add(new CloseButton(dialog), BorderLayout.SOUTH); dialog.pack(); dialog.setLocationRelativeTo(this); dialog.setVisible(true); //updateStatusText(" "); } /** * shows a window with the broken links in this page */ protected void validateLinks(final URLCache uc) { if (busy) return; busy = true; new Thread() { public void run() { validateLinksInThread(uc); } }.start(); updateStatusText("validating links .."); } /** * executes outside the event handler thread */ private void validateLinksInThread(URLCache uc) { final URL[] broken; try { broken = URLSorter.sort(new Spider(uc.getURL()).getBrokenLinks()); } catch (IOException e) { JOptionPane.showMessageDialog(this, e.getMessage(), "cannot verify links", JOptionPane.ERROR_MESSAGE); updateStatusText(" "); return; } if (broken.length == 0) { JOptionPane.showMessageDialog(this, "no broken links in current page", "links validated", JOptionPane.INFORMATION_MESSAGE); updateStatusText(" "); return; } Runnable showDialog = new Runnable() { public void run() { // this is going to be performed in the event handler thread again JDialog dialog = new JDialog(JWebBrowser.this, "broken links", true); dialog.getContentPane().setLayout(new BorderLayout()); JList list = new JList(broken); dialog.getContentPane().add(new JScrollPane(list), BorderLayout.CENTER); dialog.getContentPane().add(new CloseButton(dialog), BorderLayout.SOUTH); dialog.pack(); dialog.setLocationRelativeTo(JWebBrowser.this); dialog.setVisible(true); updateStatusText(" "); busy = false; } }; SwingUtilities.invokeLater(showDialog); } /** * implements the action for the browser's refresh button */ public void refresh() { URLCache tmp = current; current.clearCache(); setPage(blankPage); busy = false; setPage(tmp); } /** * sets the current page for the browser's main window; * the call may be ignored if the browser is currently * busy loading another page (preventing multiple loads) */ public void setPage(URL url) { URLCache uc; synchronized (cache) { if (cache.containsKey(url)) { uc = (URLCache) cache.get(url); } else { uc = new URLCache(url); cache.put(url, uc); } } history.push(current); forwards.clear(); setPage(uc); } /** * only to be called by back(), forward() and refresh(), * as it doesn't maintain history; use setPage(URL) otherwise */ private void setPage(final URLCache uc) { if (busy) return; busy = true; new Thread() { public void run() { loadPageInThread(uc); } }.start(); nowLoading = uc; stopButton.setEnabled(true); updateStatusText("loading page .."); } /** * executes outside the event handler thread and is only called by setPage(URLCache) */ private void loadPageInThread(final URLCache uc) { // loading URL into cache uc.waitForRefresh(); stopButton.setEnabled(false); // put the remainder back in the event handler thread Runnable showstuff = new Runnable() { public void run() { try { String type = uc.getContentType(); if ((type != null) && (type.indexOf("mage/") > 0)) { ImageViewer iv = new ImageViewer(new ImageIcon(uc.getURL()), uc.getURL().toString()); iv.setVisible(true); updateStatusText("displaying image in external viewer"); busy = false; return; } // textPane.setPage(uc); textPane.setPage(uc.getURL()); current = uc; textUrlField.setText(current.getURL().toString()); updateStatusText("page loaded: " + ((current.getTitle().length() == 0) ? "(no title)" : current.getTitle())); } catch (IOException e) { // todo //textPane.setPage((URL)null); current = uc; textUrlField.setText(current.getURL().toString()); updateStatusText("page loaded with error: " + current.getURL().toString()); JOptionPane.showMessageDialog(JWebBrowser.this, e.getMessage(), "page load error", JOptionPane.ERROR_MESSAGE); updateStatusText(" "); } busy = false; } }; SwingUtilities.invokeLater(showstuff); } /** * implements the action for the browser's stop button */ public void stopLoading() { if (!stopButton.isEnabled()) return; stopButton.setEnabled(false); nowLoading.stopCurrentRefresh(); } /** * downloads the given URL with a JDownloader after the GUI * asked for the file name * * @see JDownloader */ protected void download(URL url) { if (url == null) return; URLCache uc; synchronized (cache) { if (cache.containsKey(url)) { uc = (URLCache) cache.get(url); } else { uc = new URLCache(url); cache.put(url, uc); } } download(uc); } void download(final URLCache uc) { if (uc == null) return; if (busy) return; fchooser.setDialogTitle("download URL"); if (uc.getURL().getProtocol().equals("mailto")) { JOptionPane.showMessageDialog(this, "cannot download email links"); updateStatusText(" "); return; } String path = uc.getURL().toExternalForm(); path = path.substring(path.lastIndexOf("/")); if (path.length() < 2) path = "default.html"; fchooser.setSelectedFile(new File(fchooser.getCurrentDirectory(), path)); int option = fchooser.showSaveDialog(this); if (option == fchooser.APPROVE_OPTION) { if (!uc.isCached()) uc.refresh(); File file = fchooser.getSelectedFile(); new JDownloader(this, uc, file).start(); } } /** * implements the action for the browser's back button */ public void back() { if (busy) return; if (history.size() > 0) { setPage((URLCache) history.peek()); forwards.push(current); current = (URLCache) history.pop(); textUrlField.setText(current.getURL().toString()); } } /** * implements the action for the browser's forward button */ public void forward() { if (busy) return; if (forwards.size() > 0) { setPage((URLCache) forwards.peek()); history.push(current); current = (URLCache) forwards.pop(); textUrlField.setText(current.getURL().toString()); } } /** * returns the page currently set as the home page */ public URL getHome() { return home; } /** * returns the list of favorites */ public URL[] getFavorites() { return (URL[]) favorites.toArray(new URL[favorites.size()]); } /* sets the home page that can be accessed using the browser's home button */ public void setHome(URL homeURL) { if (homeURL == null) throw new IllegalArgumentException(); home = homeURL; } /** * returns the page currently displayed */ public URL getCurrentURL() { return current.getURL(); } /** * returns a map of URL objects to URLCache objects */ public Map getCache() { return cache; } /** * starts the JWebBrowser and makes it visible; * you can optionally specify a URL as parameter */ public static void main(String[] args) throws Exception { if (args.length > 0) { new JWebBrowser(new URL(args[0])).setVisible(true); } else { new JWebBrowser().setVisible(true); } } }