На прошлой неделе мне довелось побывать на семинаре, посвященном новому языку Java FX от Sun, на котором Константин Будник рассказал о возможностях языка, истории создания и будущих перспективах, и с изрядной долей юмора ответил на вражеские вопросы. Материалы презентации можно скачать
отсюда, в
pdf можно найти все необходимые ссылки для первоначального знакомства с
javafx.
Демонстрации, расположенные на
openjfx.dev.java.net впечатляют, однако я решил для начала написать небольшой скрипт, который был бы полезен в практике администрирования системы. Это опять все тот же
memory-метр, однако теперь на
javafx. Для начала нам нужен системный скрипт, который будет опрашивать систему о размере свободной памяти и свопа и передавать данные уже непосредственно
javafx-скрипту. Это может быть скрипт на
ksh,
perl или любом другом языке, в данном примере я буду использовать
программу на
Си -
memstat. Изменим для удобства вывод программы на следующий:
...
printf("ram:%llu:",totalsize);
printf("%llu\n",totalused);
printf("swap:%llu:", swaptotal/1024);
printf("%llu\n", swapalloc/1024 + swapresv/1024);
exit(0);
Скомпилируем и, назвав ее
fxmemstat, перенесем в каталог
/usr/local/sbin. При запуске
fxmemstat выводит две строки:
# fxmemstat
ram:4088:2944
swap:5681:1432
Теперь с помощью
JavaFXPad или
netbeans(с установленным
javafx-плагином), напишем первую
javafx-программу. Следует отметить, что на написание и тестирование у меня ушло часа четыре, из которых половину времени я пытался понять, как же конвертировать
String в
Integer, ибо стандартные методы у меня не заработали. Внятной документации пока немного, в основном информацию приходится черпать из самих исходников (в большинстве своем, опубликованных на японских блогах). В результате получилась вот такая программа (код которой наверняка можно улучшить):
import javafx.ui.*;
import javafx.ui.canvas.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.System;
import java.lang.Runtime;
import javax.swing.Timer;
import java.awt.event.ActionListener;
class ShowMem extends CompositeNode {
attribute xwidth: Number;
attribute rwidth: Number;
attribute swidth: Number;
attribute total: Integer;
attribute used: Integer;
attribute swap: Integer;
attribute sused: Integer;
attribute interval: Number;
attribute active: Boolean;
attribute myTimer: Timer;
}
attribute ShowMem.active = false;
attribute ShowMem.xwidth = 220;
attribute ShowMem.interval = 5000;
trigger on ShowMem.active[oldValue] = newValue {
var self = this;
if (newValue == true) {
self.myTimer = new Timer(bind self.interval, new ActionListener() {
operation actionPerformed(event) {
var cmd = "/usr/local/sbin/fxmemstat";
var r = Runtime.getRuntime();
var line = null;
var p = r.exec(cmd);
var buf = new BufferedReader(new InputStreamReader(p.getInputStream()));
while (true) {
line = buf.readLine();
if (line == null) { break; }
var tmp = line.split(":");
if (tmp[0]=="ram") {
self.total = new <<java.util.Scanner>>(tmp[1]).nextInt();
self.used = new <<java.util.Scanner>>(tmp[2]).nextInt();
self.rwidth=self.used/self.total*self.xwidth;
} else {
self.swap = new <<java.util.Scanner>>(tmp[1]).nextInt();
self.sused = new <<java.util.Scanner>>(tmp[2]).nextInt();
self.swidth = self.sused/self.swap*self.xwidth;
}
}
}
});
self.myTimer.start();
} else {
self.myTimer.stop();
}
}
function ShowMem.composeNode() =
Group {
content: [ Rect {
x:20
y:30
width: bind xwidth
height: 30
fill: Color {red: 0.325, green: 0.318, blue: 0.992}
}, Rect {
x:20
y:30
width: bind rwidth
height: 30
fill: LinearGradient {
x1: 0
y1: 0.5
x2: 1
y2: 0.5
spreadMethod: PAD
stops: [Stop {
offset: 0
color: black:Color
}, Stop {
offset: 1
color: Color {red: 0.996, green: 0.286, blue: 0.604}
}]
}
}, Rect {
x:20
y:100
width: bind xwidth
height: 30
fill: Color {red: 0.78, green: 0.557, blue: 0.004}
}, Rect {
x:20
y:100
width: bind swidth
height: 30
fill: LinearGradient {
x1: 0
y1: 0.5
x2: 1
y2: 0.5
spreadMethod: PAD
stops: [Stop {
offset: 0
color: Color {red: 0.008, green: 0.031, blue: 0.118}
}, Stop {
offset: 1
color: Color {red: 0.973, green: 0.988, blue: 0.027}
}]
}
}, Text {
x: 20
y: 15
content: bind "RAM Total: {total} Mb Used: {used} Mb"
} , Text {
x: 20
y: 85
content: bind "SWAP Total: {swap} Mb Used: {sused} Mb"
}]
};
Frame {
title: "Memory"
width:260
height:170
content: Canvas {
content: ShowMem { interval: 5000
active: true
}
} centerOnScreen: true
visible: true
onClose: operation() {System.exit(0);}
}
Цвета можете изменить по своему вкусу. Если все сделано правильно, то запустив скрипт, получаем вот такое окно:
Желающие могут, предварительно подготовив свой собственный системный скрипт (с таким же выводом в
Mb как и в
memstat, и не забыв назначить разрешения), попробовать запустить эту программу с помощью
Java Web Start (должно работать в том числе на
Linux и
MacOSX):