はじめに
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]
- 開始位置, 終了位置
AttributedString
では、属性の種類はjava.awt.fontパッケージのTextAttribute
クラスで指定します。このクラスには、あらかじめ種類を示すクラスフィールドが用意されており、これを使って指定をします。例えば、次のような形です。
- TextAttribute.FONT
- TextAttribute.FOREGROUND/BACKGROUND
Font
インスタンスで値を指定する。Color
インスタンスで値を指定する。 これで、「○文字目から○文字目まで」という形でFont
やColor
を属性として設定していき、完成したところで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();