2007年12月19日水曜日

JavaFX SCADA UI:UIプログラムで数値を表示する

Javaで記述した模擬依頼者プログラムから、UIプログラムへSCADA情報(実数値)を渡す準備ができました。そこで、JavaFXでUIプログラムを記述して、それを枠付き窓に数値表示させることにします。
数値は、
JavaFXの書式設定演算子formatを利用して、小数点以下第2位までの表示とします。書式として、「##0.00」形式を指定しました。丸め方法も指定できると良かったのですが、現状のJavaFXではそこまで記述できません
Javaでは数値の書式として、「%m.nf」形式で全体の桁数と小数点以下の桁数を指定することができます。JavaFXでもこの書式を使えないわけではありません。UIの窓に数値指示計として表示するには、こちらの方が都合はいいです。
しかし、現状では「%m.nf」形式の使用にいろいろと制限がついてしまいます。私のプログラムでは、置換引金の処理で、Javaプログラムから数値を読み込んでいます。「%m.nf」形式を有効にするためには、この区画の中でJavaクラスの実体を生成し、その参照変数を介して実体手続きを呼び出すようにするか、実体を生成したくない場合は、クラス手続きを呼び出すようにしなければなりません。そうしないと、「illegal format specifier %8.2f」のような誤りになってしまいます。
更に、そうして
「%m.nf」形式で書式を設定しても、それを割り当てる図形要素によって、書式が有効になるものとならないものがあります。Label要素では有効ですが、Text要素では無効で、頭の空白文字は無視されてしまいます。
今回の例では、書式指定が利用できることを示すために、Label要素を使用していますので、「%m.nf」形式を指定しても問題はありません。しかし、後で、文字列を図形や画像と組み合わせて表示できるよう、Text要素を使うつもりですので、「%m.nf」形式は使用しませんでした。
前説が長くなりましたが、プログラムの作成に話を進めます。12月18日の投稿で作成した「Javaアプリケーションプロジェクト」内に、UIプログラム用のJavaFXファイルを作成します。以前に紹介した目覚まし時計のプログラムでは、JavaとJavaFXの企画(Project)を分けました。今回は、
同じJava企画にJavaFXプログラムも記述します。その方が、構築作業が楽になります。
私は、「ScadaClientUI」という名前でJavaFXファイルを作成しました。ファイルを作成したら、企画名をマウスで右押しし、表示される状況目録から、「プロパティー」を選択します。表示された窓の「カテゴリ」から「実行」を選択し、右側に表示された「引数」文字列枠に、作成したJavaFXのファイル名を包み名付きで設定します。私は、包み名を「client」としましたので、「client.ScadaClientUI」と設定しました。
ページの最後にコードを載せておきます。なお、目覚まし時計と同様に、編集用具上では「import client.ScadaClient;」の「
ScadaClient」の部分に、誤りを示す赤い波線が表示されますが、無視します。
企画を構築して実行すると、次のように、出力窓と枠付き窓に書式化された数値が、1秒ごとに表示されます(ときどき、表示の更新が欠落することがありますが、そこはご愛嬌ということで)。




package client;

import javafx.ui.*;
import javafx.ui.canvas.*;
import java.lang.System;
import client.ScadaClient;

class ScadaDataModel {
attribute presenting: Boolean;
attribute timingGenerator: Number;
attribute numericData: Number;
attribute sc: ScadaClient;
function formatNumber(value:Number): String;
}

attribute ScadaDataModel.timingGenerator
= bind [1..60] dur 60000 linear continue if presenting;

function ScadaDataModel.formatNumber(value:Number): String {
return value format as <<##0.00>>;
}

trigger on new ScadaDataModel {
sc = new ScadaClient();
}

trigger on ScadaDataModel.timingGenerator = value {
numericData = sc.receiveData();
System.out.println("受信生データ: {numericData}");
System.out.println("書式化データ: {formatNumber(numericData)}");
}

Frame {
var scadaData = ScadaDataModel {presenting: true}
title: "JavaFX SCADA UI"
centerOnScreen: true
width: 400
height: 200
onClose: operation() {System.exit(0);}
content: Label {
text: bind scadaData.formatNumber(scadaData.numericData)
}
visible: true
}

2007年12月18日火曜日

JavaFX SCADA UI:模擬依頼者を作る

これから、JavaFXでSCADAのUIプログラムを構築していきます。最初に、UIプログラムにSCADA情報を提供する依頼者の処理を模擬するプログラムを、Javaで作ります。
依頼者からUIプログラムへは倍精度浮動小数点数の模擬情報を渡し、UIプログラムで数値指示計や図式指示計などにその値を数値や図式として表示させます。値は何でも良いのですが、とりあえず正弦関数の絶対値を100倍して渡すことにしました。依頼者の手続きが呼び出されるたびに、正弦関数の角度を1度ずつ増やして計算します。
まず、NetBeansで「Javaアプリケーションプロジェクト」(名前は任意)を作成します。同様に任意の「パッケージ
」と「クラス名」を指定して、Javaクラスを作成します。私は、パッケージ名に「client」、クラス名に「ScadaClient」を指定しました。
Javaクラスには実体手続きを定義し、上記の値を計算して戻り値として返すようにしました。また、主手続きで、作成した実体手続きの動作確認を行っています。
私が作成したコードを、最後に載せておきます(例によって、字下げが消えてるため、読みづらくてすみません)。
Javaアプリケーションプロジェクトを構築・実行すると、0~4度までの5つの正弦関数値が、出力窓に表示されます。

package client;

public class ScadaClient {

// 模擬SCADAデータ生成用作業変数。
private int i = -1;

public double receiveData() {
// 模擬SCADAデータを生成して返す。
i += 1;
if (i >= 360) {
i = 0;
}
return (double)(Math.abs(Math.sin(i * Math.PI / 180.0) * 100));
}

public static void main(String[] args) {
ScadaClient sc = new ScadaClient();
for (int i = 0; i <>

2007年12月17日月曜日

JavaFX SCADA UI:はじめに

前に、目覚まし時計を作りましたので、次は、SCADAのUIをJavaFXで作ってみたいと思います。
そもそも、JavaFXを含め、RIAの調査を始めたきっかけが、
SCADAのUIをAppletよりも簡単かつ表現力豊かに構築する方法はないかということでしたので、ようやく本題に突入と言ったところでしょうか。
SCADAとは、「Supervisory Control And Data Acquisition」の頭文字をとったもので、日本では「遠隔監視制御システム」などと呼ばれています。その名のとおり、諸所に分散した施設の設備や機器の運転情報を収集して処理するとともに、運転制御をも行う機構です
(監視だけを行うものもあります)
関連する技術分野が多方面に及ぶ(分散処理、画像処理、データベース、AI、電子郵便、携帯端末、RAS、などなど、数え上げると切りがない)ため、プログラミングの題材としては、なかなか面白いものです。
機構全体としては、かなり膨大なものになりうるのですが、ここではその内のUI部分を(それも、かなり単純化して)構築することにします。したがって、SCADA役務の依頼者と提供者間の通信の実現方法については考慮しません。何らかの方法で依頼者は
SCADA役務の提供を受けることができる、という前提で作成します。
例によって、開発環境としてNetBeansを使います。「それでは、…」と言いたいところですが、今日は前置きで終わりです。

2007年12月16日日曜日

JavaFX安定版の公開時期

JavaFX共同体討論場に載せられていた投稿によると、JavaFXのある程度の安定版公開時期は、来年のJavaOneのころになるようです。
今は、その黎明期の姿を垣間見ることができる、貴重なときなのかもしれません。

2007年12月13日木曜日

SunもJavaFX用GUI構築用具を開発中

ベルギーで開催されたJavaPolis 2007(ヨーロッパ版のJavaOne)において、SunのJames Gosling氏が基調講演を行い、SunがJavaFX用のGUI構築用具の原型版を開発中であることを披露されました。
JavaFXにおけるGUIプログラミングは、Javaにおけるそれよりはるかに容易になったとはいえ、やはりGUIはWYSIWYGで設計したいものです。NetBeansのMatisseようなGUI構築用具を一度使うと、正直、WYSIWYGで編集できないのはつらいものがあります。
JavaFX用のGUI
構築用具としては、ご存知のように、JFXBuilderというお試し用具もあるようですが、Sunのものはどのような機能を提供してくれるのか、今から楽しみです。

2007年12月11日火曜日

JavaFXファイルでJavaクラスを輸入するときはご注意を

現状の逐次解釈(Interpreter)版のJavaFXプログラムで、Javaのクラスを輸入(import)して使うときは、ちょっと注意が必要です。
少なくとも現状の逐次解釈版のJavaFX(一括変換(Compiler)版では調べていません)プログラムでは、java.lang.Systemクラスなどを輸入して使う場合、包み(Package)全体の輸入宣言「import java.lang.*;」で済ますと、思わぬ誤動作をすることがありますので注意が必要です。
私が経験した事例では、
java.lang包みの輸入宣言を行っているプログラムで、クラスに数値(Number)型の属性を定義し、その属性に実数を格納したときに、その整数部分しか格納されないというものでした(同じプログラム内で、クラス属性ではなく、数値型としてvar宣言した変数には実数として格納されるので、ややこしい)。
いろいろ調べた結果、包み全体ではなく、
java.lang.Systemクラスを明示的に宣言することで、この不具合が解消されることが分かりました。
もともと、Javaのプログラムでも、包み全体ではなく、なるべく個々のクラスごとに輸入宣言を記述する方が良いとはされていますが、包み全体の輸入を宣言してもプログラムが
動作をすることはありません。ですから、包みの宣言でも正常に動作するのが、本来の姿だとは思いますが。

2007年12月8日土曜日

JavaFX言語の展開:置換引金の定義場所と構文の変更

これまで、クラス属性の置換引金はクラス本体の外で定義していましたが、これからは、クラス属性の宣言の一部として記述するようになります。そして、置換引金の構文も、鍵語が「trigger on」から「on replace」へと、置換処理の定義であることを明示したものに変わります。
(旧)
class Foo {
attribute bar: Boolean = true;
}
trigger on Foo.bar = value {
if (bar == true) {
beep();
}
}
(新)
class Foo {
attribute bar: Boolean = true on replace {
if (bar == true) {
beep();
}
};
}