`
Ivan_Pig
  • 浏览: 387352 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

学习JavaFX脚本语言----8,9

    博客分类:
  • RIA
阅读更多
Lesson 8: Data Binding and Triggers

目录

- 绑定概述
- 绑定和对象
- 绑定和方法
- 绑定序列
- 替换触发器

-绑定的概念

bind关键字将目标变量的值和一个范围表达式联系(bound expression)起来。范围表达式可以是基本类型,一个对象,方法的返回值或者一个表达式的返回值。
下面的章节将一个个的举例。

-绑定和对象

现实中,大部分情况下,你要使用数据绑定,来同步GUI和它的数据
(GUI是 《Building GUI Applications with JavaFX》的主题; 下面我们演示的是简单的非GUI例子)

我们从简单的开始:下面的脚本中,将变量x绑定到了变量y上,改变x的值,然后打印出y的值。由于变量被绑定了,y的值会自动的更新为新值。

var x = 0;
def y = bind x;
x = 1;
println(y); // y now equals 1
x = 47;
println(y); // y now equals 47


注意,我们是用def声明的变量y。这样的话,能够阻止直接修改y的值!(y的值允许以绑定的方式修改)在下面的绑定对象的例子中,你应该以相同的方式来绑定。

var myStreet = "1 Main Street";
var myCity = "Santa Clara";
var myState = "CA";
var myZip = "95050";

def address = bind Address {
     street: myStreet;
     city: myCity;
     state: myState;
     zip: myZip;
};

println("address.street == {address.street}");
myStreet = "100 Maple Street";
println("address.street == {address.street}");


当你修改myStreet的值的时候,address对象里的street变量的值也会随之改变。

address.street == 1 Main Street
address.street == 100 Maple Street


注意,myStreet值的改变将导致一个新的Address对象被创建,并且这个对象被赋予了address变量。如果想改变值,但是不要新创建一个新的Address对象,直接在实例变量上进行绑定。

def address = bind Address {
     street: bind myStreet;
     city: bind myCity;
     state: bind myState;
     zip: bind myZip;
};


如果你已明确的对实例变量进行了绑定,那么你可以省略第一个bind(Address前面的那个bind)

def address = Address {
     street: bind myStreet;
     city: bind myCity;
     state: bind myState;
     zip: bind myZip;
};


-绑定和方法

前面已经讨论过方法了,但是你还要学习一下bound functions 和non-bound functions之间的差别。

下面的方法,它创建并返回一个Point对象:

var scale = 1.0;

bound function makePoint(xPos : Number, yPos : Number) : Point {
     Point {
          x: xPos * scale
          y: yPos * scale
     }
}

class Point { 
     var x : Number;
     var y : Number;
}


这就是所谓的bound function,因为它以bound关键字开头。

Note: bound关键字不是替代bind关键字的。在下面的例子里面,将会同时使用bound和bind.

接着,我们添加一些代码来调用这个方法并测试绑定:

var scale = 1.0;

bound function makePoint(xPos : Number, yPos : Number) : Point {
     Point {
          x: xPos * scale
          y: yPos * scale
     }
}

class Point {
     var x : Number;
     var y : Number;
}

var myX = 3.0;
var myY = 3.0;
def pt = bind makePoint(myX, myY);
println(pt.x);

myX = 10.0;
println(pt.x);

scale = 2.0;
println(pt.x);



输出:

3.0
10.0
20.0

我们来分析这段代码:

代码:

var myX = 3.0;
var myY = 3.0;
def pt = bind makePoint(myX, myY);
println(pt.x);


初始化变量myX和myY为3.0。这些值将已参数的方式传给makePoint方法。makePoint方法前面的bind关键字,将新创建的Point对象pt绑定到了makePoint方法的返回值上。(
The bind keyword, placed just before the invocation of makePoint, binds the newly created Point object (pt) to the outcome of the makePoint function.)[这里字面意思是pt绑定到了makePoint的返回值上去了,我理解的是返回值绑定到pt上去。]

下一段代码:

myX = 10.0;
println(pt.x);


修改myX的值为10.0然后打印pt.x。pt.x也将输出10.0

最后一段代码:

scale = 2.0;
println(pt.x);


修改scale的值并打印出pt.x。现在pt.x的值是20.0,如果我们将方法前面的bound关键字去掉(就变成了non-bound function),输出将会是:

3.0
10.0
10.0


这是因为non-bound functions只有在它的参数发生改变的时候才会重新执行。而scale并不是方法的参数,所以改变scale的值不会对方法产生影响。

-绑定序列

你还可以在表达式上使用bind。要解释这一点,让我们先来定义两个序列并打印他们的值。

var seq1 = [1..10];
def seq2 = bind for (item in seq1) item*2;
printSeqs();

function printSeqs() {
     println("First Sequence:");
     for (i in seq1){println(i);}
     println("Second Sequence:");
     for (i in seq2){println(i);}
}


seq1有10个项(1到10).seq2也有10个项,并且和seq1的值相等,但是我们给每项都乘以了2,所以值将是seq1的两倍。

输出:

第一个序列:
1
2
3
4
5
6
7
8
9
10
第二个序列:
2
4
6
8
10
12
14
16
18
20

只要在for关键字前面加上bind关键字,我们就能将两个序列绑定了。

def seq2 = bind for (item in seq1) item*2;


现在的问题就是“如果seq1里面发生改变了,seq2里面的所有项或部分项会有影响吗?”我们可以在seq1的末尾插入一项(值为11)来测试一下。

var seq1 = [1..10];
def seq2 = bind for (item in seq1) item*2;
insert 11 into seq1;
printSeqs();

function printSeqs() {
     println("First Sequence:");
     for (i in seq1){println(i);}
     println("Second Sequence:");
     for (i in seq2){println(i);}
}




输出:

第一列:
1
2
3
4
5
6
7
8
9
10
11
第二列:
2
4
6
8
10
12
14
16
18
20
22

输出显示了在seq1中插入11后,对seq2里的前面10项并没有产生影响,而是自动的加到了seq2的后面,并且值是22.

-替换触发器(replace trigger)

替换触发器是一段特殊的代码,它和变量关联,并且只要变量的值发生改变就会执行。下面的例子展示了基本的语法:定义了一个password变量并和一个替换触发器关联,当password改变的时候,触发器打印出password的新值。

var password = "foo" on replace oldValue {
     println("\nALERT! Password has changed!");
     println("Old Value: {oldValue}");
     println("New Value: {password}");
};

password = "bar";



输出:

ALERT! Password has changed!
Old Value:
New Value: foo

ALERT! Password has changed!
Old Value: foo
New Value: bar


这里触发器被触发了两次:第一次,当password被初始化为"foo"的时候,以及第二次当值变成"bar"时。
注意,oldValue变量持有触发器执行前变量的值。你能够任意命名此变量,我们使用oldValue只是因为它比较直观。


Lesson 9: Writing Your Own Classes

目录

- 例子:Customer
- 从其他类继承

-例子:Customer

在Writing Scripts章节,你学会了如何使用对象。但是,当时我们是让你去下载了.class文件,以使编译器知道怎么去创建Address和Customer对象。在下面的例子里面,我们重新来看代码,新增缺少的类定义,以保证所有的代码都能通过编译。

def customer = Customer {
     firstName: "John";
     lastName: "Doe";
     phoneNum: "(408) 555-1212"
     address: Address {
          street: "1 Main Street";
          city: "Santa Clara";
          state: "CA";
          zip: "95050";
     }
}

customer.printName();
customer.printPhoneNum();
customer.printAddress();

class Address {
     var street: String;
     var city: String;
     var state: String;
     var zip: String;
}

class Customer {
     var firstName: String;
     var lastName: String;
     var phoneNum: String;
     var address: Address;

    function printName() {
        println("Name: {firstName} {lastName}");
    }

    function printPhoneNum(){
        println("Phone: {phoneNum}");
    }

    function printAddress(){
        println("Street: {address.street}");
        println("City: {address.city}");
        println("State: {address.state}");
        println("Zip: {address.zip}");
    }
}


如果你已经掌握了变量和方法,那么这段代码你应该很容易理解。Address类声明了street, city, state, and zip实例变量,且都是String类型。Customer也声明了一些实例变量还有一些方法来打印他们的值。因为这些变量和方法都是在类里面声明的,所以在你创建的任意的Address和Customer类的实例都能够访问到他们。

-从其他类继承

你还能创建一个类,并从其他类里面继承变量和方法。例如,假设在银行里面保存,验证一个帐户。每个帐户都有帐户号码和金额。你能查询金额,存款或取款。我们能对此建模,抽象出一个基本的帐户类并且给与通用的变量和方法:

abstract class Account {

     var accountNum: Integer;
     var balance: Number;

     function getBalance(): Number {
          return balance;
     }

     function deposit(amount: Number): Void {
          balance += amount;
     }

     function withdraw(amount: Number): Void {
          balance -= amount;
     }
}


我们将此类标记为抽象的,这样的话,Account对象是不能够直接被创建出来的(继承的类只需要savings accounts or checking accounts)

accountNum和balance 变量持有帐户号码和当前的帐户金额。 而余下的那些方法则提供了基本的取钱,存钱和查询金额的功能。 T

我们能定义一个SavingsAccount,并使用extends关键字来继承得到这些变量和方法。

class SavingsAccount extends Account {

     var minBalance = 100.00;
     var penalty = 5.00;

     function checkMinBalance() : Void {
          if(balance < minBalance){
               balance -= penalty;
          }
     }
}


因为SavingsAccount是Account的子类,所以它将自动的包含Account里面所有的实例变量和方法。这可以使我们专注于SavingsAccount所特有的属性和方法(比如,如果帐户金额小于100,则无法取款)

类似的,我们再定义一个CheckingAccount类继承Account

class CheckingAccount extends Account {

     var hasOverDraftProtection: Boolean;

     override function withdraw(amount: Number) : Void {
          if(balance-amount<0 and hasOverDraftProtection){

               // code to borrow money from an overdraft account would go here

          } else {
               balance -= amount; // may result in negative account balance!
          }
     }
}


这里定义了一个变量,来判断帐户持有者能否透支。(如果取款的时,取款金额超过了帐户现有金额,那么透支功能将起作用,判断此用户是否能透支)注意,在这里我们修改了继承的withdraw方法,这就是方法的覆盖,所以方法前面需要加上override关键字
4
1
分享到:
评论
5 楼 lrh_b2b 2009-03-08  
请问javafx的类能否继承与java的类,并且能够调用其方法。楼主能给个例子吗?
4 楼 liyaxi 2009-02-15  
rubyeye 写道

支持LZ 问一下,在一些javaFx的例子里我看到有的引用了 javafx.ui 这个包里的类,如: javafx.ui.Frame. 但是在javafx sdk 的API里面却找不到这个包,是怎么回事?


我估计是javafx 升级了! 我也遇到同样的问题! 在sun 的官方网站上  变成了
var  stage = Stage {
    title: "Interesting Photos"
    resizable: false
   width: 240
    height: 320
    visible: false
    style: StageStyle.TRANSPARENT
    scene: bind scene
}
让我们共同期待有大师们出本关于javaFx 的书籍!
3 楼 Ivan_Pig 2008-12-11  
rubyeye 写道

支持LZ
问一下,在一些javaFx的例子里我看到有的引用了 javafx.ui 这个包里的类,如:
javafx.ui.Frame. 但是在javafx sdk 的API里面却找不到这个包,是怎么回事?

你看的可能是老例子,正式版之前有两个PDF的文档,关于JavaFX,也是分为Script和GUI的。其中关于GUI的PDF,里面都是用的ui。
我之前的版本看过,但是没仔细研究,毕竟不是正式版。据说以前是基于widget(忘怎么拼了,好像是这样)的。现在正式版是基于Node的。
所以之前PDF上面的程序,到正式版上面基本都运行不了了
2 楼 cherryQQ 2008-12-11  
第一次看到javaFX 感觉很强,lz辛苦
1 楼 rubyeye 2008-12-11  
支持LZ
问一下,在一些javaFx的例子里我看到有的引用了 javafx.ui 这个包里的类,如:
javafx.ui.Frame. 但是在javafx sdk 的API里面却找不到这个包,是怎么回事?

相关推荐

    学习JavaFX脚本语言--中文PDF版

    这个压缩包文件“学习JavaFX脚本语言_翻译_.pdf”显然是一个关于JavaFX编程的中文教程,对于想要深入理解JavaFX的人来说,这是一个宝贵的资源。 JavaFX最初是Sun Microsystems开发的,后来被Oracle收购并继续发展。...

    学习JavaFX脚本语言

    学习JavaFX脚本语言,你需要掌握如何声明和操作对象,以及如何利用它的图形和动画功能创建动态用户界面。随着对JavaFX深入的理解,你可以创建出交互性强、视觉效果丰富的应用程序。而要更进一步,还可以学习如何编写...

    javafx-sdk-17.0.2-lts-windows-x64

    3. **bin**: 这个目录通常包含可执行文件和脚本,如JavaFX的编译器`javac`和链接器`javafxpackager`。这些工具允许开发者编译和打包JavaFX应用程序,使其可以在不同平台上运行。 4. **src**: 可能包含了示例代码或...

    深入学习javaFx脚本语言

    深入学习JavaFX脚本语言,意味着我们将探讨其语法、特性以及如何利用它来构建动态的应用程序。 JavaFX最初引入了一种名为JavaFX Script的专用脚本语言,但后来在JavaFX 2.0中,JavaFX Script被Java API所取代,使得...

    学习JavaFX1.2脚本语言

    JavaFX是Oracle公司推出的一种用于创建富互联网应用程序(RIA)的平台,它允许开发者使用JavaFX脚本语言或Java编程语言来构建具有丰富图形界面的应用程序。JavaFX 1.2是该技术的一个早期版本,提供了许多创新特性,...

    JavaFX Script 脚本编程语言

    knowledge point 9: JavaFX Script 编程语言的未来发展 JavaFX Script 编程语言的未来发展方向包括了多媒体技术、人工智能、云计算等领域。 knowledge point 10: JavaFX Script 编程语言的相关技术 JavaFX Script...

    javafx脚本语言中文学习文档

    javafx语言中文教程,内附代码,有助于学习理解!

    javafx使用指南-目录版.pdf

    1. JavaFX Script:JavaFX 的脚本语言,用于开发 JavaFX 应用程序。 2. JavaFX API:JavaFX 的应用程序编程接口,用于开发 JavaFX 应用程序。 3. JavaFX Graphics:JavaFX 的图形编程接口,用于开发 JavaFX 应用程序...

    javafx入门教程

    本教程将指导您从基础知识开始学习JavaFX脚本语言。 JavaFX概述 JavaFX是一种新的脚本语言,由Sun Microsystems开发,用于开发RIA。JavaFX脚本语言基于Java平台,可以在Java虚拟机(JVM)上运行。JavaFX的主要特点...

    Learning the JavaFX Script Programming Language.pdf

    《深入学习JavaFX脚本编程语言》:现代GUI应用程序开发的高效工具 一、JavaFX脚本编程语言概述 JavaFX脚本编程语言是专为创建具有现代化图形用户界面(GUI)的应用程序而设计的一种高级编程语言。它以其声明式的...

    Javafx Script - Dynamic Java Scripting For Rich Internet-Client-Side Applications (Apress, 2007).pdf

    JavaFX Script是一种基于Java的脚本语言,它结合了Java的强大特性和动态脚本语言的灵活性。JavaFX Script最初由Sun Microsystems于2007年的JavaOne大会上发布,并被视为构建丰富内容应用程序的关键工具之一。它提供...

    JavaFX2.0基础教程.pdf

    Oracle宣布停止对JavaFX脚本语言的支持,并将JavaFX的部分API集成到Java标准库中,使得JavaFX成为开发跨平台富客户端应用的理想选择。 - **JavaFX2.0新特性**: - **API整合**:将原有的JavaFX脚本API集成到了Java...

    JavaFX-Resizable-Draggable-Node

    9. **学习资源**: - Oracle的JavaFX官方文档提供了详细的API参考和教程。 - Stack Overflow和GitHub上的JavaFX社区是获取帮助和示例代码的好地方。 通过理解和应用这些概念,开发者可以创建出具有高度交互性的...

    JavaFX-Script语言教程.doc

    JavaFX Script是Oracle公司推出的一种用于创建富互联网应用程序(RIA)的脚本语言,它专门设计用来构建桌面和Web上的图形用户界面。虽然JavaFX Script的流行度在JavaFX后来转向Java语言API后逐渐降低,但它依然为...

    JavaFX Script - Dynamic Java Scripting for Rich Internet-Client-Side Applications

    为了满足这些需求,Sun Microsystems 推出了 JavaFX Script,这是一种专为创建丰富的互联网客户端应用程序而设计的动态脚本语言。本文将基于提供的文档信息对 JavaFX Script 的核心概念、优势以及应用场景进行深入...

    JavaFX Script 语言教程(面向Swing 程序员).rar

    对于Swing程序员来说,学习JavaFX Script 可以拓宽他们的技能范围,为他们提供更现代的UI开发工具。Swing虽然功能强大,但在视觉效果和交互性上可能略显传统,而JavaFX Script 则提供了更先进的解决方案。 这个...

    javaFx script

    学习JavaFX Script的最佳起点是官方提供的教程,该教程详细介绍了JavaFX Script的核心概念和语言语法。通过这个教程,开发者可以逐步掌握JavaFX Script的基础知识,并进一步了解如何构建图形用户界面(GUI)应用程序...

    JavaFX高级教程:JavaFX2.0的FXML语言(中文版)

    10. **使用脚本语言**:如果需要,可以通过绑定和表达式在FXML中使用Java脚本来增强功能。 11. **使用样式表**:应用CSS样式表,以实现自定义的视觉效果和主题。 通过以上步骤,我们将能够完全理解如何使用FXML来...

    javaFX 入门教程

    1. **高生产力的脚本语言**:JavaFX脚本语言设计得易于学习且表达能力强,支持声明式的编程风格,使得开发者可以专注于应用程序逻辑而非底层实现细节。 2. **静态类型**:虽然JavaFX脚本语言采用了类似脚本语言的...

    JavaFX2.0基础教程(整合版)

    - **Oracle 接手**:Oracle 收购 Sun 后,在 2010 年 JavaOne 大会上宣布将停止对 JavaFX 脚本语言的支持,并将 JavaFX 的 API 导入 Java,这意味着 Java 开发者无需学习新的脚本语言即可利用 JavaFX 的功能。...

Global site tag (gtag.js) - Google Analytics