<前の日記(2006年06月25日) 次の日記(2006年07月02日)> 最新 編集

高木浩光@自宅の日記

目次 はじめに 連絡先:blog@takagi-hiromitsu.jp
訪問者数 本日: 2474   昨日: 17345

2006年07月01日

簡易Webブラウザに winnytp:// プロトコルハンドラを組み込んでみた

javax.swing.JEditorPaneを使って簡易ブラウザを作った。戻るボタンとリロードボタンは付けたが、まだフォームの処理や text/html 以外のContent-Typeの処理がない。

これに、先週の日記「Java用「winnytp://」プロトコルハンドラを作ってみたら簡単にできた」で作ったハンドラファクトリをセットしてみたところ、そのまま動いた。

図1: コマンド4とコマンド13の受信から他のサイトへのリンク集を表示した様子

図2: コマンド13の受信からこのサイトが自ら「このファイルを送信可能です」と主張しているものを表示した様子

ファイルのリンクをクリックするとそのサイトからそれをダウンロードする仕掛けになっている。しかし、プロトコルハンドラがダウンロード機能に対応していない。

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ブラウザの例


<前の日記(2006年06月25日) 次の日記(2006年07月02日)> 最新 編集

最近のタイトル

2000|01|
2003|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|05|06|07|08|09|10|11|12|
2012|02|03|04|05|06|07|08|09|
2013|01|02|03|04|05|06|07|
2014|01|04|07|09|11|12|
2015|01|03|06|07|10|11|12|
2016|01|02|03|04|06|07|08|10|11|12|
2017|01|02|03|04|05|06|07|10|12|
2018|03|05|06|10|12|
2019|02|03|05|06|07|08|10|
2020|08|09|
2021|07|08|10|12|
2022|01|04|06|12|
2023|03|
2024|03|04|07|11|12|
2025|01|02|03|04|05|06|10|11|12|
<前の日記(2006年06月25日) 次の日記(2006年07月02日)> 最新 編集