実数値を表示する文字列Text、その背景となる矩形Rect、および単位を表示する文字列Textを、Groupで組にし、アフィン変換transformを指定して、画面上の任意の位置に配置します。
実数値に設定した書式は固定幅ではないので、Textのhalign属性にTRAILINGを指定し、文字列の末尾(文字列を囲む矩形の右上隅の点)を座標指定の基準点とします。
また、数値指示計に表示される文字は、等幅の書体の方が読みやすいので、Textのfont属性にはMonospacedのFontを生成して設定しています。
ただ数値を表示するだけでは面白くないので、数値が上限値と上上限値を超えると、表示色が緑から橙、赤と変わるようにしてみました。「上上限値」という言い方は計測制御の分野独特のもので、上限値を2段階に設け、その上の方の上限値をさします(同様に、下の方の下限値は「下下限値」と言います)。英語だとなんと言うんでしょうね。「Upper maximum」では、ちょっと意味が違うし…。
ScadaDataModelクラスにtextColor()操作を定義し、引数で渡された値によって、3種類の色オブジェクトColorを返すようにしました。この操作をTextオブジェクトのfill属性に結合し、数値にあわせてその表示色を変えています。

等幅の書体を指定したので、小数点もそれなりの幅を持って表示されます。しかし、表示を繰り返していると、なぜか数値表示の部分だけが左右に微妙にぶれてしまいます。JavaFXも、細かい点での改良の余地は、まだまだありそうですね。
いつもどおり、最後に源コードを載せておきます。
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;
operation textColor(value:Number): Color;
}
attribute ScadaDataModel.timingGenerator
= bind [1..60] dur 60000 linear continue if presenting;
function ScadaDataModel.formatNumber(value:Number): String {
return value format as <<##0.00>>;
}
operation ScadaDataModel.textColor(value:Number): Color {
var c:Color = green;
if (value > 10.0) {c = red;}
else if (value > 5.0) {c = Color {red: 1.0, green: 0.5, blue: 0.0};}
return c;
}
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: 800
height: 600
background: Color {red: 0.9, green: 0.9, blue: 0.9}
onClose: operation() {System.exit(0);}
content: BorderPanel {
center: Canvas {
content:
[Group {
transform: translate(50, 50)
content:
[Rect {
height: 18
width: 50
arcHeight: 4
arcWidth: 4
stroke: blue
fill: white
},
Text {
content: bind scadaData.formatNumber(scadaData.numericData)
font: new Font("Monospaced", "PLAIN", 14)
x: 47
y: 4
halign: TRAILING
fill: bind scadaData.textColor(scadaData.numericData)
},
Text {
content: "m3/s"
x: 54
y: 6
}]
}]
}
}
visible: true
}
0 件のコメント:
コメントを投稿