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

JavaFX学习笔记

    博客分类:
  • RIA
阅读更多
1.JavaFX是一种静态输入的语言
   与javascript不同,JavaFX是静态输入的。
   如果你声明了一个变量如下。
  
var a="Hello";

   如果你继续下面的操作将会报错。
  
a=123;

   因为a初始为String,所以不能给它赋值数值类型。

2.JavaFX是声明式脚本编制语言
   脚本编制引擎在执行之前读取完整的程序,然后允许解释器采取必要的步骤正确运行程序。更准确地讲,脚本编制引擎所需的工作就是在执行开始之前进行声明,然后引擎决定如何使用所有给定声明,以完成既定目标。

3.JavaFX中字符串的连接
   与java不同,javaFX不支持+连接字符串。连接方法如下。
  
var a="Hello";
   var b="{a} World";


4.JavaFX数据类型
   JavaFX编程语言只提供了四种原语类型: String、 Boolean、 Number和 Integer。可以对每种类型调用现有Java方法。

5.JavaFX基础操作符
    ?  任意值(例如,可为null)
    +  一个或多个
    *  零个或多个

5.JavaFX变量声明格式
   
var variableName [: typeName] [? | + | *] [= initializer];

   例如:
   var nums:Number* = [5, 9, 13];
   声明了一个名为nums的新变量,其值被定义为由零个或多个 Number类型的实例组成,并且其初始值为3个数字:5、9和13。
    声明部分中的 typeName、基数操作符和初始化程序部分是可选的,因此以下内容与前面的示例是等价的:

  
var nums = [5, 9, 13];


6.JavaFX中的字符串
   javaFX中的字符串可以用双引号,也可以用单引号。
  
var a='Hello';
   var b="Hello";

   是等价的。

   区别是,双引号里的字符串可以包含换行。。。
 
var a="Hello
        World";


7.javaFX中的数组
   数组表示对象 序列。在JavaFX中,数组本身不是对象。此外,生成嵌套序列的表达式会被自动扁平化。
  
var weekdays = ["Mon","Tue","Wed","Thur","Fri"];
   var days = [weekdays, ["Sat","Sun"]];
   days == ["Mon","Tue","Wed","Thur","Fri","Sat","Sun"];
     // returns true


如果执行 System.out.println(days),将只能看到数组的第一个元素。可以使用数组索引获得数组中的其他元素。同样,如果您指定的是一个不存在的索引,则无法像在Java中那样获得 ArrayIndexOutOfBoundsException,而仅会得到一个0值。

数组的当前大小可以使用 sizeof操作符确定:

var n = sizeof days;     // n = 7


对于数组成员组成数列的数组,JavaFX使用一种由两个句号( ..)组成的简写符号表示。例如,以下代码将创建一个包含100个元素的数组:

var oneToAHundred = [1..100];
var arraySize = sizeof oneToAHundred;   // size == 100


 

在处理数组时,JavaFX技术还支持 insert和 delete语句。下面的示例演示了如何向数组 插入值。

var x = [1,2,3];
insert 12 into x;                 // yields [1,2,3,12]
insert 10 as first into x;        // yields [10,1,2,3,12]
insert [99,100] as last into x;   // yields [10,1,2,3,12,99,100]


 

除了使用 into外,还可以使用 before和 after关键字,如下所示:

var x = [1,2,3];
insert 10 after x[. == 3];        // yields [1,2,3,10]
insert 12 before x[1];            // yields [1,12,2,3,10]
insert 13 after x[. == 2];        // yields [1, 12, 2, 13, 3, 10];


 

方括号里面的某些表达式看上去有些古怪,不必多虑。这实际上是 Xquery-UpdateXquery-Update(类似于XPath) 谓词.这种情形下,方括号中的句号并不是指索引,而是指索引 值。JavaFX技术将检验数组中的每个元素,直到表达式为真,然后使用 insert。例如,最后一条语句将遍历数组的每个值,在找到数组值等于2的元素(即数组的第三个元素)后,在其后插入数值13。此时,代码停止。

deletedelete语句的工作原理大致相同。注意,如果省略了方括号内的表达式,整个数组将被清除。

var x = [1,2,3];
insert 10 into x;          // yields [1,2,3,10]
insert 12 before x[1];     // yields [1,12,2,3,10]
delete x[. == 12];         // yields [1,2,3,10]
delete x[. >= 3];          // yields [1,2]
insert 5 after x[. == 1];  // yields [1,5,2];
insert 13 as first into x; // yields [13, 1, 5, 2];
delete x;                  // clears the array and yields []


 

最后,使用 select和 for each操作符可以对数组执行更加复杂的查询。这种操作也被称为列表推导。下面是一个使用 select的简单示例:

var a:Integer* = select n*n from n in [1..10];
    //  yields [1,4,9,16,25,36,49,64,81,100]


 

以上代码表达的意思是“循环遍历 [1..10]数组中的每个值,将它赋予本地变量n。对于每个 n,创建一个新元素 n squared并将其添加到 Integers a数组中。”

还可以使用以下代码添加一个过滤器:

var a:Integer* = select n*n from n in [1..10] where (n%2 == 0);
    //  yields [4,16,36,64,100]


 

这将定义修改为:“循环遍历 [1..10]数组中的每个值, 如果数组值除以 2余数为0(即偶数),将它赋予本地变量 n。然后对于每个产生的 n,创建一个新元素 n squared并将其添加到 Integers a数组中。”

最后,还可以向选择语句添加多个列表:

var a:Integer* = select n*m from n in [1..4], m in [100,200] where (n%2 == 0);
    //  yields [200, 400, 400, 800]


 

这实际上是一个嵌套循环,在形式上创建了一个 笛卡尔乘积。首先获得第一个有效的 n值,即2,然后乘以第一个有效的 m值100。然后再用2乘以下一个有效的 m值200。接着使用下一个有效的 n值(即4)重新迭代有效值 m的列表(100和200),生成的结果为400和800。此时,选择语句结束,您得到了最终的数组,放置在数组 a中。

使用 foreach操作符可以表示相同的内容:

var a:Integer* =
    foreach(n in [1..4], m in [100,200] where (n%2 == 0) )
            n*m;      // also yields [200, 400, 400, 800]


数组讲挺多,直接copy了。。。。

8.JavaFX中的格式化
   format as操作符支持若干格式化指令。
  
import java.util.Date;

     100.896 format as <<%f>>; // yields '100.896000'
     31.intValue() format as <<%02X>>;
        // yields '1F'
     var d = new Date();
     d format as <<yyyy-MM-dd'T'HH:mm:ss.SSSZ>>;
        // yields '2005-10-31T08:04:31.323-0800'
     0.00123 format as <<00.###E0>>;
         // yields '12.3E-4'


9.JavaFX中的书名号<<>>
   JavaFX技术将法语引用符中包含的任何字符序列视为一个标识符,包括空格。这样允许您使用class、variable、f unction或属性名这些JavaFX关键字。下面提供了一个示例:

var <<while>> = 100;


这个特性使您能够调用以JavaFX关键字命名的Java方法,如下所示:

import javax.swing.JTextArea;

var textArea = new JTextArea();
textArea.<<insert>>("Hello", 0);



10.JavaFX中类的声明
   JavaFX中对类进行声明的语法为:在 class关键字之后紧跟类名,然后是可选的 extends关键字和以逗号分隔的基类名列表。注意,与Java不同,JavaFX技术可以扩展多个类。之后是一个起始的大括号({),一个属性列表,函数和操作,一个关闭的大括号( }),在大括号中间的每一项都使用分号( ;)结尾。下面给出了一个例子:

class Person {

    attribute name: String;
    attribute parent: Person;
    attribute children: Person*;

    function getFamilyIncome(): Number;
    function getNumberOfChildren(): Number;

    operation marry(spouse: Person): Boolean;
}


11.JavaFX中的属性、函数和操作

现在进一步查看三种类成员声明类型。 属性使用 attribute关键字声明,后跟属性名、一个冒号( :)、属性类型、可选的 基数说明,一个可选的反向子句.如果使用了基数,该属性通常被称为 多值属性。

下面展示了更正式的声明,属性使用了以下语法:

attribute 
AttributeName [: 
AttributeType] [? | + | *] [inverse 
ClassName.
InverseAttributeName];


 

可选的 inverse语句位于末尾,说明了与另一个属性的双向关系。如果出现了反向语句,那么当属性被修改时,JavaFX技术将自动更新反向语句中说明的属性——根据更新类型和属性的基数分别使用 insert或 delete或 replace。

函数JavaFX表示编程语言中的纯函数部分。换而言之,函数体可能只包含一些变量声明和一个 return语句。这使它们非常适合于accessors – –getters– – 属性和简单的数学程序。下面是一些示例函数:

function z(a,b) {
    var x = a + b;
    var y = a - b;
    return sq(x) / sq (y);
}

function sq(n) {return n * n; }


 

JavaFX中使用 operation关键字声明 操作。与函数不同,操作可能包含一些语句,例如条件语句、循环语句、 try和 catch语句等等。这一特点使操作非常类似于Java技术中的类方法。声明的主要内容包括操作名,后跟输入变量(使用圆括号括起)、一个冒号和return变量类型。下面是一个例子:< /p>

operation substring(s:String, n:Number): String {
    try {
        return s.substring(n);
    } catch (e:StringIndexOutOfBoundsException) {
        throw "sorry, index out of bounds";
    }
}


12.初始化声明后的属性

和函数和过程一样,属性值的初始化声明在类定义外进行。在新建对象的上下文中,初始化程序按照类声明中指定的属性顺序被逐一求值:

import java.lang.System;

class X {
    attribute a: Number;
    attribute b: Number;
}

attribute X.a = 10;
attribute X.b = -1;

var x = new X();
System.out.println(x.a); // prints 10
System.out.println(x.b); // prints -1


 

JavaFX使用由类名、用大括号包含的属性初始化程序列表构成的 声明式语法来完成对象的初始化。每个初始化程序由属性名、冒号、定义属性值的表达式构成,注意, new关键字被忽略。下面是一个等价的示例:

var myXClass = X {
    a: 10
    b: -1
};



 

JavaFX技术经常使用到声明式语法。但是同样支持Java对象分配语法。在Java类中,可以像Java技术一样将属性传递给类的构造函数,或者可以使用声明式语法:

import java.util.Date;
import java.lang.System;

var date1 = new Date(95, 4, 23);    // call a Java constructor
var date2 = Date {  // create the same date as an object literal
    month: 4
    date: 23
    year: 95
};

System.out.println(date1 == date2);   // prints true


13.函数和操作定义

与Java方法不同的是,所有成员函数体和操作体都是在类声明 之外定义的。Java程序员最初会对这种语法感觉不习惯,但是执行起来 相当简单。在JavaFX技术中,函数或操作的定义为:函数和操作所属的类、一个句号、函数或操作名。返回值将列于函数或操作名后,前面加一个冒号。参数 也可包含在括号中,使用逗号分隔并遵循前面操作部分所示的 name: type语法。如下所示:

operation Person.marry(spouse: Person): Boolean {
    //  Body of operation
}


 

在类声明中,操作和函数声明部分需要包含参数和返回类型。然而,外部定义中可能会忽略这些内容。因此,可以使用下面这种简单的方式:

operation Person.marry() {
    //  Body of operation
}


14.触发器
 

与Java技术不同,JavaFX类不具备构造函数,JavaFX属性一般没有“setter”方法。相反,JavaFX技术提供了类似SQL风格的触发器,允许您处理数据修改事件。这些触发器使用 trigger关键字。

  (1)对象创建触发器

通过指定一个创建触发器,可以在新建的对象上下文中触发某个操作,如下所示:

import java.lang.System;

class X {
     attribute nums: Number*;
}

trigger on new X {
     insert [3,4] into this.nums;
}

var x = new X();
System.out.println(x.nums == [3,4]); // prints true


 

上面这个例子中定义的触发器将在创建一个新的X类实例时执行。在这个例子中,将向 nums属性插入两个数值。注意,这里使用了 this关键字表示触发器上下文的当前对象。

(2)Insert 触发器

当元素被插入到多值属性中时,也可以触发一个操作:

import java.lang.System;

class X {
     attribute nums: Number*;
}

trigger on insert num into X.nums {
     System.out.println("just inserted {num} into X.nums at position {indexof num}");
}

var x = new X();
insert 12 into x.nums;
    // prints just inserted 12 into X.nums at position 0
insert 13 into x.nums;
    // prints just inserted 13 into X.nums at position 1


 

(3)Delete触发器

同样,当从多值属性中删除某个元素时,可以触发一个操作:

import java.lang.System;

class X {
     attribute nums: Number*;
}

trigger on delete num from X.nums {
     System.out.println("just deleted {num} from X.nums at position {indexof num}");
}

var x = X {
     nums: [12, 13]
};

delete x.nums[1];
    // prints just deleted 13 from X.nums at position 1
delete x.nums[0];
    // prints just deleted 12 from X.nums at position 0


 

(4)Replace触发器

最后,当替代某个属性的值时可以执行一个操作。在下面的例子中, oldValue和 newValue两个任意变量名,引用被替换变量的前一个值和当前值。您可以随意选择其他变量名。

import java.lang.System;

class X {
     attribute nums: Number*;
     attribute num: Number?;
}

trigger on X.nums[oldValue] = newValue {
     System.out.println("X.nums: replaced {oldValue} with {newValue} at position {indexof
newValue}");
}

trigger on X.num[oldValue] = newValue {
     System.out.println("X.num: replaced {oldValue} with {newValue}");
}

var x = X {
     nums: [12, 13]
     num: 100
};

x.nums[1] = 5;
    // prints replaced 13 with 5 at position 1 in X.nums
x.num = 3;
    // prints X.num: replaced 100 with 3
x.num = null;
    // prints X.num: replaced 3 with null



15.语句
 

JavaFX技术支持一些与Java技术中的同类语句类似但不完全相同的语句。这一节将介绍它们之间的区别。

If语句

JavaFX的 if语句用法类似Java,但是大括号必须像下面这样:

 if (condition1) {
    System.out.println("Condition 1");
} else if (condition2) {
    System.out.println("Condition2");
} else {
    System.out.println("not Condition 1 or Condition 2");
}


 

While语句

JavaFX while语句中的大括号必须环绕语句体之外:

var i = 0;
while (i < 10) {
    if (i > 5) {
       break;
    }
    System.out.println("i = {i}");
    i += 1;
}


 

Try、 Catch和 Throw语句

JavaFX的 try和 catch语句类似Java技术,但是具有JavaFX变量声明语法。注意,在JavaFX技术中,可以抛出和捕捉任何对象,而不仅仅是 java.lang.Throwable的扩展类。

try {
   throw "Hello";
} catch (s:String) {
   System.out.println("caught a String: {s}");
} catch (any) {
   System.out.println("caught something not a String: {any}");
} finally {
   System.out.println("finally...");
}
 

 

For语句

JavaFX的 for语句头与前面讨论的 foreach列表推导操作符使用相同的语法。但是,在下面示例中for语句体处理的是由列表推导生成的成员:

for (i in [0..10]) {
     System.out.println("i = {i}");
}

// print only the even numbers using a filter
for (i in [0..10] where (i%2 == 0) ) {
     System.out.println("i = {i}");
}

// print only the odd numbers using a range expression
for (i in [1,3..10]) {
     System.out.println("i = {i}");
}

// print the cartesian product
for (i in [0..10], j in [0..10]) {
     System.out.println(i);
     System.out.println(j);
}


 

Return语句

JavaFX的 return语句类似于Java技术:

operation add(x, y) {
    return x + y;
}



 

Break和 Continue语句

JavaFX的 break和 continue语句类似于Java技术,不同之处是,这里不支持标签。在Java语言中, break和 continue必须位于 while或 for语句的语句体内。

operation foo() {
   for (i in [0..10]) {
       if (i > 5) {
           break;
       }
       if (i % 2 == 0) {
           continue;
       }
       System.out.println(i);
   }
}

operation bar() {
    var i = 0;
    while (i < 10) {
        if (i > 5) {
            break;
        }
        if (i % 2 == 0) {
            continue;
        }
        System.out.println(i);
        i += 1;
    }
}
 

 

Do和 Do Later语句

JavaFX的 do语句运行执行JavaFX代码块。但是, do语句体通常在后台线程执行。通常,JavaFX代码都在AWT事件调度线程(Event Dispatch Thread,EDT)中执行——只允许包含在 do语句体内的代码在另一个线程执行。考虑下面的示例:

import java.net.URL;
import java.lang.StringBuffer;
import java.lang.System;
import java.io.InputStreamReader;
import java.io.BufferedReader;

// in the AWT Event Dispatch Thread (EDT)
var result = new StringBuffer();

do {
    // now in a background thread
     var url = new URL("http://www.foo.com/abc.xml");
     var is = url.openStream();
     var reader = new BufferedReader(new InputStreamReader(is));
     var line;
     while (true) {
          line = reader.readLine();
          if (line == null) {
               break;
          }
          result.append(line);
          result.append("\n");
     }
}

// now back in the EDT
System.out.println("result = {result}");


 

在EDT中正在执行的代码将在执行 do语句体期间被阻塞。但是,在等待后台线程完成期间,将在堆栈中创建一个新的事件调度循环。因此,在处理do语句时,将继续执行图形用户界面(GUI)事件。

do语句的第二种形式 do later,运行在EDT中异步执行语句体,而不是在后台线程中同步执行,这类似于 java.awt.EventQueue.invokeLater()提供的功能。见下面的例子:

import java.lang.System;
var saying1 = "Hello World!";
var saying2 = "Goodbye Cruel World!";
do later {
     System.out.println(saying1);
}
System.out.println(saying2);


 

运行代码将生成以下输出:

Goodbye Cruel World!
Hello World!

16.增量式求值
JavaFX技术的一个最令人兴奋的特性就是增量式求值。它允许程序员声明式地定义复杂的动态GUI。在JavaFX技术中,属性初始化程序能够使用 bind操作符进行增量式求值。使用bind初始化的属性类似于包含公式(而不是字母值)的电子表格中的单元格。只要在初始化表达式右侧引用的任何对象发生改变,其左侧的对象属性值将被自动更新。

示例如下:

import java.lang.System;

class X {
    attribute a: Number;
    attribute b: Number;
}

var x1 = X {
    a: 1
    b: 2
};

var x2 = X {
    a: x1.a           // nonincremental
    b: bind x1.b      // incremental
};

System.out.println(x2.a); // prints 1
System.out.println(x2.b); // prints 2

x1.a = 5;
x1.b = 5;

System.out.println(x2.a); // prints 1
System.out.println(x2.b); // prints 5


 

上例中, x2的 b属性被绑定到 x1的 b属性。这意味着,当 x1的 b属性被更新时, x2的 b属性也会相应地被更新。

注意:函数体无需 bind操作符便可被增量地求值,但操作体则做不到。与函数不同,在改变本地变量的操作中并不触发增量式求值。增量式求值不能在操作体内执行,除非表达式明确地以 bind为前缀。

您也可以对示例进行修改,从而使用懒惰增量式求值。这种情况下,绑定只有在首次访问 attribute值时才会起作用。

import java.lang.System;

class X {
    attribute a: Number;
}

var x1 = X {
    a: 1
};

var x2 = X {
    a: bind lazy x1.a
    // no value is assigned yet
};

System.out.println(x2.a);
// Now the value is accessed, so x2.a is set to 1


 

懒惰增量式求值通常用于处理递归数据结构,例如树和图。

























分享到:
评论
1 楼 daoyongyu 2008-12-15  
学习了。楼主辛苦了。
提个小小的建议,楼主的页面看起来感觉好沉重!

相关推荐

Global site tag (gtag.js) - Google Analytics