前回、前々回とシェイプの紹介を行ってきました。今回はシェイプと同じような描画機能を持つキャンバスについて取り上げます。

 シェイプでは丸や四角をノードのサブクラスとして表すのに対し、キャンバスは丸や四角の描画を手続き的に記述していくという違いがあります。いうなれば、Java 2D的な描画ということができます。

 シェイプでは描画要素がオブジェクトに分かれており、個々のシェイプに対してエフェクトなどを施すことも可能です。また、マウスクリックのようなイベントも扱うことができます。その反面、シェイプの数が増えてくると、パフォーマンスも落ちてしまいます。

 これに対し、キャンバスは個々の描画要素を単体で扱うことはできません。このため、描画要素ごとにエフェクトを施すこともできませんし、イベントを扱うのも大変です。また、手続き的に書かなくてはいけないため、FXMLでは記述できないという欠点もあります。

 しかし、描画のパフォーマンスはシェイプに比べるとかなり高く、また描画要素が多くなったとしてもパフォーマンスの劣化はわずかです。

 このような性質の違いから、シェイプとキャンバスを使い分けるようにします。

キャンバスの基本的な使用法

 キャンバスはJava 2D的だということを前述しましたが、使い方もJava 2Dに影響を受けています。逆にいうと、Java 2Dを使用したことがある人であれば、キャンバスはすぐに使えるはずです。

 ここではシェイプと比較できるように、前々回のシェイプのサンプルと同じ描画を行ってみましょう。また、シェイプでは扱えないイメージもキャンバスでは扱うことができるので、それも付け加えました。

サンプルのプロジェクト (こちらからダウンロードできます)
CanvasDemo.zip

キャンバスの生成

 キャンバスはjavafx.scene.canvas.Canvasクラスで表します。もちろん、CanvasクラスもNodeクラスのサブクラスなので、シーングラフに追加することができます。

リスト1●Canvasオブジェクトの生成
    private void drawCanvas(StackPane parent) {
        // キャンバスを生成
        Canvas canvas = new Canvas(WIDTH, HEIGHT);
        parent.getChildren().add(canvas);
        
        // グラフィックスコンテキストを取得
        // 描画はグラフィックスコンテキストに対して行う
        GraphicsContext gc = canvas.getGraphicsContext2D();

 Canvasオブジェクトの生成には幅と高さを指定します。ここでは、定数でシーンと同じ幅、高さを指定しています(赤字部分)。

 Canvasオブジェクトは絵を描くキャンバスでしかなく、キャンバスに絵を描くための筆の役割をするのがjavafx.scene.canvas.GraphicsContextクラスです。

 GraphicsContextオブジェクトは青字で示したように、CanvasクラスのgetGraphicsContext2Dメソッドで取得します。

 このGraphicsContextクラスが丸や四角などを描画するメソッドを定義しています。つまり、Java 2DのGraphics2Dクラスに対応したクラスということができます。