テーブルを作成する
では、準備が整ったところでテーブルの作成を行いましょう。先のmakeContentメソッドを修正し、テーブルを配置してみます。
void makeContent(Component component){ TableModel model = new MyTableModel(5,5); Table table = new Table(model); table.setDefaultRenderer(Object.class, new MyTableRenderer()); table.setDefaultHeaderRenderer(new MyHeaderRenderer()); table.setWidth(new Extent(300)); table.setBackground(Color.WHITE); table.setSelectionEnabled(true); table.setSelectionBackground(new Color(200,200,255)); table.setBorder(new Border(1,Color.LIGHTGRAY,Border.STYLE_SOLID)); component.add(table); }
ブラウザからアクセスすると、5×5のテーブル(ヘッダーを除く)が表示されます。このテーブルは単に表示するだけでなく、マウスでクリックして特定の行を選択することもできます。
Tableクラスを作成し組み込んでいる処理を見てみると、テーブルモデル、テーブルレンダラーをそれぞれ用意し、組み込んでいるのが分かります。
TableModel model = new MyTableModel(5,5); Table table = new Table(model); table.setDefaultRenderer(Object.class, new MyTableRenderer()); table.setDefaultHeaderRenderer(new MyHeaderRenderer());
Tableを作成する際、用意したモデルクラスのインスタンスを引数に渡すことで、そのモデルを使ってテーブルを作成することができます。またレンダラーは、「setDefaultRenderer」「setDefaultHeaderRenderer」メソッドで設定することができます。setDefaultRendererでは、レンダラーの他にClassが引数に渡されますが、これは列を管理するためのクラスのです。ここでは特に用意していないのでObject.classを指定しています。
サーバー側からのプッシュ配信
一般にWebはプル型技術(自分からデータを取りに行く方式)ですが、時にはサーバーからクライアントへとアクセスするプッシュ型技術が必要となる場合もあります。最近でも、例えばWebブラウザベースのGmailなどのように、プッシュ配信するWebアプリケーションも登場しつつあります。Echoでは、こうしたプッシュ型のデータ配信をサポートしています。
プッシュ配信には、「TaskQueueHandle」というクラスを使います。このインスタンスを作成し、ApplicationInstanceに用意されているメソッドを使ってスレッドを実行することで、その処理をサーバー側で実行させることができます。非常に面白いのは、スレッド終了後も、この接続が保持され続けるという点です。常時接続を維持することで、プッシュ型で情報をクライアントに配信できるようになります。では簡単なサンプルを作成してみましょう。
package jp.codezine; import nextapp.echo.app.*; import nextapp.echo.app.event.*; public class HeloApp extends ApplicationInstance implements Runnable { private static final long serialVersionUID = 1L; Label msg; WindowPane dialog; Label result; int counter = 0; TaskQueueHandle taskQueue; @Override public Window init() { Window window = makeWindow(); new Thread(this).start(); return window; } // ウインドウと基本部品作成 Window makeWindow() {……略……} // メッセージダイアログ作成 void makeWindowPane() {……略……} // ダイアログの表示 void showDialog(String s) {……略……} // その他のコンポーネント作成 void makeContent(Component component) { final Label msg = new Label("message."); component.add(msg); final ApplicationInstance app = this; if (taskQueue == null) taskQueue = app.createTaskQueue(); Button btn = new Button("Click"); btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { counter = 0; } }); component.add(btn); } // スレッド @Override public void run() { final ApplicationInstance app = this; while (true) { try { Thread.sleep(1000); counter++; } catch (InterruptedException e) { e.printStackTrace(); } app.enqueueTask(taskQueue, new Runnable() { public void run() { showDialog("Counter: " + counter); // app.removeTaskQueue(taskQueue); // ★ } }); } } }
変更のないメソッドについては省略してあります。Webブラウザからこのページにアクセスすると、画面にメッセージダイアログが現れ、そこに「Counter: ○○」というようにカウンターの数字が表示され、約1秒ごとに数字が増えていきます。「Click」をクリックすると、カウンターはゼロに戻され、再び増えていきます。ダイアログをクリックして閉じても、すぐにまたウインドが現れ、カウントが続けられます。
これが、サーバーと接続を維持していることを証明するために、カウンターが動いているのを確認してから、サーバーを停止してみましょう。カウンターの増加が止まり、しばらくすると「This application has been stopped due to an error.」というエラー画面になります。サーバーへの問い合わせが切れ、エラーになっていることが分かります。