javax.swing.JEditorPaneを使って簡易ブラウザを作った。戻るボタンとリロードボタンは付けたが、まだフォームの処理や text/html 以外のContent-Typeの処理がない。
これに、先週の日記「Java用「winnytp://」プロトコルハンドラを作ってみたら簡単にできた」で作ったハンドラファクトリをセットしてみたところ、そのまま動いた。
ファイルのリンクをクリックするとそのサイトからそれをダウンロードする仕掛けになっている。しかし、プロトコルハンドラがダウンロード機能に対応していない。
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.io.*; import java.net.*; public class Nyzilla extends TinyWebBrowser { public static void main(String[] args) { URL.setURLStreamHandlerFactory(new WinnytpURLStreamHandlerFactory()); new Nyzilla(); } protected String getDefaultPage() { return "winnytp://"; } protected String getWindowTitle() { return "Nyzilla 0.2"; } } class TinyWebBrowser { public static void main(String[] args) { new TinyWebBrowser(); } TinyWebBrowser() { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } protected String getDefaultPage() { return "http://www.yahoo.co.jp/"; } protected String getWindowTitle() { return "TinyWebBrowser 0.2"; } protected Dimension getDefaultWindowSize() { return new Dimension(750, 800); } JPanel browserPanel; JTextField addressField = new JTextField(); JButton backButton = new JButton("Back"); JButton reloadButton = new JButton("Reload"); JLabel statusArea = new JLabel(" "); Cursor waitCursor = new Cursor(Cursor.WAIT_CURSOR); Page currentPage = null; java.util.Stack pageStack = new java.util.Stack(); static final Font font = new Font("SansSerif", Font.PLAIN, 14); private void createAndShowGUI() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { } JFrame f = new JFrame(getWindowTitle()); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); browserPanel = new JPanel(); browserPanel.setOpaque(true); browserPanel.setLayout(new BorderLayout()); JPanel addressBar = new JPanel(new BorderLayout()); JLabel l = new JLabel("Address (URL): "); l.setFont(font); addressBar.add(l, BorderLayout.LINE_START); addressField.setFont(font); setAddress(getDefaultPage()); addressField.addActionListener(new AddressEnterAction()); addressBar.add(addressField, BorderLayout.CENTER); JPanel buttonPanel = new JPanel(new FlowLayout()); backButton.addActionListener(new BackButtonAction()); backButton.setEnabled(false); buttonPanel.add(backButton); reloadButton.addActionListener(new ReloadButtonAction()); buttonPanel.add(reloadButton); addressBar.add(buttonPanel, BorderLayout.LINE_END); browserPanel.add(addressBar, BorderLayout.PAGE_START); statusArea.setFont(font); browserPanel.add(statusArea, BorderLayout.PAGE_END); f.setContentPane(browserPanel); f.setSize(getDefaultWindowSize()); f.setVisible(true); } class Page { JScrollPane pane; JEditorPane editor; Page() { editor = new JEditorPane(); editor.setEditable(false); editor.setContentType("text/html"); pane = new JScrollPane(editor); pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); editor.addHyperlinkListener(new HyperlinkAction()); } void setPage(String url) throws IOException { if (url == null || url.length() == 0) return; try { browserPanel.setCursor(waitCursor); editor.setPage(url); setAddress(editor.getPage().toString()); } catch (IOException e) { showAccessError(e); throw e; } finally { browserPanel.setCursor(Cursor.getDefaultCursor()); } } } class HyperlinkAction implements HyperlinkListener { public void hyperlinkUpdate(HyperlinkEvent v) { HyperlinkEvent.EventType t = v.getEventType(); if (t == HyperlinkEvent.EventType.ACTIVATED) { String url = v.getURL().toString(); statusArea.setText(" "); replaceLocation(url); } else if (t == HyperlinkEvent.EventType.ENTERED) { String url = v.getURL().toString(); statusArea.setText(url); } else if (t == HyperlinkEvent.EventType.EXITED) { statusArea.setText(" "); } } } class AddressEnterAction implements ActionListener { public void actionPerformed(ActionEvent v) { String url = addressField.getText(); replaceLocation(url); } } private void replaceLocation(String url) { try { Page newPage = new Page(); newPage.setPage(url); if (currentPage != null) { pageStack.push(currentPage); backButton.setEnabled(true); browserPanel.remove(currentPage.pane); } currentPage = newPage; browserPanel.add(newPage.pane, BorderLayout.CENTER); refresh(); setAddress(newPage.editor.getPage().toString()); } catch (IOException e) { } } class BackButtonAction implements ActionListener { public void actionPerformed(ActionEvent v) { if (pageStack.isEmpty()) return; backButton.setEnabled(false); Page prevPage = (Page)pageStack.pop(); browserPanel.remove(currentPage.pane); currentPage = prevPage; browserPanel.add(currentPage.pane, BorderLayout.CENTER); refresh(); if (!pageStack.isEmpty()) { backButton.setEnabled(true); } } } class ReloadButtonAction implements ActionListener { public void actionPerformed(ActionEvent v) { String url = currentPage.editor.getPage().toString(); try { reloadButton.setEnabled(false); Page newPage = new Page(); newPage.setPage(url); browserPanel.remove(currentPage.pane); currentPage = newPage; browserPanel.add(newPage.pane, BorderLayout.CENTER); refresh(); setAddress(newPage.editor.getPage().toString()); } catch (IOException e) { } finally { reloadButton.setEnabled(true); } } } private void refresh() { browserPanel.validate(); browserPanel.repaint(); } private void setAddress(String url) { addressField.setText(url); addressField.setCaretPosition(0); } private void showAccessError(Exception e) { JOptionPane.showMessageDialog( browserPanel, e.toString(), "Access Error", JOptionPane.ERROR_MESSAGE ); } }
javax.swing.JEditorPaneを用いた簡易Webブラウザの例
http://takagi-hiromitsu.jp/diary/20060701.html#p01 このツールを使えば自分がキンタマウイルスに感染することなく他人の流出情報を安全に探すことができるぞ!
ポジティブシンキングばかりでは、見落とす・無理難題をほおって置いて現場がやる気な