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
}

0 件のコメント: