Java tutorial
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall */ import java.awt.*; import java.awt.event.*; import java.beans.*; import java.io.*; import java.net.*; import java.util.*; import javax.swing.*; import javax.swing.text.*; import javax.swing.text.html.*; public class EditorPaneExample10A extends JFrame { public EditorPaneExample10A() { super("JEditorPane Example 10 - using getIterator"); pane = new JEditorPane(); pane.setEditable(false); // Read-only getContentPane().add(new JScrollPane(pane), "Center"); // Build the panel of controls JPanel panel = new JPanel(); panel.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.gridwidth = 1; c.gridheight = 1; c.anchor = GridBagConstraints.EAST; c.fill = GridBagConstraints.NONE; c.weightx = 0.0; c.weighty = 0.0; JLabel urlLabel = new JLabel("URL: ", JLabel.RIGHT); panel.add(urlLabel, c); JLabel loadingLabel = new JLabel("State: ", JLabel.RIGHT); c.gridy = 1; panel.add(loadingLabel, c); JLabel typeLabel = new JLabel("Type: ", JLabel.RIGHT); c.gridy = 2; panel.add(typeLabel, c); c.gridy = 3; panel.add(new JLabel(LOAD_TIME), c); c.gridy = 4; c.gridwidth = 2; c.weightx = 1.0; c.anchor = GridBagConstraints.WEST; onlineLoad = new JCheckBox("Online Load"); panel.add(onlineLoad, c); onlineLoad.setSelected(true); onlineLoad.setForeground(typeLabel.getForeground()); c.gridx = 1; c.gridy = 0; c.anchor = GridBagConstraints.EAST; c.fill = GridBagConstraints.HORIZONTAL; urlCombo = new JComboBox(); panel.add(urlCombo, c); urlCombo.setEditable(true); loadingState = new JLabel(spaces, JLabel.LEFT); loadingState.setForeground(Color.black); c.gridy = 1; panel.add(loadingState, c); loadedType = new JLabel(spaces, JLabel.LEFT); loadedType.setForeground(Color.black); c.gridy = 2; panel.add(loadedType, c); timeLabel = new JLabel(""); c.gridy = 3; panel.add(timeLabel, c); getContentPane().add(panel, "South"); // Change page based on combo selection urlCombo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if (populatingCombo == true) { return; } Object selection = urlCombo.getSelectedItem(); try { // Check if the new page and the old // page are the same. URL url; if (selection instanceof URL) { url = (URL) selection; } else { url = new URL((String) selection); } URL loadedURL = pane.getPage(); if (loadedURL != null && loadedURL.sameFile(url)) { return; } // Try to display the page urlCombo.setEnabled(false); // Disable input urlCombo.paintImmediately(0, 0, urlCombo.getSize().width, urlCombo.getSize().height); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); // Busy cursor loadingState.setText("Loading..."); loadingState.paintImmediately(0, 0, loadingState.getSize().width, loadingState.getSize().height); loadedType.setText(""); loadedType.paintImmediately(0, 0, loadedType.getSize().width, loadedType.getSize().height); timeLabel.setText(""); timeLabel.paintImmediately(0, 0, timeLabel.getSize().width, timeLabel.getSize().height); startTime = System.currentTimeMillis(); // Choose the loading method if (onlineLoad.isSelected()) { // Usual load via setPage pane.setPage(url); loadedType.setText(pane.getContentType()); } else { pane.setContentType("text/html"); loadedType.setText(pane.getContentType()); if (loader == null) { loader = new HTMLDocumentLoader(); } HTMLDocument doc = loader.loadDocument(url); loadComplete(); pane.setDocument(doc); displayLoadTime(); populateCombo(findLinks(doc, null)); enableInput(); } } catch (Exception e) { System.out.println(e); JOptionPane.showMessageDialog(pane, new String[] { "Unable to open file", selection.toString() }, "File Open Error", JOptionPane.ERROR_MESSAGE); loadingState.setText("Failed"); enableInput(); } } }); // Listen for page load to complete pane.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals("page")) { loadComplete(); displayLoadTime(); populateCombo(findLinks(pane.getDocument(), null)); enableInput(); } } }); } public void loadComplete() { loadingState.setText("Page loaded."); } public void enableInput() { urlCombo.setEnabled(true); // Allow entry of new URL setCursor(Cursor.getDefaultCursor()); } public void displayLoadTime() { double loadingTime = ((double) (System.currentTimeMillis() - startTime)) / 1000d; timeLabel.setText(loadingTime + " seconds"); } public void populateCombo(URL[] urls) { // Save existing selection Object o = urlCombo.getSelectedItem(); populatingCombo = true; urlCombo.setModel(new DefaultComboBoxModel(urls)); // Restore original selection urlCombo.setSelectedItem(o); populatingCombo = false; } public URL[] findLinks(Document doc, String protocol) { Vector links = new Vector(); Vector urlNames = new Vector(); URL baseURL = (URL) doc.getProperty(Document.StreamDescriptionProperty); if (doc instanceof HTMLDocument) { HTMLDocument.Iterator iterator = ((HTMLDocument) doc).getIterator(HTML.Tag.A); for (; iterator.isValid(); iterator.next()) { AttributeSet attrs = iterator.getAttributes(); Object linkAttr = attrs.getAttribute(HTML.Attribute.HREF); if (linkAttr instanceof String) { try { URL linkURL = new URL(baseURL, (String) linkAttr); if (protocol == null || protocol.equalsIgnoreCase(linkURL.getProtocol())) { String linkURLName = linkURL.toString(); if (urlNames.contains(linkURLName) == false) { urlNames.addElement(linkURLName); links.addElement(linkURL); } } } catch (MalformedURLException e) { // Ignore invalid links } } } } URL[] urls = new URL[links.size()]; links.copyInto(urls); links.removeAllElements(); urlNames.removeAllElements(); return urls; } public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) { } JFrame f = new EditorPaneExample10A(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setSize(500, 400); f.setVisible(true); } private static final String spaces = " "; private static final String LOAD_TIME = "Load time: "; private JEditorPane pane; private HTMLDocumentLoader loader; private JLabel loadingState; private JLabel timeLabel; private JLabel loadedType; private JCheckBox onlineLoad; private JComboBox urlCombo; private long startTime; private boolean populatingCombo; } class HTMLDocumentLoader { public HTMLDocument loadDocument(HTMLDocument doc, URL url, String charSet) throws IOException { doc.putProperty(Document.StreamDescriptionProperty, url); /* * This loop allows the document read to be retried if the character * encoding changes during processing. */ InputStream in = null; boolean ignoreCharSet = false; for (;;) { try { // Remove any document content doc.remove(0, doc.getLength()); URLConnection urlc = url.openConnection(); in = urlc.getInputStream(); Reader reader = (charSet == null) ? new InputStreamReader(in) : new InputStreamReader(in, charSet); HTMLEditorKit.Parser parser = getParser(); HTMLEditorKit.ParserCallback htmlReader = getParserCallback(doc); parser.parse(reader, htmlReader, ignoreCharSet); htmlReader.flush(); // All done break; } catch (BadLocationException ex) { // Should not happen - throw an IOException throw new IOException(ex.getMessage()); } catch (ChangedCharSetException e) { // The character set has changed - restart charSet = getNewCharSet(e); // Prevent recursion by suppressing further exceptions ignoreCharSet = true; // Close original input stream in.close(); // Continue the loop to read with the correct encoding } } return doc; } public HTMLDocument loadDocument(URL url, String charSet) throws IOException { return loadDocument((HTMLDocument) kit.createDefaultDocument(), url, charSet); } public HTMLDocument loadDocument(URL url) throws IOException { return loadDocument(url, null); } // Methods that allow customization of the parser and the callback public synchronized HTMLEditorKit.Parser getParser() { if (parser == null) { try { Class c = Class.forName("javax.swing.text.html.parser.ParserDelegator"); parser = (HTMLEditorKit.Parser) c.newInstance(); } catch (Throwable e) { } } return parser; } public synchronized HTMLEditorKit.ParserCallback getParserCallback(HTMLDocument doc) { return doc.getReader(0); } protected String getNewCharSet(ChangedCharSetException e) { String spec = e.getCharSetSpec(); if (e.keyEqualsCharSet()) { // The event contains the new CharSet return spec; } // The event contains the content type // plus ";" plus qualifiers which may // contain a "charset" directive. First // remove the content type. int index = spec.indexOf(";"); if (index != -1) { spec = spec.substring(index + 1); } // Force the string to lower case spec = spec.toLowerCase(); StringTokenizer st = new StringTokenizer(spec, " \t=", true); boolean foundCharSet = false; boolean foundEquals = false; while (st.hasMoreTokens()) { String token = st.nextToken(); if (token.equals(" ") || token.equals("\t")) { continue; } if (foundCharSet == false && foundEquals == false && token.equals("charset")) { foundCharSet = true; continue; } else if (foundEquals == false && token.equals("=")) { foundEquals = true; continue; } else if (foundEquals == true && foundCharSet == true) { return token; } // Not recognized foundCharSet = false; foundEquals = false; } // No charset found - return a guess return "8859_1"; } protected static HTMLEditorKit kit; protected static HTMLEditorKit.Parser parser; static { kit = new HTMLEditorKit(); } }