asdtiang的博客 感謝blogjava提供的博客交流平臺

          JAVA FX語法學習----數據綁定和觸發器

          Posted on 2010-01-15 14:35 asdtiang 閱讀(1124) 評論(0)  編輯  收藏 所屬分類: java fx學習筆記

          bind 關鍵字將目標變量的值與綁定表達式的值相關聯。綁定表達式可以是某個基本類型的簡單值、對象、函數的結果或表達式的結果。以下幾節分別提供每種綁定表達式 的示例。

          在大多數實際的編程情況下,需要通過數據綁定使應用程序的圖形用戶界面 (Graphical User Interface, GUI) 與其底層數據同步。(GUI 編程是使用 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
           

          請注意,我們已將變量 y 聲明為 def。這可防止任何代碼直接 為該變量賦值(盡管允許該變量的值因綁定 (bind) 而更改)。在綁定到對象時,此約定仍適用(請回顧使 用對象中介紹的 Address):

          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 對象,請改為直接綁定 (bind) 到該對象的實例變量:

          def address = bind Address {

          street: bind myStreet;

          city: bind myCity;

          state: bind myState;

          zip: bind myZip;

          };
           

          如果要顯式綁定到實例變量,還可以省略第一個 bindAddress 前面的那個):

          def address = Address {

          street: bind myStreet;

          city: bind myCity;

          state: bind myState;

          zip: bind myZip;

          };
           

          前面的課程已講授了函數,但是您還必須了解綁定函數非綁定函數之間的區別。

          請考慮下面的函數,該函數創建和返回一個 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 關鍵字。


          注意: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);
           

          將腳本變量 myXmyY 初始化為 3.0。 這些值隨后作為參數傳遞給 makePoint 函數,該函數會創建并返回一個新的 Point 對象。bind 關鍵字(位于 makePoint 調用前面)將新創建的 Point 對象 (pt) 綁定到 makePoint 函數的結果。

          接下來,代碼:

          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 關鍵字(從而使其成為非綁定函數),則輸出應為:

          3.0

          10.0

          10.0
           

          這是因為,非綁定函數只是在其某個參數發生變化時才被重新調用。由于 scale 不是函數的參數,因此更改它的值將不會導致另一個函數調用。

          您還可以將 bindfor 表達式結合使用。為了對此進行研究,讓我們首先定義兩個序列并輸出這兩個序列中各個項的值:

          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 包含十個項(數字 1 至 10)。seq2 也包含十個項;這些項本來會與 seq1 具有相同的值,但是我們已經對其中的每個項都應用了表達式 item*2, 因此它們的值將加倍。

          因此,輸出為:

          First Sequence:

          1

          2

          3

          4

          5

          6

          7

          8

          9

          10

          Second Sequence:

          2

          4

          6

          8

          10

          12

          14

          16

          18

          20
           

          我們可以通過將 bind 關鍵字放在 for 關鍵字前面來綁定這兩個序列。

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

          問題現在變成:“如果 seq1 發生了某些變化,那么是 seq2 中的所有項都受到影響還是部分項受到影響?”我們可以通過以下方法來對此進行測試:將一個項(值 11)插入 seq1 的末尾處,然后輸出這兩個序列的值,看有什么變化:

          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);}

          }
           

          輸出:

          First Sequence:

          1

          2

          3

          4

          5

          6

          7

          8

          9

          10

          11

          Second Sequence:

          2

          4

          6

          8

          10

          12

          14

          16

          18

          20

          22
           

          輸出表明,將 11 插入 seq1 的末尾處不會影響 seq2 中的前 10 個項;新項會自動添加到 seq2 的末尾處,其值為 22。

          替換觸發器是附加到變量的任意代碼塊,一旦變量的值發生變化,它們就會執行。以下示例顯示了基本語法: 它定義一個 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 變量命名為任何所需的名稱,我們是由于該名稱具有描述性才恰好使用它。



          天蒼蒼,野茫茫,風吹草底見牛羊

          posts - 80, comments - 24, trackbacks - 0, articles - 32

          Copyright © asdtiang

          asdtiang的博客 PaidMailz
          點擊廣告網賺A(每天4個廣告,每個0.0025美元,一個搜索廣告0.03美元)
          主站蜘蛛池模板: 长葛市| 绿春县| 合川市| 梅河口市| 盐池县| 泰安市| 大邑县| 沙田区| 怀远县| 溧阳市| 武穴市| 星子县| 广东省| 台北市| 通海县| 永州市| 岑巩县| 三原县| 湖南省| 绥中县| 旌德县| 阿克陶县| 岑巩县| 开化县| 永寿县| 安乡县| 邵阳县| 梅河口市| 武功县| 灵石县| 罗定市| 密云县| 武夷山市| 合作市| 稷山县| 兴安盟| 阜新市| 新建县| 灌南县| 乳山市| 武义县|