プログラミングトピック 高度なイベント処理を実現するJSFコンポーネント

JClass ServerChartのグラフイメージは、アプリケーションサーバー上で作成され、クライアントブラウザで表示されます。グラフは、クライアントマシンでは単なるイメージファイルとして扱われます。そのためサーバー側では、通常グラフに対するマウス操作のイベントを受け取ることができません。

これまでのJClass ServerChartには、入力イベントを受け取るため「イメージマップ」という機能が用意されていました。イメージマップを使うと、HTMLの<map>タグにより、グラフ上のポイントにハイパーリンクを設定できます。ただし、コーディングが複雑になりがちで、動作もHTMLベースのシンプルなものでした。

バージョン5.5Jでは、Webアプリケーション用UIフレームワーク、JSF(JavaServer Faces)で使用できるグラフコンポーネントが追加されました。JSFにはユーザー入力イベントを受け取る仕組みが用意されています。JClass ServerChartのJSFコンポーネントでも、グラフ上で発生したイベントをサーバーに通知することができます。

このコンポーネントは、Java開発者にとってなじみ深いリスナーの実装でイベントを処理します。JSPファイルにタグを追加するだけで、サーバー側でイベントを受け取ることができます。また、クリックされた座標に対応するデータポイントやオブジェクトも簡単に取得できます。

今回の特集では、JSFコンポーネントの利用方法とすぐれたイベント処理機能をご紹介します。

1. JSFによるグラフイメージの作成

まずは、JSFコンポーネントを使ってグラフを表示します。

JSF上で利用できるJClass ServerChartのコンポーネントは、com.klg.jclass.schart.faces.JCFacesChartというクラスです。あらかじめ、このクラスが含まれるランタイムライブラリのjcschart.jarを、アプリケーションサーバーのクラスパスに追加しておいてください。

JSFにJCFacesChartを登録する手順は次のとおりです。

  1. JCFacesChartを含むBacking Beanの作成
  2. JSFフレームワークとBacking Beanの関連付け
  3. Webページ(JSPファイル)の作成

サンプルソースを使って詳しくご説明します。

1-a. JCFacesChartを含むBacking Beanの作成

JSFにおいて、Web画面上のJSFコントロールに受け渡すデータを管理するJava Beanを「Backing Bean」と呼びます。グラフを表示するには、Backing Bean内でJCFacesChartのインスタンスとset/getメソッドを追加します。

Backing Beanクラスのサンプル
package mypackage;

public class myBean implements Serializable{
  
  // JCFacesChartのインスタンス作成
  private JCFacesChart chart1 = new JCFacesChart();
  
  // JCFacesChartのsetメソッド
  public void setChart1(JCFacesChart chart){
    this.chart1 = chart;
  }
  
  // JCFacesChartのgetメソッド
  public JCFacesChart getChart1(){
    return(chart1);
  }
  
  (中略)
  
}

1-b. JSFフレームワークとBacking Beanの関連付け

Backing Beanを作成したら、それをJSFコントロールから参照できるよう登録を行います。通常faces-config.xmlというファイルに、JSPからBeanを参照する際の名前と対応するBacking Beanのクラス名、スコープを定義します。

XMLファイルのサンプル
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
  
<faces-config>
  
  (中略)
  
  <managed-bean>
      <managed-bean-name>chartbean</managed-bean-name>
      <managed-bean-class>mypackage.myBean</managed-bean-class>
      <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>
  
</faces-config>

1-c. Webページ(JSPファイル)の作成

最後に、作成したグラフをWebページで表示します。

JSPファイルの冒頭<jsp:root>タグで、参照するタグライブラリを指定しています。この中に、JClass JCFacesChartタグライブラリのxmlns:jclassjsfを追加しておきます。

JSPファイルの<h:form>タグの中で、<jclassjsf:chart>タグを使用してBacking BeanのJCFacesChartを呼び出し、グラフ画像を作成します。

<jclassjsf:chart>タグの属性、bindingで、関連付けられているJCFacesChartコンポーネントを、Backing Bean名およびプロパティ名で指定します。その他、グラフ画像のファイル形式やイメージマップ生成有無なども属性で切り替えられます。各属性の詳細はプログラマズガイドをご覧ください。

関連ドキュメント
《プログラマズガイド》 [14.2.4 グラフへのアクションイベントの追加]
JSPファイルのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="1.2"
  xmlns:f="http://java.sun.com/jsf/core" 
  xmlns:h="http://java.sun.com/jsf/html" 
  xmlns:jclassjsf="http://quest.com/jclass/jsf/chart-jsf"
  xmlns:jsp="http://java.sun.com/JSP/Page">
<jsp:directive.page contentType="text/html;charset=WINDOWS-31J"
pageEncoding="UTF-8"/>
<f:view>
<html lang="ja-JP" xml:lang="ja-JP">

  
  (中略)
  
<body style="-rave-layout: grid">
<h:form>
<jclassjsf:chart binding="#{chartbean.chart1}" chartName="My Chart"
encoding="PNG" id="chart1" chartXmlValue="/MyChart.xml" debug="false" 
generateImageMap="false" charsetName="utf-8"/>
</h:form>
</body>
</html>
</f:view>
</jsp:root>

これで、Webページにグラフ画像を表示できました。

出力結果

画像「出力結果」拡大

なお、上記のJSPファイルは、タグライブラリを使用したXML形式で記述されています。JSPファイルには、Javaのコードを直接埋め込むスクリプトレットで記述する方法もあり、製品付属サンプルのJSPファイルではこちらが使われています。

JClass ServerChartのJClass JCFacesChartはどちらの記述方法でも利用できます。しかし、IDEによってはXML形式を標準としているため、ここではXML形式で記述しています。

2. JCFacesChartのイベント処理

ここから次の手順でJCFacesChartのイベント処理を説明します。

  1. Backing Beanでのイベント処理実装
  2. JSPファイルへのアクションリスナーの登録

JClass ServerChartのTomcatデモに含まれる「ActionListenerのサンプル」で、マウスクリックを受け取る動作を確認できます。このサンプルのソースを使って実装方法をご紹介します。

2-a. Backing Beanでのイベント処理実装

先にBacking Bean側のソースを見てみましょう。「ActionListenerのサンプル」のBacking Beanは、ListenerBeanというクラスです。ソースコードは以下のディレクトリにあります。

/jakarta-tomcat/webapps/schart-samples/examples/schart/jsf/

ListenerBeanクラスにはselection()というメソッドが含まれています。イベントを受け取るメソッドは、selection()メソッドのようにjavax.faces.event.ActionEventを引数として設定します。

ActionEventオブジェクトからは、下記のソースコードのように、イベント呼び出し元となるJCFacesChart(JCServerChart)のインスタンスや、クリックされた座標を取得することができます。

ListenerBeanクラスのイベントメソッド(1)
package examples.schart.jsf;

public class ListenerBean implements Serializable{
  
  (中略)
  
  // イベントメソッド
  public void selection(ActionEvent ae){
  
  // JCFacesChartEventにキャスト
  JCFacesChartEvent event = (JCFacesChartEvent) ae;

  // イベント呼び出し元のJCFacesChartオブジェクト取得
  JCFacesChart chartComponent = 
        (JCFacesChart)event.getComponent();

  // JCServerChartオブジェクト取得
  JCServerChart chart = chartComponent.getChart();

  // JCFacesChartEventから、クリックされたデータやインデックス取得
  JCDataIndex dataIndex = event.getDataIndex();

  // JCFacesChartEventから、クリックされた座標取得
  Point p = event.getPickPoint();
  
  (続く)

「ActionListenerのサンプル」では、クリックイベントが発生すると、座標、コンポーネント、系列、データインデックス(x値)を表示し、選択された系列のラインスタイルを変更しています。

このようなグラフプロパティの更新を行った場合、イベントメソッドの最後でJCFacesChartEventクラスのsetChartChanged()メソッドを実行します。それによって、プロパティの更新が反映された状態で、グラフの再描画が行われます。

ListenerBeanクラスのイベントメソッド(2)
(続き)
  
  StringBuffer sb = new StringBuffer("Point: (" +
                                     p.x + "," +
                                     p.y + ") ");
  sb.append("Component: ");

  // クリックされた座標付近にあるコンポーネント取得
  Object o = dataIndex.getObject();

  // クリックされた座標付近にあるデータ系列取得
  int seriesIndex = dataIndex.getSeriesIndex();

  // クリックされたコンポーネントがグラフ内のどのオブジェクトかをチェック
  if (o == chart.getHeader()) {
   sb.append("Header");
  }
  else if (o == chart.getFooter()) {
  
  (中略)
  
  }
  
  setChartStyles(chart, seriesIndex);
  
  // イベントメソッド内で更新されたプロパティを反映するため再描画
  event.setChartChanged();
  
  pickResult = sb.toString();
  
}
関連ドキュメント
《プログラマズガイド》 [14.2.4 グラフへのアクションイベントの追加]
[14.2.4.3 JCFacesChartEvent]

2-b. JSPファイルへのアクションリスナーの登録

Backing Beanにイベントメソッドを追加したら、あとはJSPファイルにアクションリスナーを登録するだけです。「ActionListenerのサンプル」のJSPファイルはlistener.jspという名前です。Backing Beanのソースコードと同じディレクトリにあります。

/jakarta-tomcat/webapps/schart-samples/examples/schart/jsf/

アクションリスナーの追加では、<jclassjsf:chart>タグのactionListener属性にBacking Beanのイベントメソッドを値として設定します。サンプルでは、Backing Beanに追加したselection()メソッドの名前が設定されています。

アクションリスナー属性の登録(listener.jsp)
<f:view>
    <h:form>
        <f:loadBundle basename="examples.schart.jsf.resources.jsf" var="bundle"/>
(中略)
        <center>
        <table>
            <tr>
              <td><jclassjsf:chart binding="#{listener.chart1}"
                       chartName="ActionChart"
                       chartXmlValue="/examples/schart/jsf/radar.xml"
                       dataFlatValue="/examples/schart/jsf/radar.dat"
                       actionListener="#{listener.selection}"
                       debug="true" encoding="png"
                       charsetName="utf-8"/>
              </td>
            </tr>
(中略)
        </table>
        </center>
    </h:form>
</f:view>

このJSPファイルで表示されたグラフ上でマウスクリックを行うと、ListenerBeanクラスのイベントメソッドであるselection()が呼び出されます。

イベント発生前

画像「イベント発生前のサンプル」拡大

selection()メソッド内で取得されたクリック位置から、対象系列のラインスタイル(この場合赤いラインの太さ)変更が行われ、グラフイメージ下部に座標数値などのデータも追加されます。

イベント発生後

画像「イベント発生後のサンプル」拡大

なお、アクションリスナーを独立したタグとして追加することもできます。1つのグラフに複数のリスナーを登録する場合、この方法を使用してください。Backing BeanおよびJSPファイルを以下の形式で記述します。

Javaソースコード(Backing Bean)
public class myChartListener implements ActionListener {
  public void processAction(ActionEvent e) {
    JCFacesChartEvent event = (JCFacesChartEvent)e;
    ・・・・
  }
}
JSPファイル
<jclassjsf:chart ・・・ >
  <f:actionListener type="myPackage.myChartListener"/>
</jclassjsf:chart>
関連ドキュメント
《プログラマズガイド》 [14.2.4 グラフへのアクションイベントの追加]
[14.2.4.2 アクションリスナーの登録]

まとめ

JSFフレームワーク上でJCFacesChartを利用すると、Webページへのグラフの追加がより簡単になります。さらに、これまでアプレットが採用されてきたインタラクティブな画面開発も、サーバーサイドで行えます。

JSFでは、画面ロジック(JSP)とデータロジック(Backing Bean)が明確に分離するため、開発が一層シンプルになります。グラフプログラムが陥りやすいコードの冗長化を避けることができます。

また、JSFのもうひとつのメリットとして、サーバーサイドJavaでありながらIDE上で画面開発を行える点が挙げられます。JCFacesChartは、Sun Java Studio CreatorやIBM Rational Application Developerといった、JSF対応IDEをサポートしています。これらのIDEでは、イベントリスナーの登録やプロパティ設定をGUIで行えるので、高度なグラフアプリケーションを短期間で開発できます。

インタラクティブな操作を含んだグラフシステムの開発時には、JSFフレームワーク上でのJClass ServerChartの利用をお勧めします。あわせて、JSF対応IDEを利用すれば開発効率がますます高まることでしょう。