CodeZine(コードジン)

特集ページ一覧

Swing再入門 マウスで選択可能なマルチフォントテキストの描画

第5回 マルチフォントの描画と応用例

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/06/19 14:00

今回はSwing再入門の番外編として、Graphics2Dによるマルチフォントの描画について解説します。また、その応用として「マウスで選択できるテキスト」の描画や、テキストの折り返し処理などを行ってみます。

目次

はじめに

 Swingという新しいコンポーネントがJavaに導入された際、同時にグラフィック・コンテキストも刷新されました。「Graphics2D」です。現在、多くの描画用メソッドで使われているGraphicsインスタンスが実はGraphics2Dであることは、Swingをかじっていればご存知でしょう。

 今回は、このGraphics2Dのテクニックについて取り上げてみます。需要がありそうで意外と使われていない、「マルチフォント・テキストの描画」です。JavaのGraphicsによる描画では、マルチフォントによるテキスト描画が結構面倒です。結局、setFontをしながら、1つ1つのStringを描画してごまかしている人も多いのではないでしょうか。

 テキストの描画というのは、意外に奥が深いものです。きちんと行おうとするとさまざまなところで壁にぶつかります。今回は、さまざまなテキストの描画について、その方法を整理していきます。

対象読者

  • JavaでGUIを利用するアプリケーションを作成している人。
  • Graphics関係はごくざっと使ったぐらいしかない人。
  • 自前でエディタ機能を実装しようと企んでいる人。

マルチフォント描画の考え方

 まずは、「マルチフォント」のテキスト描画についてです。マルチフォントの利用は、描画そのものが大変なわけではありません。「マルチフォントのテキスト」を用意するのが大変なのです。テキストさえ用意できれば、描画はdrawStringで行えます。

 マルチフォントは、通常のテキスト値を扱うStringではなく、java.textパッケージのAttributedStringクラスを利用します。これは、文字通りアトリビュート(属性)を持ったStringを作成するためのクラスです。引数にString値を指定してインスタンスを生成し、それからマルチフォントに関する各種の属性を追加していきます。属性の追加は、次のメソッドを利用します。

[AttributedString].addAttribute(
    [TextAttribute], [Object], 開始位置, 終了位置 );
  • [TextAttribute]
  • 追加する属性の種類を示すもの
  • [Object]
  • 属性として追加するオブジェクト
  • 開始位置, 終了位置
  • その属性を適用するテキストの範囲(int値)

 AttributedStringでは、属性の種類はjava.awt.fontパッケージのTextAttributeクラスで指定します。このクラスには、あらかじめ種類を示すクラスフィールドが用意されており、これを使って指定をします。例えば、次のような形です。

  • TextAttribute.FONT
  • フォント属性(フォント名、サイズ、スタイル)を示す。Fontインスタンスで値を指定する。
  • TextAttribute.FOREGROUND/BACKGROUND
  • テキストの文字色・背景色を示す。Colorインスタンスで値を指定する。

 これで、「○文字目から○文字目まで」という形でFontColorを属性として設定していき、完成したところでdrawStringを実行すれば、マルチフォントの描画を行うことができます。

 では、実際に簡単な描画例をあげておきましょう。ここではSwingベースの簡単なアプリケーションを作成し、そこに描画用のJPanelを組み込んで簡単な描画を行ってみます。

package codezine.java;

import java.awt.*;
import java.awt.font.TextAttribute;
import java.text.*;

import javax.swing.*;

public class Sample extends JFrame {
    private static final long serialVersionUID = 1L;

    public static void main(String args[]) {
        Sample sample1 = new Sample();
        sample1.setBounds(100,100,300,150);
        sample1.setVisible(true);
    }

    public Sample() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        G2Panel gp = new G2Panel();
        this.add(gp,BorderLayout.CENTER);
    }
}

class G2Panel extends JPanel {
    private static final long serialVersionUID = 1L;

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        AttributedString as1 = new AttributedString("MultiFont Text.");
        // フォント関係のアトリビュートを追加
        as1.addAttribute(TextAttribute.FONT,new Font(
            "Dialog",Font.BOLD,36),0,5);
        as1.addAttribute(TextAttribute.FONT,new Font(
            "Dialog",Font.ITALIC,24),5,9);
        as1.addAttribute(TextAttribute.FONT,new Font(
            "Dialog",Font.PLAIN,18),10,15);
        // 表示色関係のアトリビュートを追加
        as1.addAttribute(TextAttribute.BACKGROUND,Color.RED,0,5);
        as1.addAttribute(TextAttribute.BACKGROUND,Color.GREEN,5,9);
        as1.addAttribute(TextAttribute.FOREGROUND,Color.BLACK,0,9);
        as1.addAttribute(TextAttribute.BACKGROUND,Color.BLUE,10,15);
        as1.addAttribute(TextAttribute.FOREGROUND,Color.WHITE,10,15);
        // CharacterIteratorを取得し描画
        AttributedCharacterIterator ac1 = as1.getIterator();
        g.drawString(ac1,10,50);
    }
}

 描画を行っているのは、G2Panelというクラスです。このpaintComponent内でAttributedStringを作成し、これにaddAttributeで属性を追加しています。そして完成したところで描画しています。

 ここでの描画は、次のようにAttributedStringからAttributedCharacterIteratorというインスタンスを取得し、それをdrawStringすることで行えます。

AttributedCharacterIterator ac1 = as1.getIterator();

  • LINEで送る
  • このエントリーをはてなブックマークに追加

あなたにオススメ

著者プロフィール

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

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

バックナンバー

連載:Swing再入門
All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5