submitイベントでフォームの入力内容を取得

ユーザがフォームに入力した内容を得るのに最も簡単な方法はsubmitボタンが押されたときに発行されるイベントを処理することです。 FormSubmitEventがそれに当たります。 FormSubmitEventはHyperlinkEventのサブクラスで、リンクをクリックしたときと同様にHyperlinkListenerで受け取れます。

JEditorPaneはデフォルトでユーザの編集を受け付けています。 setEditableメソッドで編集不可にしておきましょう。 プレーンテキストを読み込む設定になっているのでsetContentTypeメソッドでhtmlファイルを読むように指定します。

editorPane.setEditable(false);
editorPane.setContentType("text/html");

HTMLEditorKitの設定も必要です。 デフォルトの設定だと、submitボタンを押すとFormタグのaction属性で指定されたページに移動してしまいます。 アプリケーションのUIにフォームを使う場合、移動を無効にします。 スタイルシートはhtmlファイルに記述しても読み込まれません。 javaのコードで読み込む必要があります。

HTMLEditorKit editorKit = (HTMLEditorKit)editorPane.getEditorKit();
editorKit.setAutoFormSubmission(false);
File cssFile = new File(スタイルシートファイル名);
editorKit.getStyleSheet().importStyleSheet(cssFile.toURI().toURL() );

setPageメソッドでhtmlファイルを読み込みます。 JEditorPaneはhtml3.2にしか対応していないのでbuttonやselectのoptgroupなど一部のタグは使用できません。 しかし中途半端にhtml4.0以降のタグに対応しているらしく、metaタグのcharsetは反映されるようです。

File htmlFile = new File(htmlファイル名);
editorPane.setPage(htmlFile.toURI().toURL() );

submitイベントの処理

HyperlinkListenerインターフェースのhyperlinkUpdateメソッドでHyperlinkEventを受け取ります。 そのインスタンスがFormSubmitEventならgetDataメソッドでパラメータを調べます。 パラメータはコンポーネントタグのname属性と入力値の対を&でつないだ文字列です。 次のような形になります。

password=abc&checkbox2=checkbox2&test_radio=radio2&select_list=...

コンポーネントタグにname属性が書かれていない場合はパラメータに反映しません。 チェックボックスの場合はチェックされていなければ省略されます。 テキスト入力コンポーネントの場合はユーザの入力が空ならば省略されます。

submitボタンにname属性が付いているとパラメータにname属性の値が追加されます。 例えば、次のようなsubmitボタンの場合、

<input type="submit" name="ボタン名" value="ボタンのラベル">

「&ボタン名=ボタンのラベル」という項目が追加されます。 イメージボタンもsubmitボタンと同様の効果を持っています。 イメージボタンの場合はパラメータにボタン上のどこを押したか座標データが追加されます。 例えば、「&ボタン名.x=132&ボタン名.y=39」などの項目です。

// HyperlinkListenerインターフェイスのhyperlinkUpdateを実装
public void hyperlinkUpdate(HyperlinkEvent event)
{
    if(event instanceof FormSubmitEvent)
    {
        String paramData = ( (FormSubmitEvent)event).getData();
        String[] params = paramData.split("&");
        for(String param : params)
        {
            // 各パラメータに対する処理
            // 省略される項目もあるので注意
        }
    }
}

getDataの戻り値はURLエンコーディングされています。 日本語を使用する場合はjava.net.URLDecoderでデコードしましょう。 私が試した環境ではhtmlに指定した文字コードに関わらずデフォルトのCharsetを使うと上手くいきました。

String paramData = ( (FormSubmitEvent)event).getData();
String charset = Charset.defaultCharset().toString();
paramData = URLDecoder.decode(paramData, charset);

サンプルコード

以下はサンプルコードの全文です。 フォームに入力された内容、クリックされたリンク先をダイアログに表示します。 htmlファイルなどはネタのトップからダウンロードしてください。

// SubmitTest.java
import java.io.File;
import java.util.Enumeration;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.text.html.*;

public class SubmitTest extends JFrame implements HyperlinkListener
{
    public static final String TEST_HTML = "jeditorpane_test.html";
    public static final String TEST_CSS = "jeditorpane_test.css";
    
    public SubmitTest()
    {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        try
        {
            JEditorPane editorPane = new JEditorPane();
            editorPane.setEditable(false);
            editorPane.setContentType("text/html");
            
            HTMLEditorKit editorKit = (HTMLEditorKit)editorPane.getEditorKit();
            editorKit.setAutoFormSubmission(false);
            File cssFile = new File(TEST_CSS);
            editorKit.getStyleSheet().importStyleSheet(cssFile.toURI().toURL() );
            
            File htmlFile = new File(TEST_HTML);
            editorPane.setPage(htmlFile.toURI().toURL() );
            JScrollPane scrollPane = new JScrollPane(editorPane);
            getContentPane().add(scrollPane);
            
            editorPane.addHyperlinkListener(this);
        }
        catch(Exception exc)
        {
            exc.printStackTrace();
        }
    }
    
    public static void main(String[] args)
    {
        SubmitTest app = new SubmitTest();
        app.setSize(640, 480);
        app.setVisible(true);
    }
    
    public void hyperlinkUpdate(HyperlinkEvent event)
    {
        try
        {
            // submitボタンまたはイメージボタンが押された場合は
            // フォームの入力内容をダイアログに表示
            if(event instanceof FormSubmitEvent)
            {
                String msg = "FormSubmitEvent\n";

                String paramData = ( (FormSubmitEvent)event).getData();
                String charset = Charset.defaultCharset().toString();
                paramData = URLDecoder.decode(paramData, charset);

                String[] params = paramData.split("&");
                for(String param : params)
                {
                    msg += param + "\n";
                }
                System.err.println(msg);
                JOptionPane.showMessageDialog(this, msg);
            }
            // リンクがクリックされた場合はリンク先をダイアログに表示
            else
            {
                HyperlinkEvent.EventType eventType = event.getEventType();
                if(eventType == HyperlinkEvent.EventType.ACTIVATED)
                {
                    String msg = "HyperlinkEvent.EventType.ACTIVATED\n";
                    msg += event.getURL().toString();
                    System.err.println(msg);
                    JOptionPane.showMessageDialog(this, msg);
                }
            }
        }
        catch(Exception exc)
        {
            exc.printStackTrace();
        }
    }
}