本文向您介绍JavaFX的绑定,通过图文结合的方式和一些实例,对JavaFX SDK和如何建立JavaFX绑定等做出解释。
在进行JavaFX绑定之前,要理解,JavaFX树立在一般的Java SE运转上。为了在本文中展现这个示例,你需求为你的操作系统(在此只支撑官方的Windows 和Mac OS X)下载适宜的JavaFX SDK。详细请参阅Resources。装置installation进程只需求几个过程。在Windows的机器上,默许装置地址是C:\Program Files\JavaFX\javafx-sdk1.1. Mac OS X users should look at /Library/Frameworks/JavaFX.framework/Versions/1.1。
图1. JavaFX SDK根底目录 |
图1 显现了JavaFX SDK的根底目录。这个bin目录包括可履行编译并运转JavaFX Script程序。咱们不运用它们。JavaFX(Script)documentation在docs中。文件src.zip包括部分JavaFX运转的来历。假如你翻开它,你会留意到文件是以stg 和 .st结束的。***lib和它的子目录包括库.jars。本文的示例取决于它们中的一些。
Locations
lib/shared/javafxrt.jar包括com.sun.javafx.runtime.location包。它的类和接口来自根本的JavaFX Binding的构建块。例如,Location接口代表一个值,它或许是可变的或是不能改动的,有用或无效的,空的或对错空。这样的状况能够经过相应的getters来查询,例如,isMutable()。假如Location的值是无效的,当update()办法被调用时,或该值被检索时,它会被更新。
一个Location的类型是经过子接口来决议的;例如,IntLocation.。假如你要在src.zip中查询IntLocation.java,你不会看到它。这是由于它的来历是来自两个文件XxxLocation.st 和XxxTemplate.stg。每个子接口为类型XYZ增加getAsXYZ和and setAsXYZ()。还有DoubleLocation, FloatLocation, ShortLocation, CharLocation, LongLocation, BooleanLocation, ByteLocation和 ObjectLocation。
其他的方针或许会附归于一个Location。当值与地址改动联络在一起的时分,change listeners能够接收到告诉。***,Locations是很懒散的:尽管当值无效的时分change listeners会得到告诉,可是新的值不会被从头核算直到需求它的时分。到目前为止,我指议论了接口的问题。当然,能够为我以上所说到的类型而随时履行Locations。
public static void main(String[] args) {
final IntVariable i1 = IntVariable.make(42); i1.addChangeListener(new ChangeListener() { @Override public boolean onChange() { System.out.println("onChange(): " + i1.get()); return false; } }); System.out.println(i1.get() + ", isMutable(): " + i1.isMutable()); IntLocation i2 = IntConstant.make(24); System.out.println(i2.get() + ", isMutable(): " + i2.isMutable()); i1.set(i2.get()); } |
为了编译并运转LocationDemo1,请附加lib/shared/javafxrt.jar到你的类途径上。这个演示示例采用了IntVariable 和IntConstant类。两个都履行了IntLocation接口,因而是Locations。运用静态make()办法创立Instances。运用get()查询当时值。正如你在图2中所看到的,在初始化引发一个告诉之后,设置一个值。它经过子抽象类ChangeListener来进行处理。
图2. LocationDemo1输出 |
当地址内容现已改动的时分,它的onChange()办法被调用。该办法回来一个Boolean值,指示监听者是否依然有用。回来false将导致监听者从监听者名单上删去。Javadoc主张,当相关的弱引证被陈述铲除的时分,那些做它们自己弱引证办理的监听者应该回来false。
就像JGoodies Binding的ValueModel,还有Beans Binding的Property相同,Locations 读取和编写类型值供给了一个办法。它们也能够告诉注册的监听者关于值的改动。***,你将会在以下的末节中看到它们用于树立绑定。
树立Java绑定
像Beans Binding 和JGoodies Binding相同,JavaFX运转包括一个辅佐类来树立JavaFX绑定:com.sun.javafx.runtime.location.Bindings。它是用于在两个Locations之间树立bijective联系。这个意思是说假如一个值被更新,它所对应的也会被更新。在Locations被实例之后,它们被传递到bijectiveBind()。
public class BindingDemo1 {
private static IntLocation i1, i2; public static void main(String[] args) { i1 = IntVariable.make(); i2 = IntVariable.make(); Bindings.bijectiveBind(i2, i1); showValues(); i1.setAsInt(10); showValues(); i2.setAsInt(100); showValues(); } private static void showValues() { System.out.println("i1: " + i1.get()); System.out.println("i2: " + i2.get()); } } |
bijectiveBind(i2, i1)在i1 和 i2之间树立两种依靠联系。假如其间一个被更新,例如,调用setAsInt(),其他的值也会改动。为了抵达此意图,履行附加了两个监听者在Locations中共享状况。便利的办法makeBijectiveBind()创立一个新的Location并它绑定到现存的绑定上面。如下所示:
i1 = IntVariable.make();
i2 = Bindings.makeBijectiveBind(i1);
BindingDemo2展现了怎么运用它。它包括在/today/2009/06/02/sources.zip中。详细细节请参阅Resources。图3显现了它的输出。
图3. BindingDemo2输出 |
请留意只需可编译的类型才干运用bijectiveBind()来进行绑定。以下的代码行取自BindingDemo3.java(包括在sources.zip中的)。***眼看上去代码没什么问题。可是,它们会抛出ClassCastException反常。这儿产生什么作业了呢?
ObjectLocation loc1 = IntVariable.make();
ObjectLocation loc2 = BooleanVariable.make();
Bindings.bijectiveBind(loc1, loc2);
在创立绑定的进程中,loc2.get()成果被传递到loc1的set()办法中。这个不会为Boolean 和 Integer作业的。为了防止这种问题,只需恰当的确认参数泛型类型ObjectLocation。目前为止,咱们现已看到两个变量是怎么被同步的。以下的末节中将看一看Swing组件是怎么被绑定的。
绑定Swing组件
简直每个JavaFX Script教程都是由显现一个窗口,按钮或是标签的小程序开端的。JavaFX 运用Swing来构建并显现这些组件。因而,咱们能够假定Swing融入了JavaFX运转。不久你将会看到,这个也会运用于绑定。
lib/desktop/javafx-swing.jar文件包括javafx.ext.swing包。它的类包括了大多数常见的Swing组件。假如你查看它们,你将会留意到它们用$开端显现各区域。它们的类型是ObjectVariable,它能够履行ObjectLocation。
图4. 在Eclipse的Members视图中SwingLabel |
考虑到这个接口归于com.sun.javafx.runtime.location包,它是安全的假定这样的Locations能够绑定到其他的变量上。以下的程序展现你是怎么做到这个的。为了编译并运转这个示例,请增加lib/shared/javafxrt.jar, lib/desktop/javafx-swing.jar, lib/desktop/Scenario.jar, 以及 lib/desktop/javafxgui.jar到你的类途径上。
public class SwingDemo1 {
public static void main(String[] args) { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel p = new JPanel(new BorderLayout()); f.setContentPane(p); SwingLabel label = new SwingLabel(); ObjectLocation text = Bindings.makeBijectiveBind(label.$text); p.add(label.getJComponent(), BorderLayout.CENTER); f.pack(); f.setVisible(true); text.set("Hello, JavaFX!"); } } |
SwingLabel被实例化并分配到label。
Location被分配到test并绑定到label.的$text上。
标签被有层次的增加到组件上。
请留意你不能直接增加SwingLabel到容器中。相反。它的getJComponent()办法用来获取JComponent实例。
尽管这个简略的比如展现了一个Swing组件怎么被绑定到一个变量上的,可是却没有阐明运用JavaFX 绑定的优点。在我曾经的文章"Binding Beans,"中,我演示了怎么运用JGoodies Binding 和 Beans Binding来履行一个简略的音量操控。
VolumeControl示例
音量操控是根据一个简略的特定运用的POJO叫做Volume。它有两个区域:volume 和mute。如图5所示,它经过一个复选框和一个滑块进行操作。标签显现现在的volume值。除此之外,mute操控音量是否调整。
图5. 音量操控示例 |
触及Swing组件和POJO区域之间的联系如下:
复选框设置mute。
滑块设置volume。
Mute挑选或不挑选复选框。
Volume设置成滑块的方位。
Mute启用或禁用滑块。
Volume设置标签文本。
完好的来历包括在sources.zip中。细节请参阅Resources部分。它的结构很像我曾经的文章中的版别,所以很简略比较不同的版别。为了编译并运转VolumeControl,请增加lib/shared/javafxrt.jar, lib/desktop/javafx-swing.jar, lib/desktop/Scenario.jar, 和lib/desktop/javafxgui.jar到你的类途径。
首要,一切相关的组件都要初始化。这个产生在initComponents()中。例如,笔直坏块被创立并有如下设置:
sliderVolume = new SwingSlider();
sliderVolume.$vertical.set(true);
在initEventHandling()中树立绑定。例如,复选框与mute链接,用以下指令Bindings.bijectiveBind(checkboxMute.$selected, volume.mute); 当复选框被挑选的时分禁用滑块是经过增加一个监听者到mute上完结的。
volume.mute.addChangeListener(new ChangeListener() {
@Override public boolean onChange() { sliderVolume.$enabled.set(! volume.mute.get()); return true; } }); |
public boolean onChange() {
labelInfo.$text.set(volume.volume.get().toString()); return true; } |
总结
很惊奇的看到JavaFX绑定在Swing运用程序中的运用是如此简略。尽管绑定构架还没有为这个所规划,可是它是一个适当面子的作业。尽管如此,本文仍是成心忽视了一些问题:
Sun会答应运用并或许从头分配部分JavaFX运转给非JavaFX运用程序吗?
怎么安全运用内部类?这儿所描绘的包还没有被规划成公共的APIS。
为什么没有老练的绑定构架给Swing开发者们运用?
即便JavaFX绑定能够或是不能在产品环境中运用,可是关于它的内部研讨仍是充溢趣味和鼓动的。
【修改引荐】
- Red Hat CEO呼吁甲骨文持续坚持Java敞开
- 自学Javabean敏捷成为Java高手
- Java经过JNI调用C言语的办法
- 高手Java核心技术学习笔记
- 成为Java高手需求留意的25个学习方针
知优网 » JavaFX绑定探求(javafx 绑定)