SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Swing再入門

Swing再入門 マルチフォントへの対応

第4回 JTextPaneを使用したリッチテキストの利用

RTFへのファイルの保存

 では、saveメニューを選んだ際に実行されるwriteToFileメソッドを定義しましょう。RTFへの保存は、javax.swing.text.rtfパッケージの「RTFEditorKit」クラスを利用して行います。このクラスに用意されているメソッドを使い、指定のストリームにRTFデータを出力できます。基本的な手順を整理すると、

  1. ファイルに保存するためのFileOutputStreamを作成する。
  2. RTFEditorKitのwriteメソッドを使い、FileOutputStreamに指定範囲の属性付テキストを出力する。
  3. closeでFileOutputStreamを閉じる。

 以上の操作でRTFへの出力を行うことができます。ただし、実際には、ファイルを選択するためのダイアログの利用などの処理が必要となってくるでしょう。では、メソッドを実装してみましょう。

public void writeToFile(){
    Document doc = pane.getDocument();
    RTFEditorKit rtfkit = new RTFEditorKit();
    File file = null;
    JFileChooser chooser = new JFileChooser();
    FileFilter filter = new CustomRTFFilter();
    chooser.setFileFilter(filter);
    int res = chooser.showSaveDialog(this);
    if (res == JFileChooser.APPROVE_OPTION){
        OutputStream out = null;
        try {
            file = chooser.getSelectedFile();
            out = new FileOutputStream(file);
            rtfkit.write(out,doc,0,doc.getLength());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (BadLocationException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
「save」メニューを選ぶとファイルダイアログが開き、RTFファイルで保存できる
「save」メニューを選ぶとファイルダイアログが開き、RTFファイルで保存できる

 ここでは、RTFファイルだけを表示させるのにCustomRTFFilterというフィルタ・クラスを利用しています。これについては後で作成をします。ここでは、必要なオブジェクトとして、テキストデータを管理するDocumentと、保存のためのRTFEditorKitを最初に用意しています。この部分です。

Document doc = pane.getDocument();
RTFEditorKit rtfkit = new RTFEditorKit();

 それから、JFileChooserのshowSaveDialogでファイルダイアログを呼び出し、ファイルを選択します。ダイアログの呼び出しは、こんな具合に行っています。

int res = chooser.showSaveDialog(this);
if (res == JFileChooser.APPROVE_OPTION){

 JFileChooserのshowSaveDialogを呼び出すと、ダイアログが画面に現れます。これはモーダルなので、ダイアログが閉じられるまで処理は停止されます。返された値が、JFileChooser.APPROVE_OPTIONであれば、ファイルが選択されたとみなし処理できるわけです。

 JFileChooserから保存するファイルの情報を取得し、RTFEditorKitで保存を行う処理は次のようになります。

file = chooser.getSelectedFile();
out = new FileOutputStream(file);
rtfkit.write(out,doc,0,doc.getLength());

 実は、RTFファイルへの保存の部分は、たったこれだけです。ソースコードをよく見ると、処理の大半がJFileChooser関係であることが分かるでしょう。

RFTファイルの読み込み

 続いて、RTFファイルを読み込んで表示させる処理に進みましょう。こちらも、基本的な考え方はほぼ同じです。違いは、出力ストリームではなく入力ストリームを使う、という点ぐらいでしょう。流れを整理すると、

  1. ファイルに保存するためのFileInputStreamを作成する。
  2. RTFEditorKitのreadメソッドを使い、FileInputStreamから属性付テキストを取り出す。
  3. closeでFileInputStreamを閉じる。

 このようになります。では、こちらもメソッドを実装しましょう。

public void readFromFile(){
    StyleContext style = new StyleContext();
    DefaultStyledDocument doc = new DefaultStyledDocument(style);
    RTFEditorKit rtfkit = new RTFEditorKit();
    File file = null;
    JFileChooser chooser = new JFileChooser();
    FileFilter filter = new CustomRTFFilter();
    chooser.setFileFilter(filter);
    int res = chooser.showOpenDialog(this);
    if (res == JFileChooser.APPROVE_OPTION){
        InputStream in = null;
        try {
            file = chooser.getSelectedFile();
            in = new FileInputStream(file);
            rtfkit.read(in, doc, 0);
            pane.setDocument(doc);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (BadLocationException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
「open」メニューを選ぶとファイルダイアログが開き、RTFファイルを選択し開くことができる
「open」メニューを選ぶとファイルダイアログが開き、RTFファイルを選択し開くことができる

 基本的な部分は先のwriteToFileとほとんど同じです。JFileChooserで選択したファイルからRTFデータを読み込み、JTextPaneに表示させる部分だけを見てみると、こんな具合になっています。

file = chooser.getSelectedFile();
in = new FileInputStream(file);
rtfkit.read(in, doc, 0);
pane.setDocument(doc);

 RTFEditorKitのreadで、入力ストリームから読み込み、それをDocumentに設定します。そして、このDocumentを改めてJTextPaneに設定すれば、読み込まれたRTFのテキストが表示されるというわけです。

フィルタ・クラスの作成

 最後に、RTFファイルを選択するためのフィルタクラスを用意しておきましょう。これは、JFileChooserに設定し、.rtf拡張子のファイルだけが表示されるようにするためのものです。

class CustomRTFFilter extends FileFilter {

    public boolean accept(File f) {
        if (f.isDirectory()) {
            return true;
        }
        String fname = f.getName();
        int n = fname.lastIndexOf(".");
        String ext = fname.substring(n);
        ext = ext.toLowerCase();
        if (ext != null) {
            if (ext.equals(".rtf")){
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    public String getDescription() {
        return "RTF";
    }
}

 フィルタ・クラスは、javax.swing.filechooserパッケージの「FileFilter」を継承して作ります。acceptメソッドで、引数に渡されたFileオブジェクトが表示可能かどうかをチェックしboolean値を返すようにします。ここでは、ファイル名の最後が".rtf"ならばtrue、そうでなければfalseを返すようにしてあります。これで、.rtfで終わるファイルだけが選択できるようになるわけです。JFileChooserを利用する際には覚えておきたいクラスですね。

まとめ

 今回は、JTextPaneを使って、マルチフォントのテキストを扱うための基本について説明をしました。これで、テキストの一部分のスタイルを変更したり、またマルチフォントのテキストをファイルに読み書きしたりできるようになりました。

 このJTextPaneも、表示される情報はモデル・クラスを使って管理していました。このモデル・クラスのように、画面にはまったく表示されない、コンピュータの内部だけであれこれ動いているクラスというのが、Swingではたくさんあります。Swingというと、「GUIのライブラリ」ということで、目に見える部分ばかりに注意がいきがちですが、こうした「見えないクラス」の働きの方が目に見えるコンポーネントよりも何倍も大きいのです。こうしたクラスの扱いに慣れておくのも、Swing上達のポイントと言えるでしょう。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Swing再入門連載記事一覧

もっと読む

この記事の著者

掌田 津耶乃(ショウダ ツヤノ)

三文ライター&三流プログラマ。主にビギナーに向けたプログラミング関連の執筆を中心に活動している。※現在、入門ドキュメントサイト「libro」、カード型学習サイト「CARD.tuyano.com」を公開...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1717 2007/10/10 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー