Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 706|回复: 0

[JavaFx学习]JavaFX编程语言

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-16 15:03:31 | 显示全部楼层 |阅读模式
    javaFX编程语言
      
       Last Updated: May 2007
       
      
       Translated by Liu Dan (
       cleverpig) and Tian Le (Tin)
       
      

      JavaFX Script? (下文中成为JavaFX)语言是一种声明式的静态类型编程语言。它具有第一级函数(first-class functions)、声明式的语法、列表推导(list-comprehensions)及基于依赖关系的增量式求值(incremental dependency-based evaluation)等特征。JavaFX 脚本式语言特别适用于Java2D swing GUI组件,它允许简单地创建图形界面。  
      译者注:第一级函数指函数被当作对象对待,可以在运行时赋值、传递和返回。详见wikipedia上的解释
      译者注:列表推导指一种在函数语言中的表达式,它表示了在一个或者多个列表的成员(被选择的)进行某种操作的结果。它被称为“syntactic sugar”,即为开发者提供了便捷的多种函数的应用组合。详见FOLDC对list comprehension的解释
      本文档给出了JavaFX 脚本式编程语言的非正式描述。
      内容:
       
       基本类型
       调用Java对象  
       变量
       函数、数组、表达式和操作  
       修改数组
         
         insert语句
          
           into  
           before, after
            
         delete语句
          
       查询数组
       表达式
       字符串和字符串表达式
       引用标识符
       范围表达式
       字符串(String)、数值(Number)和日期的格式化
       操作
         
         表达式语句
         If语句
         While语句
         Try语句
         For语句
         Return语句
         Throw语句
         Break和Continue语句
         Do语句
          
           do later
            
          
       类与对象
         
         属性声明
         对象声明
          
       更新触发器
         
         创建触发器
         插入触发器
         删除触发器
         替换触发器
          
       增量式求值和懒惰求值
       反射
       广度(Extents)和枚举
       相关资源
       关于译者
       译文Feedback
       
      top
      基本类型
       JavaFX语言提供四种基本类型:
    1. String(字符串)
    复制代码
    1. Boolean(布尔)
    复制代码
    1. Number(数值)
    复制代码
    1. Integer(整数)
    复制代码
    。这些类型相当于Java的如下类型:  
       
       
         
          
         
         
         JavaFX
         Java
         
         
       
    1. String
    复制代码

       
    1. java.lang.String
    复制代码

         
         
       
    1. Boolean
    复制代码

       
    1. java.lang.Boolean
    复制代码

         
         
       
    1. Number
    复制代码

       
    1. java.lang.Number
    复制代码

         
         
       
    1. Integer
    复制代码

       
    1. byte,short,int,long,BigInteger
    复制代码

         
       
       
      

      例如:
      
            var s = "Hello";
            s.toUpperCase(); // yields "HELLO";
            s.substring(1);  // yields "ello";
            var n = 1.5;
            n.intValue();    // yields 1
            (1.5).intValue();    // yields 1
            s.substring(n);  // yields "ello"
            var b = true;
            b instanceof Boolean; // yields true
                        [/code]
       
       在向Java方法传递参数或者从Java方法返回结果的时候,数值类型会自动执行强制类型转换。并且,在转换
    1. Number
    复制代码
    1. Integer
    复制代码
    的时候还会进行隐式的强制截断。  
      top
      调用Java对象
       JavaFX可以导入Java类、创建新的Java对象、调用它们的方法,也可以实现Java的接口。下面的代码片断提供了一个示例:  
             
            import javax.swing.JFrame;
            import javax.swing.JButton;
            import java.awt.event.ActionListener;
            import java.lang.System;
           
            var frame = new JFrame();
            var button = new JButton("Press me");
            frame.getContentPane().add(button);
            button.addActionListener(new ActionListener() {
                    operation actionPerformed(event) {
                        System.out.println("You pressed me");
                    }
            });
            frame.pack();
            frame.setVisible(true);
                        [/code]
       运行上面的程序后,屏幕上显示如下内容:
       
      
       
       
       
       当然,这并不是JavaFX推荐的创建图形用户界面的方式。下面的JavaFX代码实现了相同的效果:  
               
            Frame {
                    content: Button {
                            text: "Press Me"
                            action: operation() {
                                    System.out.println("You pressed me");
                      }
              }
              visible: true
            }
                        [/code]
      top
      变量
       在JavaFX中,
    1. var
    复制代码
    这个关键词用来声明变量。你可以在声明中指定变量的类型。然而,这在JavaFX中是可选的。如果你不指定类型,JavaFX解释器会根据它的用途推断变量的类型。变量声明使用如下格式:  
              var variableName : typeName [?,+,*] = initializer;
                        [/code]
       你可以使
    1. ?
    复制代码

    1. +
    复制代码
    或者
    1. *
    复制代码
    操作表示变量的重数(cardinality),如下表:
      

      

       
       
         
          
         
         
         操作符
         含义
         
         
       
    1. ?
    复制代码

         Optional (i.e, may be
    1. null
    复制代码
    )
         
         
       
    1. +
    复制代码

         One or more
         
         
       
    1. *
    复制代码

         Zero or more
         
       
       
       例如:
              var nums:Number* = [1,2,3];
                        [/code]
      上面的示例声明了一个新的、名为nums的变量,它值由零个或者多个Number类型组成,其初始值为
    1. [1,2,3]
    复制代码
    。  
    1. [i]:typeName[/i]
    复制代码

    1. [i][?,+,*][/i]
    复制代码
    以及
    1. [i]=initializer[/i]
    复制代码
    这些声明部分是可选的,所以下面的方式与上面等价:
      
            var nums = [1,2,3];
                        [/code]
      top
      
      函数、数组、表达式和操作
       JavaFX
    1. 函数
    复制代码
    代表了JavaFX编程语言的纯函数子集。函数体可以仅包含一组变量声明和一个返回语句。JavaFX也提供了过程(procedures)(被调用的
    1. 操作
    复制代码
    ,详见下面关于操作的章节),里面可以包括任意数量的声明、条件语句、循环条件、try/catch等等。语句在函数中的给定顺序并不很重要。下面是一个简单的函数程序的例如:  
      
            function z(a,b) {
               var x = a + b;
               var y = a - b;
               return sq(x) / sq (y);
            }
           
            function sq(n) {return n * n;}
           
            function main() {
               return z(5, 10);
            }
                        [/code]
       尽管JavaFX语言是静态类型的,但这里并没有强制的类型声明(后面会详细叙述)。  最常用的数据结构是数组,它在JavaFX中通过方括弧和逗号来声明:
    复制代码

      
            var week_days = ["Mon","Tue","Wed","Thur","Fri"];
            var days = [week_days, ["Sat","Sun"]];
                        [/code]
       数组代表了一组顺序的对象。JavaFX中的数组本身不是对象,而且不能嵌套。创建嵌套数组的表达式(例如上面“days”的初始化方式)会被自动扁平化,例如:  
    复制代码

      
            days == ["Mon","Tue","Wed","Thur","Fri","Sat","Sun"]; // returns true
                        [/code]
       数组的大小可以通过JavaFX的
    1. sizeof
    复制代码
    操作符确定:
    复制代码

      
            var n = sizeof days; // n = 7
                        [/code]
       对于数组成员形成数列(arithmetic series)的数组,JavaFX提供了一种简写符号:“
    1. ..
    复制代码
    ”。下面提供了定义阶乘函数和奇数求和函数的示例,其中“result”的数值是1至100中奇数的和:
      
            function fac(n) {return product([1..n]);}
            var result = sum([1,3..100]);
                        [/code]
       数组中的所有元素必须是同一种类型。  
       数组可以像在Java中那样通过索引访问:
    复制代码

              var wednesday = days[2];
                        [/code]
       JavaFX中的
    1. []
    复制代码
    操作符还可用来表示选择(类似XPath的用法)。在这种情况下,
    1. []
    复制代码
    中包含的表达式应是一个布尔表达式。此表达式可以返回一个新的数组,此数组中只包含满足
    1. []
    复制代码
    中断言(predicate)的成员。
       
       就像在XPath一样,可以在
    1. []
    复制代码
    操作符包含的断言中通过.操作符访问上下文对象。例如:
    复制代码

              var nums = [1,2,3,4];
            var numsGreaterThanTwo = nums[. > 2]; // yields [3, 4]
                        [/code]
       
       另一种方法,也可以将变量声明为上下文对象。例如,这种方式与上面的方式等价:
    复制代码

              numsGreaterThanTwo = nums[n|n > 2];
                        [/code]
       
       JavaFX中的
    1. indexof
    复制代码
    操作符返回对象在数组中的顺序位置(类似XPath中的
    1. position()
    复制代码
    函数)。  
       下面list的car和cdr可以用选择表达式来表示:
    复制代码

              function car(list) {return list[indexof . == 0];}
            function cdr(list) {return list[indexof . > 0];}
                        [/code]
       
       当然,car可以用更简单、高效的方式表示:
    复制代码

              function car(list) {return list[0];}
                        [/code]
       
       例如:
    复制代码

              var list = [1..10];
            car(list); // yields 1
            cdr(list); // yields [2,3,4,5,6,7,8,9,10]
                        [/code]
       JavaFX中的空数组
    1. []
    复制代码
    1. null
    复制代码
    等价,例如:
    复制代码

      
            [] == null // yields true
            sizeof null // yields 0
                        [/code]
      top
      修改数组
       除了赋值操作(
    1. =
    复制代码
    )之外,JavaFX还提供数据修改操作符(
    1. insert
    复制代码
    1. delete
    复制代码
    ),它类似XQuery-Update规范中的语法和语义:  
      insert语句
       可以用下面方式中的任意一种进行声明:  
       
      
            insert Expression1 [as first | as last] into Expression2
            insert Expression1 before Expression2
            insert Expression1 after Expression2
                        [/code]
       
      
    1. insert
    复制代码
    语句将表达式1求值后的返回结果插入到下面表达式中所描述的位置:  
       into  
       表达式2必须指向一个属性或者变量。如果表达式2指向一个单值属性,那么插入的效果等同于赋值操作。  
       如果指定了
    1. as first
    复制代码
    ,那么插入位置就在表达式2所表示的列表的第一个元素的前面。如果指定了
    1. as last
    复制代码
    ,那么插入位置就在表达式2所表示的列表的最后一个元素的后面。如果没有明确地指定
    1. as first
    复制代码
    或者
    1. as last
    复制代码
    ,则默认为
    1. as last
    复制代码
    。  
       例如:  
      
            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]
                        [/code]
       
       before, after   
       表达式2必须是在属性或者变量之上的选择表达式。如果指定了
    1. before
    复制代码
    ,那么插入位置就是在被选择的元素之前。如果指定了
    1. after
    复制代码
    ,插入位置则在被选择的元素之后。  
       例如:  
      
    复制代码

      
            var x = [1,2,3];
            insert 10 after x[. == 10]; // 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];
                        [/code]
      top
      delete语句
      
    1. delete
    复制代码
    语句可以使用下面形式中的一种:  
       
      
            delete variable
            delete Expression.attribute
            delete variable[predicate]
            delete Expression.attribute[predicate]
                        [/code]
       
       前两种形式将删除变量或者属性中的所有元素,它们等价于将变量或者属性赋值为
    1. []
    复制代码
    或者
    1. null
    复制代码
    。后两种形式仅删除满足断言的元素。  
       例如:  
      
    复制代码

      
            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; // yields []
                        [/code]
      top
       
       查询数组
        像在MirandaHaskell这些函数式编程语言中一样,JavaFX支持列表推导(list comprehensions),但是为了使用一种Java程序员更加熟悉、易懂的语法形式进行表达,JavaFX采取了
    1. select
    复制代码
    1. foreach
    复制代码
    操作符。  
        这里提供一个例如:  
       
            class Album {
                    attribute title: String;
                    attribute artist: String;
                    attribute tracks: String*;
            }
            var albums =
            [Album {
                    title: "A Hard Day"s Night"
                    artist: "The Beatles"
                    tracks:
                    ["A Hard Day"s Night",
                    "I Should Have Known Better",
                    "If I Fell",
                    "I"m Happy Just To Dance With You",
                    "And I Love Her",
                    "Tell Me Why",
                    "Can"t Buy Me Love",
                    "Any Time At All",
                    "I"ll Cry Instead",
                    "Things We Said Today",
                    "When I Get Home",
                    "You Can"t Do That"]
                    },
            Album {
                    title: "Circle Of Love"
                    artist: "Steve Miller Band"
                    tracks:
                    ["Heart Like A Wheel",
                      "Get On Home",
                      "Baby Wanna Dance",
                      "Circle Of Love",
                      "Macho City"]
            }];
            // Get the track numbers of the albums" title tracks
            // using the select operator:
            var titleTracks =
                    select indexof track + 1 from album in albums,
                            track in album.tracks
                                    where track == album.title; // yields [1,4]
            // the same expressed using the foreach operator:
            titleTracks =
                    foreach (album in albums,
                            track in album.tracks
                                    where track == album.title)
                                            indexof track + 1;  // also yields [1,4]
                        [/code]
       
        列表推导由一个或多个输入列表,一个可选的过滤器和一个生成器表达式组成。每个源列表与一个变量关联。列表推导的结果是将生成器应用于满足过滤器的源列表成员的笛卡尔乘积的子集后得到的新列表。  
        译者注:这里的过滤器指的是where子句。  
        列表推导为创建在列表上进行迭代遍历的通用类提供了一种简明的语法。  
        列表推导的另外一个简单示例:  
      
    复制代码

       
            select n*n from n in [1..100]
                        [/code]
       
        这个列表(顺序地)包含1至100的所有数的平方值。注意上面表达式中的“n”是局部变量。  
        下面的代码通过定义计算某个数值的所有因子的函数演示了如何使用过滤器:  
       
      
    复制代码

       
            function factors(n) {
                    return select i from i in [1..n/2] where n % i == 0;
            }
                        [/code]
       top
       
       
       表达式
        JavaFX支持如下操作符:  
       
         
          
          
          
          
          操作符
          含义
          Java等价物
          
          
          
          
          
          关系操作符
          
          
         
    1. ==
    复制代码

          equality
         
    1. ==
    复制代码

          
          
         
    1. <>
    复制代码

          inequality
         
    1. !=
    复制代码

          
          
         
    1. <
    复制代码

          less than
         
    1. <
    复制代码

          
          
         
    1. >
    复制代码

          greater than
         
    1. >
    复制代码

          
          
         
    1. <=
    复制代码

          less than or equal
         
    1. <=
    复制代码

          
          
         
    1. >=
    复制代码

          greater than or equal
         
    1. >=
    复制代码

          
          
          
          
          
          布尔操作符
          
          
          
         
    1. and
    复制代码

          logical and
         
    1. &&
    复制代码

          
          
         
    1. or
    复制代码

          logical or
         
    1. ||
    复制代码

          
          
         
    1. not
    复制代码

          logical negation
         
    1. !
    复制代码

          
          
          
          
          
          算术操作符
          
          
         
    1. +
    复制代码

          addition
         
    1. +
    复制代码

          
          
         
    1. -
    复制代码

          subtraction; unary negation
         
    1. -
    复制代码

          
          
         
    1. *
    复制代码

          multiplication
         
    1. *
    复制代码

          
          
         
    1. /
    复制代码

          division
         
    1. /
    复制代码

          
          
         
    1. %
    复制代码

          remainder
         
    1. %
    复制代码

          
          
         
    1. +=
    复制代码

          add and assign
         
    1. +=
    复制代码

          
          
         
    1. -=
    复制代码

          subtract and assign
         
    1. -=
    复制代码

          
          
         
    1. *=
    复制代码

          multiply and assign
         
    1. *=
    复制代码

          
          
         
    1. /=
    复制代码

          divide and assign
         
    1. /=
    复制代码

          
          
         
    1. %=
    复制代码

          remainder and assign
         
    1. %=
    复制代码

          
          
          
          
          
          其它操作符
          
          
         
    1. sizeof
    复制代码

          array length
         
    1. n/a
    复制代码

          
          
         
    1. indexof
    复制代码

          ordinal position
         
    1. n/a
    复制代码

          
          
         
    1. if [i]e1[/i] then [i]e2[/i] else [i]e3[/i]
    复制代码

          conditional expression
         
    1. [i]e1[/i] ? [i]e2[/i] : [i]e3[/i]
    复制代码

          
          
         
    1. select
    复制代码

          list comprehension
         
    1. n/a
    复制代码

          
          
         
    1. foreach
    复制代码

          list comprehension
         
    1. n/a
    复制代码

          
          
         
    1. new
    复制代码

          allocation
         
    1. new
    复制代码

          
          
         
    1. [i]op[/i]()
    复制代码

          function/operation call
         
    1. [i]n/a[/i]
    复制代码

          
          
         
    1. [i]x[/i].[i]op[/i]()
    复制代码

          member function/operation call
         
    1. [i]x[/i].[i]op[/i]()
    复制代码

          
          
         
    1. instanceof
    复制代码

          type check
         
    1. instanceof
    复制代码

          
          
         
    1. this
    复制代码

          self access
         
    1. this
    复制代码

          
          
         
    1. .
    复制代码

          attribute access, context access
         
    1. ., n/a
    复制代码

          
          
         
    1. bind [lazy]
    复制代码

          incremental [lazy] evaluation
         
    1. n/a
    复制代码

          
          
         
    1. :
    复制代码

          eager initialization
         
    1. n/a
    复制代码

          
          
         
    1. []
    复制代码

          array selection
         
    1. []
    复制代码

          
          
         
    1. format as
    复制代码

          String formatting
         
    1. n/a
    复制代码

          
          
         
    1. <<>>
    复制代码

          Identifier quotes
         
    1. n/a
    复制代码

          
          
         
    1. {}
    复制代码

          String expression
         
    1. n/a
    复制代码

          
          
         
    1. ([i]expr[/i])
    复制代码

          grouping
         
    1. ([i]expr[/i])
    复制代码

          
          
         
    1. reverse
    复制代码

          reverses a list
         
    1. n/a
    复制代码

          
          
         
    1. [[i]number1[/i],[i]next[/i]..[i]number2[/i]]
    2.          
    复制代码

          numeric range
         
    1. n/a
    复制代码

          
         
       
        一些示例:  
                
            import java.lang.System;
            import java.lang.Math;
           
            var x = 2;
            var y = 4;
            var a = true;
            var b = false;
            System.out.println(x == y);  // prints false
            System.out.println(x <> y);  // prints true
            System.out.println(x < y);   // prints true
            System.out.println(x > y);   // prints true
            System.out.println(x >= y);  // prints false
            System.out.println(x <= y);  // prints true
            System.out.println(x + y);   // prints  6
            System.out.println(x - y);   // prints  -2
            System.out.println(x * y);   // prints  8
            System.out.println(x / y);   // prints  0.5
            System.out.println(x % y);   // prints  2
            System.out.println(a and b); // prints  false
            System.out.println(a or b);  // prints  true
            System.out.println(not a);   // prints  false
            System.out.println(sizeof [x,y]);   // prints  2
            System.out.println([x,y][indexof . == 0]);   // prints  2
            System.out.println(if a then x else y); // prints 2
            System.out.println(select q from q in [x, y] where q > 3); prints 4
            System.out.println(foreach(q in [x, y] where q < 3) q); prints 2
            System.out.println(Math.max(x, y)); // prints 4
            System.out.println("abc".toUpperCase()); // prints ABC
            System.out.println(x instanceof Number); // prints true
            x = 10;
            System.out.println(x); // prints 10
                        [/code]
       top
       字符串和字符串表达式
        在JavaFX中,字符串通过单引号指定,例如:  
               var s = "Hello";
                        [/code]
        或者通过双引号:
               var s = "Hello";
                        [/code]
       
        在使用双引号的情况下,可以使用
    1. {}
    复制代码
    嵌入JavaFX表达式,例如:  
       
            var name = "Joe";
            var s = "Hello {name}"; // s = "Hello Joe"
                        [/code]
       
        嵌入的表达式自身也可包含使用双引号引用的字符串(同样,里面还可以包含更深一级的嵌套表达式),例如:  
       
            var answer = true;
            var s = "The answer is {if answer then "Yes" else "No"}"; // s = "The answer is Yes"
                        [/code]
       
        与Java不同,在JavaFX中使用双引号引用的字符串可以包含换行:  
       
            var s = "This
                    contains
                    new lines";
                        [/code]
       top
       引用标识符
        在JavaFX中,包含在法语引用符
    1. <<>>
    复制代码
    里的任何字符串序列(包括空白)被作为标识符。这样允许你使用像class、variable、function或者属性名这样的JavaFX关键字(或者其它的一般情况下非法的标识符),例如:  
               var <<while>> = 100;
                        [/code]
        它也使调用与JavaFX关键字同名的Java方法称为可能,例如:  
       
            import javax.swing.JTextArea;
            var textArea = new JTextArea();
            textArea.<<insert>>("Hello", 0);
                        [/code]
       top
       范围表达式
        如前所述,通过下面的语法你可以定义一个形成数列的数值数组。  
       
            [number1..number2]
                        [/code] 此表达式定义了一个从
       number1
       number2之间(含两端)的连续整数构成的数组。
       
        例如:  
       
            var nums = [0..3];
            System.out.println(nums == [0,1,2,3]); // prints true
    [/code]
       
        默认情况下,值与值的间隔是
    1. 1
    复制代码
    ,但是也可以指定不同的间隔,这需要在数列的number1后面写出下一个数值,并用逗号隔开。例如,下面的表达式定义了一个包含1至10之间奇数的数组。  
       
            [1,3..10]
    [/code]
        如果number1number2要大,会创建降序的数组:  
       
            var nums = [3..0];
            System.out.println(nums == [3,2,1,0]); // prints true
    [/code]
       top
       字符串(String)、数值(Number)和日期的格式化
        JavaFX有内建的字符串格式化操作符(
    1. format as
    复制代码
    ),语法如下:  
       
            表达式 format as 指令
    [/code]
       
    1. format as
    复制代码
    操作符支持
    1. java.text.DecimalFormat
    复制代码
    1. java.text.SimpleDateFormat
    复制代码
    1. java.util.Formatter
    复制代码
    的格式化指令:如果格式化指令以%开头,那么将会使用
    1. java.util.Formatter
    复制代码
    ;如果表达式是
    1. Number
    复制代码
    类型,则使用
    1. java.text.DecimalFormat
    复制代码
    ;如果表达式是
    1. java.util.Date
    复制代码
    类型,则使用
    1. java.text.SimpleDateFormat
    复制代码
    。指令操作数是一个在语法上的标识符,而不是一个表达式。这就允许了在编译时静态检查指令内容的正确性。  例如:
       
            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"
    [/code]
       
      top
       
       操作
        在JavaFX中使用
    1. operation
    复制代码
    关键字声明过程(procedure)。例如:  
       
            import java.lang.StringIndexOutOfBoundsException;
            operation substring(s:String, n:Number): String {
                    try {
                            return s.substring(n);
                    } catch (e:StringIndexOutOfBoundsException) {
                            throw "sorry, index out of bounds";
                    }
            }
                        [/code]
       
        在上例中定义了一个称为“
    1. substring
    复制代码
    ”的新过程,它接受两个参数:第一为字符串类型的参数“s”,第二为Number类型的参数“n”,而返回值为字符串类型。  
        除了从前提到的赋值、
    1. delete
    复制代码
    1. insert
    复制代码
    语句之外,下面的语句也可以在过程体中使用:  
       表达式语句
        一个基本的表达式可以被用作一条语句,例如下面示例中的"Hello World!":  
              System.out.println("Hello World!");
                        [/code]
       top
       If语句
        JavaFX的
    1. if
    复制代码
    语句用法类似Java,除了大括号必须环绕随后的子句(除非else子句是另一个
    1. if
    复制代码
    语句)之外。  
        例如:  
       
            if (condition1) {
                    System.out.println("Condition 1");
            } else if (condition2) {
                    System.out.println("Condition2");
            } else {
                    System.out.println("not Condition 1 or Condition 2");
            }
                        [/code]
       top
       While语句
        JavaFX的
    1. while
    复制代码
    语句用法与Java类似,除了大括号必须环绕语句体之外。  
        例如:  
       
            var i = 0;
            while (i < 10) {
                    if (i > 5) {
                            break;
                    }
                    System.out.println("i = {i}");
                    i += 1;
            }
                        [/code]
       top
       Try语句 JavaFX的
      
    1. try
    复制代码
    语句用法类似Java,但它具有JavaFX变量声明语法。 注意:在JavaFX中,任意对象都能够被抛出和捕捉,而并非仅仅是
      
    1. 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...");
            }
                            [/code]
       top
       For语句 JavaFX的
      
    1. for
    复制代码
    语句头与
      
    1. foreach
    复制代码
    列表推导操作符(list comprehension operator)使用相同的语法。但是,在下面示例中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);
            }
                            [/code]
       top
       Return语句 JavaFX的
      
    1. return
    复制代码
    语句与Java相同:
        例如:  
       
            operation add(x, y) {
                    return x + y;
            }
                            [/code]
       top
       Throw语句 JavaFX的
      
    1. throw
    复制代码
    语句类似Java。但是在JavaFX中能够抛出任何对象,而不仅仅是
      
    1. java.lang.Throwable
    复制代码
    的继承类。
        例如:  
       
            import java.lang.Exception;
            operation foo() {
                    throw new Exception("this is a java exception");
            }
            operation bar() {
                    throw "just a string";
            }
                            [/code]
       top
       Break和Continue语句 JavaFX的
      
    1. break
    复制代码

      
    1. continue
    复制代码
    语句用法Java不同的之处:前者不支持标签。像在Java中一样,
      
    1. break
    复制代码

      
    1. continue
    复制代码
    必须出现在
      
    1. while
    复制代码
    或者
      
    1. 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;
                    }
            }
                            [/code]
       top
       Do语句
        JavaFX的
    1. do
    复制代码
    语句允许使用者在后台线程中执行一块JavaFX代码,以便AWT事件调度线程继续处理事件,从而防止UI平台出现挂起现象。目前,在执行后台线程时采用
    1. java.awt.EventQueue
    复制代码
    实现了对事件的出/入队操作。通常情况下,所有的JavaFX代码都在AWT事件调度线程中执行,只有包含在
    1. do
    复制代码
    语句体中的语句被允许在另一个线程中执行。这些代码必须只访问Java对象,如果需要的话,那些Java对象还必须处理其自身的线程同步。  
        例如:  
       
            import java.net.URL;
            import java.lang.StringBuffer;
            import java.lang.System;
            import java.io.InputStreamReader;
            import java.io.BufferedReader;

            // in the AWT 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("
    ");
                    }
            }
            // now back in the EDT
            System.out.println("result = {result}");
                            [/code]
        在上面的示例中,在事件调度线程(EDT)中正在执行的那些绿色代码在
    1. do
    复制代码
    语句(红色代码)执行期间将被阻塞。但如果在等待后台线程完成的期间,一个新的事件调度循环被建立在调用堆栈上,那么在执行
    1. do
    复制代码
    语句的同时这些GUI事件将继续被处理。不幸的是,由于它能够引发建立在堆栈上的多重事件调度循环,乃至在糟糕的情况下引起堆栈溢出异常,而目前并没有一种对此称得上优秀的解决方案。  
       top
       do later
       
    1. do
    复制代码
    语句的第二种形式(
    1. do later
    复制代码
    ):它允许在事件调度线程中的语句体内进行异步执行,而不是在后台线程中执行(此功能由
    1. java.awt.EventQueue.invokeLater
    复制代码
    提供)。顾名思义,do later语句体在事件调度线程执行完成后才被执行。下面是一个例如:  
       
            import java.lang.System;
            var saying1 = "Hello World!";
            var saying2 = "Goodbye Cruel World!";
            do later {
                    System.out.println(saying1);
            }
            System.out.println(saying2);
                            [/code]
        运行上面的代码将产生如下输出:
       
            Goodbye Cruel World!
            Hello World!
                            [/code]
       top
       类与对象
        JavaFX中声明类的语法:在
    1. class
    复制代码
    关键字后面跟着类名,接着是可选的
    1. extends
    复制代码
    关键字和由逗号分割的基类名列表,一个开放的大括号({),一个属性列表,函数和操作,一个关闭的大括号(}),在大括号中间的每一个语法逻辑行都使用分号结尾。  
       例如:
       
            class Person {
                    attribute name: String;
                    attribute parent: Person inverse Person.children;
                    attribute children: Person* inverse Person.parent;
                    function getFamilyIncome(): Number;
                    function getNumberOfChildren(): Number;
                    operation marry(spouse: Person);
            }
                            [/code]
        属性的声明方式:
    1. attribute
    复制代码
    关键字后面跟着属性名,一个冒号,属性类型,可选的重数(cardinality)说明(
    1. ?
    复制代码
    代表不确定,
    1. *
    复制代码
    代表零个或者更多,
    1. +
    复制代码
    代表一个或者更多),一个可选的、用来说明与类中另一属性之间双向关系的反向子句(
    1. inverse
    复制代码
    clause),并使用分号结束。  
       
            attribute AttributeName : AttributeType Cardinality inverse ClassName.InverseAttributeName;
                            [/code]
        如果反向子句出现在对象属性定义中,那么当此属性值被修改时JavaFX解释器将自动更新其反向属性(根据更新的类型和属性的重数进行插入、删除或者替换)。  
        多值属性(例如那些使用
    1. *
    复制代码
    或者
    1. +
    复制代码
    重数描述符声明的属性)被表示为数组,并能够通过
    1. []
    复制代码
    操作符访问,并使用
    1. insert
    复制代码
    1. delete
    复制代码
    操作符更新。  
       和Java方法不同,所有的JavaFX成员操作体和成员函数体都被定义在类声明外部,例如:
       
            function Person.getNumberOfChildren() {
                    return sizeof this.children;
            }
                            [/code]
        在类声明中对操作和函数的声明都需要对参数和返回值类型进行声明,而在操作体和函数体的具体定义中则可被忽略。  
       top
       属性声明
       在JavaFX中可以声明属性的初始值。在新建对象上下文中的初始化程序按照声明顺序被逐一求值(见下例的粗体部分):  
       
            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
                            [/code]
        还可以通过
    1. bind
    复制代码
    操作将增量式求值表达式(incrementally evaluated expression)声明为属性值:  
       
            import java.lang.System;
            class X {
                    attribute a: Number;
                    attribute b: Number;
                    attribute c: Number;
            }
            attribute X.a = 10;

            attribute X.b = bind a + 10;
            attribute X.c = bind lazy b + 10;

            var x = new X();
            System.out.println(x.a); // prints 10
            System.out.println(x.b); // prints 20
            System.out.println(x.c); // prints 30
            x.a = 5;
            System.out.println(x.a); // prints 5
            System.out.println(x.b); // prints 15
            System.out.println(x.c); // prints 25
                            [/code]
       top
       对象声明
        JavaFX使用由类名、用大括号包含的属性初始化程序列表构成的说明性语法来完成对象的初始化。每个初始化程序由属性名、冒号、定义属性值的表达式(JavaFX也支持在上下文中进行增量式求值,详见下面的章节)构成:  
       
            var chris = Person {
                    name: "Chris"
                    children:
                    [Person {
                            name: "Dee"
                    },
                    Person {
                            name: "Candice"
                    }]
            };
                            [/code]
        JavaFX也支持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
                            [/code]
        JavaFX允许在对象中声明本地变量。这些变量只在对象本身的范围内可见。另外,一个引用被初始化对象的变量可以通过
    1. var
    复制代码
    关键字声明为假属性(pseudo-attribute),就如下例中的child1和child2一样:  
       
            var chris = Person {
                    var: me
                    name: "Chris"
                    var child1 = Person {
                            name: "Dee"
                            parent: me
                    }
                    var child2 = Person { name: "Candice" }
                    children: [child1, child2]
            };
                            [/code]
       top
       更新触发器
        JavaFX类没有构造器,其属性也没有“setter”。作为替代物,JavaFX提供了类似SQL的触发器(
    1. trigger
    复制代码
    )来为使用者提供处理数据修改事件的能力。  
       触发器使用
    1. trigger
    复制代码
    关键字声明。  
        触发器由头部和代码体构成。头部说明了触发器应用的事件类型。代码体则是在特定事件发生时执行的过程。在代码体中你可以使用任何在操作体中有效的语句。与成员函数/操作类似,在触发器中在代码体内的上下文对象可以通过
    1. this
    复制代码
    关键字访问。  
       top
       创建触发器
        你可以在一个新建对象的上下文中声明一个创建触发器:  
       
            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
                            [/code]
        上面的示例中定义了一个在
    1. X
    复制代码
    类的实例被创建时执行的触发器。此触发器完成了对
    1. nums
    复制代码
    属性的初始赋值。  
       
      top
      插入触发器
       当一个成员被插入到多值属性时,我们可以定义一个插入触发器:  
      
            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
                        [/code]
       以上示例代码中,“num”是引用被插入成员的变量(你可以按照自己喜好命名它)。此变量的上下文索引(由
    1. indexof
    复制代码
    操作符返回)与插入点一致。  
      top
      删除触发器
       当一个成员从多值属性中被删除时,我们可以定义一个删除触发器:  
      
            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
                        [/code]
       以上示例代码中,“num”是引用被删除成员的变量(你可以按照自己喜好命名它)。此变量的上下文索引(由
    1. indexof
    复制代码
    操作符返回)与删除点一致。  
       
      top
      替换触发器
       当一个单值的属性值或者多值属性的成员被替换时,我们可以定义一个替换触发器:  
      
            import java.lang.System;
            class X {
                    attribute nums: Number*;
                    attribute num: Number?;
            }
           
            trigger on X.nums[oldValue] = newValue {
                    System.out.println("just replaced {oldValue} with {newValue} at position {indexof newValue} in X.nums");
            }
           
            trigger on X.num[oldValue] = newValue {
                    System.out.println("X.num: just replaced {oldValue} with {newValue}");
            }
           
            var x = X {
                    nums: [12, 13]
                    num: 100
            };
            x.nums[1] = 5; // prints just replaced 13 with 5 at position 1 in X.nums
            x.num = 3; // prints X.num: just replaced 100 with 3
            x.num = null;  // prints X.num: just replaced 3 with null
                        [/code]
       以上示例代码中,“oldValue”和“newValue”是两个变量,它们分别表示对被替换成员的旧值和替换后的新值的引用(你可以按照自己喜好命名)。变量的上下文索引(由
    1. indexof
    复制代码
    操作符返回)与被替换成员的顺序位置一致。  
      top
      增量式求值和懒惰求值
       在JavaFX中,属性初始化程序能够使用bind操作符进行懒惰、增量式求值。使用
    1. bind
    复制代码
    初始化的属性类似于包含公式的电子表格中的单元格。在包含此属性的对象的生命周期中,只要在初始化表达式右侧引用的任何对象发生改变,其左侧的对象属性将被自动更新。示例如下:  
      
            import java.lang.System;
            class X {
                    attribute a: Number;
                    attribute b: Number;
                    attribute c: Number;
            }
           
            trigger on X.b = newValue {
                    System.out.println("X.b is now {newValue}");
            }
           
            trigger on X.c = newValue {
                    System.out.println("X.c is now {newValue}");
            }
           
            var x1 = X {
                    a: 1
                    b: 2   // X.b is now 2 is printed
                    c: 3   // X.c is now 3 is printed
            };
           
            var x2 = X {
                    a:  x1.a       // eager, non-incremental
                    b:  bind x1.b // eager, incremental (X.b is now 2 is printed)
                    c:  bind lazy x1.c  // lazy, incremental (nothing is printed yet)
            };
            System.out.println(x2.a); // prints 1
            System.out.println(x2.b); // prints 2
            System.out.println(x2.c); // prints X.c is now 3, then prints 3
           
            x1.a = 5;
            x1.b = 5; // prints X.b is now 5, twice
            x1.c = 5; // prints X.c is now 5, twice
           
            System.out.println(x2.a); // prints 1
            System.out.println(x2.b); // prints 5
            System.out.println(x2.c); // prints 5
                        [/code]
       上例中,x2的属性b和c被绑定到x1的属性b和c。这意味着当x1的b或c属性被更新时,x2的b或c属性都会相应地被更新。在x2中的b、c属性之间的不同是:前者的属性值在其属性初始化程序中被立即更新,而后者的绑定直到其值被访问时才被求值。  
       注意:函数体无需
    1. bind
    复制代码
    操作符便可被增量地求值,但操作体则做不到。在改变本地变量的操作中并不触发增量式求值。增量式求值不能在操作体内执行,除了表达式明确地以
    1. bind
    复制代码
    作为前缀。  
       然而,当你在一个增量式求值上下文中调用操作或者Java方法,此调用本身将被增量式求值。这意味着如果此调用变成了对操作或者Java方法的全新调用(由于此调用被增量式求值),那么它所用到的任何参数值将被使用并返回新值。  
       译者注:此处的新值是与不进行增量式求值相比。  
       相反,在增量式求值上下文中调用函数,此函数只能被调用一次,而其求值结果也将被合并到调用求值树中。  
       增量式求值是JavaFX的主要特征,它使定义复杂的动态GUI声明成为了可能。懒惰求值的特性常用在处理像tree或者graph这样的递归数据结构上。  
      top
      反射
       JavaFX类、属性、操作可以通过如下方式反射:  
      
            public class Class {
                    public attribute Name: String;
                    public attribute Documentation:String?;
                    public attribute Superclasses: Class* inverse Class.Subclasses;
                    public attribute Subclasses: Class* inverse Class.Superclasses;
                    public attribute Attributes: Attribute* inverse Attribute.Scope;
                    public attribute Operations: Operation* inverse Operation.Target;
                    public function instantiate();
            }
            public class Operation extends Class {
                    public attribute Target: Class? inverse Class.Operations;
            }
            public class Attribute {
                    public attribute Name: String;
                    public attribute Documentation: String?;
                    public attribute Scope: Class? inverse Class.Attributes;
                    public attribute Type: Class?;
                    public attribute Inverse: Attribute* inverse Attribute.Inverse;
                    public attribute OneToOne: Boolean;
                    public attribute ManyToOne: Boolean;
                    public attribute OneToMany: Boolean;
                    public attribute ManyToMany: Boolean;
                    public attribute Optional: Boolean;
            }
                        [/code]
       JavaFX支持通过
    1. class
    复制代码
    操作符对类、属性、成员函数和操作的进行反射访问:  
      
            import java.lang.System;
            System.out.println(1.class.Name) // prints "Number"
            System.out.println("Hello".class.Name); // prints "String"
            class X {
                    attribute a: Number;
            }
            var x = new X();
            System.out.println(x.class.Name); // prints "X"
            System.out.println(sizeof x.class.Attributes); // prints 1
            System.out.println(x.class.Attributes[0].Name); // prints "a"
                        [/code]
       对属性值进行反射访问时,如果访问操作数是属性,则使用
    1. []
    复制代码
    操作符:  
      
            import java.lang.System;
            class X {
                    attribute a: Number;
            }
            var x = new X();
            x.a = 2;
            System.out.println(x[x.class.Attributes[Name == "a"]]); // prints 2
            // the above statement is equivalent to this non-reflective code:
            System.out.println(x.a);
                        [/code]
       在JavaFX中,类的成员函数和操作本身被模式化作为在目标类中的类,而形参和返回值被表示为属性。代表目标对象的属性名是“this”。代表返回值的属性名为“return”。代表形参的属性具有和形参相同的属性名。  
       译者注:这里的目标类是指使用成员函数和操作的类。而目标对象则指使用成员函数和操作的对象。  
       从上例中可以发现,你也可以从
    1. Class
    复制代码
    对象中获取相同的、被反射的操作。  
       被反射的操作能够像函数那样通过将目标对象作为第一个参数、其它参数作为后面的参数的方式被调用:  
      
            import java.lang.System;
            class X {
                    operation foo(n: Number): Number;
            }
            var x = new X();
            var op = x.class.Operations[Name == "foo"];
            System.out.println(op(x, 100));
            // the above code is equivalent to the following non-reflective code:
            System.out.println(x.foo(100));
                        [/code]
       bean属性和Java类的公共字段被反射为JavaFX属性。但是,Java方法不能被反射为JavaFX操作。如果你想调用某个Java方法,那么你可以通过简单地使用Java API来实现。  
       注意:与Java不同的:在JavaFX中
    1. class
    复制代码
    操作符被用于表达式,而不是用于类型名(type name)。因此作为补充,JavaFX支持从类型名中获取反射类对象的语法:  
      
            :TypeName
                        [/code]
       For example:  
      
            import java.lang.System;
            System.out.println(:System.Name); // prints "java.lang.System"
            System.out.println(:System.class.Name); // prints "Class"
                        [/code]
      top
      广度(Extents)和枚举
       类的“广度”,即此类的所有实例的集合,能够通过以下语法获得:  
      
            *:ClassName
                        [/code]
       例如,下面的代码打印出
    1. String
    复制代码
    类的所有实例:  
      
            import java.lang.System;
            for (i in *:String) {
                    System.out.println(i);
            }
                        [/code]
      注意:这是可选特性,默认情况下是失效的。
       JavaFX也提供了声明类的命名实例的能力:
      
            objectName:ClassName
                        [/code]
       例如:  
      
            import java.lang.System;
            myString:String = "This is a string";
            System.out.println(myString:String);
                        [/code]
       这样的命名实例是全局可访问的,但通常必须使用类名进行限制。然而,在属性初始化程序和赋值的上下文中,表达式类型的命名实例被引入到了词法作用域(lexical scope)(可见性弱于变量和属性),并可以通过使用它们的无限定名(unqualified names)引用这些命名实例:  
      
            Button {
                    mnemonic: P
                    text: "Press Me"
            }[/code]
       在上面实例中,由于
    1. Button
    复制代码
    1. mnemonic
    复制代码
    属性是
    1. KeyStroke
    复制代码
    类型的,因此我能够通过使用它的无限定名访问其命名值
    1. P
    复制代码
    ,而在别处我将不得不使用
    1. P:KeyStroke
    复制代码
    来引用它。  
       JavaFX使用与Java1.5同样的语法来访问枚举类型值:  
      
            import java.lang.management.MemoryType;
            var heap = HEAP:MemoryType;
            var nonHeap = NON_HEAP:MemoryType;
                        [/code]
      top
      相关资源
       
       openJavaFX官方网站
       openJavaFX FAQ
       Functional programming
       什么是第一级函数
       FOLDC对list comprehension的解释
       XPath教材
       使用JXPath查询Java对象
       XQuery简介
       
      top
      关于译者
      cleverpig:BJUG成员,Java社区――Matrix与Java共舞负责人之一,曾参与Buffalo的文档工作、Fielding的《Architectural Styles and the Design of Network-based Software Architectures》中文化研究(还要感谢Tin、Nicholas的大力相助),关注一切新技术,业余时间研究Guru并准备得道升天,但是苦于没有得法,目前还在苦苦追寻……  
      Tin:中文名“田乐”,BJUG成员,现就职于Sina。曾经在Java Web项目中担任软件架构师和Web设计,注重使用轻量级解决方案和敏捷方法。目前主要做基于Javascript的RIA开发,喜欢研究新技术并进行思考,业余时间继续关注Java和Ruby,并与朋友一起翻译Selenium文档。  
      top
      译文Feedback
      欢迎一切友人的Feedback!!
      cleverpig@matrix.org.cn
      top
      



      
      
       
       

         
       

         
       
      
    复制代码
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-6-19 14:28 , Processed in 0.511788 second(s), 50 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表