JavaFX Script被抛弃以后,很久不关心JavaFX了,偶然发现JavaFX已经发展到2.2,而且已经绑定到JDK7中,看来Oracle对它还是蛮重视的。
看到有人在论坛提问TWaver有没有JavaFX版本,于是去Oracle网站上逛了一下,发现可以将JavaFX集成进Swing程序中,真是福音啊,立马动手写了个Demo,集成起来还是很方便的。
运行效果
窗体中间是个很典型的Network,上下各是一个JavaFX容器,上面容器中包含一个Slider,滑动时可以改变TWaver选中Node的RenderColor,下面的容器中包含一些Text,选中Network中的Node并拖动的时候在Text组件上显示Node的name和location。
在这个Demo里,程序架构还是Swing,JavaFX提供了一个名为JFXPanel的组件可以嵌入到Swing容器中,JFXPanel内可以放JavaFX的组件,需要注意,Swing和JavaFX的线程不同,官方的原文是:"JavaFX data should be accessed only on the JavaFX User thread","Swing data should be changed only on the EDT",所以如果要在Swing中修改JavaFX的数据,应该使用Platform#runLater包装,本例中,拖动Node时修改JavaFX的Text组件的相关代码:
network.getDataBox().addElementPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if("location".equals(evt.getPropertyName())){
Element element= (Element) evt.getSource();
final String name=element.getName();
final double x=element.getX();
final double y=element.getY();
Platform.runLater(new Runnable() {
@Override
public void run() {
nameText.setText(name);
locationText.setText("X:"+x+" Y:"+y);
}
});
}
}
});
同样,如果要在JavaFX中修改Swing数据,也要用SwingUtilities#invokeLater包装,本例中,滑动Slider修改选中Node的Render Color代码如下:
slider.valueProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> ov,
Number old_val,final Number new_val) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Iterator it=network.getSelectionModel().selection();
while (it.hasNext()){
Element element= (Element) it.next();
element.putRenderColor(new java.awt.Color(new_val.intValue()));
}
}
});
}
});
最后附上全部代码:
public class Test1 {
static TNetwork network;
static Text nameText;
static Text locationText;
static Slider slider;
private static void initAndShowGUI() {
initNetwork();
JFrame frame = new JFrame("TWaver With JavaFX");
frame.getContentPane().setLayout(new BorderLayout());
frame.setSize(500, 300);
frame.setVisible(true);
frame.getContentPane().add(network);
final JFXPanel controlFXPanel = new JFXPanel();
frame.add(controlFXPanel,BorderLayout.NORTH);
final JFXPanel statusFXPanel = new JFXPanel();
frame.add(statusFXPanel,BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
network.getDataBox().addElementPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if("location".equals(evt.getPropertyName())){
Element element= (Element) evt.getSource();
final String name=element.getName();
final double x=element.getX();
final double y=element.getY();
Platform.runLater(new Runnable() {
@Override
public void run() {
nameText.setText(name);
locationText.setText("X:"+x+" Y:"+y);
}
});
}
}
});
Platform.runLater(new Runnable() {
@Override
public void run() {
initFX(statusFXPanel,controlFXPanel);
}
});
}
private static void initNetwork(){
network=new TNetwork();
twaver.Node node1=new Node();
node1.setName("node1");
twaver.Node node2=new Node();
node2.setLocation(200,100);
node2.setName("node2");
Link link=new Link(node1,node2);
network.getDataBox().addElement(node1);
network.getDataBox().addElement(node2);
network.getDataBox().addElement(link);
}
private static void initFX(JFXPanel statusFXPanel,JFXPanel controlFXPanel) {
Scene scene = createStatusScene();
statusFXPanel.setScene(scene);
statusFXPanel.validate();
Scene controlScene=createControlScene();
controlFXPanel.setScene(controlScene);
controlFXPanel.validate();
}
private static Scene createControlScene(){
Group root = new Group();
Scene scene = new Scene(root, Color.ALICEBLUE);
HBox hbox=new HBox();
slider =new Slider(0,16777215,0);
slider.setPrefHeight(30);
slider.setPrefWidth(300);
slider.valueProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> ov,
Number old_val, final Number new_val) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Iterator it = network.getSelectionModel().selection();
while (it.hasNext()) {
Element element = (Element) it.next();
element.putRenderColor(new java.awt.Color(new_val.intValue()));
}
}
});
}
});
Label label=new Label("颜色:");
label.setPrefHeight(30);
hbox.getChildren().add(label);
hbox.getChildren().add(slider);
root.getChildren().add(hbox);
return scene;
}
private static Scene createStatusScene() {
Group root = new Group();
Scene scene = new Scene(root, Color.ALICEBLUE);
VBox vbox=new VBox();
vbox.setPrefWidth(300);
vbox.setPrefHeight(20);
HBox hbox=new HBox();
nameText=new Text();
hbox.getChildren().add(new Label(" Name:"));
hbox.getChildren().add(nameText);
hbox.getChildren().add(new Text(" "));
locationText=new Text();
hbox.getChildren().add(new Label("Location:"));
hbox.getChildren().add(locationText);
vbox.getChildren().add(hbox);
root.getChildren().add(vbox);
return (scene);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
initAndShowGUI();
}
});
}
}