成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用JavaFX編寫用戶界面控制器

開發 后端
本文向您介紹使用JavaFX編寫用戶界面控制器的相關知識,通過實例來闡述要介紹的技巧和典型JavaFX結構的陷阱。

在本文中,我們關心的是BlueBill Mobile類,尤其是管理所有Search Species屏幕之后邏輯的控制器;因此本文有助于你了解JavaFX的語言性能。而且我們會舉出一些實例來闡述要介紹的技巧和典型JavaFX結構的陷阱。

筆者想應用程序中嵌入了更新的屏播。視頻播放要求使用QucikTime。

這里的概念是在搜索框中鍵入查詢時,英文函數或科學名稱函數會對清單過濾。此外,當這些生效的時候,BlueBill Mobile還可以執行自動完成輸入。例如,如果在鍵入查詢的時候你仔細查看視頻會發現只輸入了"a-r-d-a-c"來選擇"Ardea Cinerea";或用于"Pied Avocet"的"p-i-e-< space>-a"。BlueBill Mobile 會自動會剩余部分進行補充因為在某些情況下,不存在其他選擇。這是用來改善移動設備性能的重要功能:你可以以較少的輸入達到相同目的。

按照MVC模式,就非常有必要在單獨的控制器中概括這種模式;此外,也很容易對這種模式進行單元測試。

首先,讓我們看一下代表了分類群的模式類:

  1. package it.tidalwave.bluebillmfx.taxon.model;   
  2.   import java.lang.Comparable;  
  3.  
  4.   public class Taxon extends Comparable  
  5.  
  6.   {  
  7.  
  8.   public-read protected var displayName : String;  
  9.  
  10.   public-read protected var scientificName : String;  
  11.  
  12.   public-read protected var id : String;  
  13.  
  14.   override function compareTo (other : Object)  
  15.  
  16.   {  
  17.  
  18.   return displayName.compareTo((other as Taxon).displayName);  
  19.  
  20.   }  
  21.  
  22.   override function toString()  
  23.  
  24.   {  
  25.  
  26.   return "{displayName} ({scientificName}) ({id})" 
  27.  
  28.   }  
  29.  
  30.   }  
  31.  
  32.   public function displayNameGetter (taxon : Taxon): String  
  33.  
  34.   {  
  35.  
  36.   return taxon.displayName;  
  37.  
  38.   }  
  39.  
  40.   public function scientificNameGetter (taxon : Taxon): String  
  41.  
  42.   {  
  43.  
  44.   return taxon.scientificName;  
  45.  
  46.   }  
  47.  
  48.   public def namePropertyGetters = [displayNameGetter, scientificNameGetter];  

類托架外面定義的函數和變量相當于Java靜態分析。

這里我們省略了一些不相關的實際項目。基本上,該模式暴露了三個屬性,其中有意思的兩個分別是displayName和scientificName。我們也可以定義兩個函數來處理這兩個問題,我們會把這些函數放在namePropertyGetters序列中。

  1.   package it.tidalwave.bluebillmfx.taxon.controller;   
  2.   import it.tidalwave.bluebillmfx.taxon.model.Taxon;  
  3.  
  4.   public class TaxonSearchController  
  5.  
  6.   {  
  7.  
  8.   public var selectedTaxon = bind if (selectedTaxonIndex < 0) then null else filteredTaxons[selectedTaxonIndex];  
  9.  
  10.   public var selectedTaxonIndex : Integer = -1;  
  11.  
  12.   public var taxons: Taxon[];  
  13.  
  14.   public var filter = "" on replace  
  15.  
  16.   {  
  17.  
  18.   filteredTaxons = taxons[taxon | matches(taxon, filter)];  
  19.  
  20.   update();  
  21.  
  22.   }  
  23.  
  24.   public-read var autoCompleted = "";  
  25.  
  26.   public var filteredTaxons: Taxon[];  
  27.  
  28.   protected function matches (taxon : Taxon, string: String) : Boolean  
  29.  
  30.   {  
  31.  
  32.   if (string == "")  
  33.  
  34.   {  
  35.  
  36.   return true;  
  37.  
  38.   }  
  39.  
  40.   for (propertyGetter in Taxon.namePropertyGetters)  
  41.  
  42.   {  
  43.  
  44.   if (propertyGetter(taxon).toLowerCase().startsWith(filter.toLowerCase()))  
  45.  
  46.   {  
  47.  
  48.   return true;  
  49.  
  50.   }  
  51.  
  52.   }  
  53.  
  54.   return false;  
  55.  
  56.   }  
  57.  
  58.   protected function update(): Void  
  59.  
  60.   {  
  61.  
  62.   def autoCompletedTry = commonLeadingSubstring(filteredTaxons, findMatchingPropertyGetter());  
  63.  
  64.   //  
  65.  
  66.   // Sometimes it can't find a better auto-completion than the current filter, since it searches the displayName  
  67.  
  68.   // and the scientificName at the same time. In this case, we just ignore the new value.  
  69.  
  70.   //  
  71.  
  72.   if (autoCompletedTry.length() > filter.length())  
  73.  
  74.   {  
  75.  
  76.   autoCompleted = autoCompletedTry;  
  77.  
  78.   }  
  79.  
  80.   selectedTaxonIndex = if (sizeof filteredTaxons == 1) then 0 else -1;  
  81.  
  82.   println("selectedTaxonIndex: {selectedTaxonIndex}")  
  83.  
  84.   }  
  85.  
  86.   protected function findMatchingPropertyGetter(): function (:Taxon): String  
  87.  
  88.   {  
  89.  
  90.   for (taxon in filteredTaxons)  
  91.  
  92.   {  
  93.  
  94.   for (propertyGetter in Taxon.namePropertyGetters)  
  95.  
  96.   {  
  97.  
  98.   if (propertyGetter(taxon).toLowerCase().startsWith(filter.toLowerCase()))  
  99.  
  100.   {  
  101.  
  102.   return propertyGetter;  
  103.  
  104.   }  
  105.  
  106.   }  
  107.  
  108.   }  
  109.  
  110.   return null;  
  111.  
  112.   }  
  113.  
  114.   // some stuff later  
  115.  
  116.   }  

這個類揭示了以下的屬性:

◆taxons:你需要用完整的鳥類列表來填充

◆filter: 字符串包括需要輸入到搜索欄中的文本

◆filteredTaxons: 種類由filter字符串過濾

◆autoCompleted: 控制器猜測的自動完成輸入字符串

◆selectedTaxon: 如果filter向下細分種類,它就會分配到這個變量

◆selectedTaxonIndex: -1如果無法獲取時,selectedTaxon的索引。

最新的四種屬性由客戶代碼來綁定,這樣做可以獲取更改提示。#p#

Filter獲取了一個觸發事件,也就是變量值更改時所執行的代碼。觸發器用JavaFX運算符 ︳執行了過濾操作:我們可以將觸發事件的第一行當作分配到taxons序列中的filteredTaxons來讀取,在這一序列中,matches()函數返回值為true。第二行的代碼調用了接下來要介紹的update()函數。

出于某些原因,這種方法并不一定奏效,因為filteredTaxons通常會被整體掃描。有多種方法可用來加速選擇過程,但是本文不會在這一方法真正應用到手機前前作出過早的優化。在筆記本上,它可以加快1000個項目的速度。

Matches()函數在所有屬性上執行了一次迭代以獲取函數并檢查看相關屬性是否以過濾值啟動。

創建獲得屬性值函數的序列的一大好處是我們可以通過定義新的函數輕松添加新的匹配標準:例如,其他語言中的本地化名稱。控制器可能會使用在搜索過程中使用這些名稱,而我們則不需要再做多余修改。

Update()函數運算出了自動完成輸入提示。它會提取filteredTaxons序列以及用于當前選擇的獲取屬性函數,還會調用剛剛在字符串屬性的序列中找到了通用子字符串的commonLeadingSubstring()。它不是每次都會作出很好的自動完成輸入猜想,因此有時建議甚至比當前過濾器還短,而這種情況我們大可忽略不計。請不要忽視指定臨時變量的重要性:由于自動完成輸入可能被綁定,因此我們不想為其指定一個會迅速失效的值。

要明白這一點的重要性,這不僅僅是避免無用更新,還能避免程序被破壞。在實際程序中,自動完成輸入更改時,TextBox會更新,因此過濾器也會隨之更新:已經輸入了"cal"后,再輸入一個"i",那么TextBox暫時會顯示"cali",然后自動輸入完成的猜測失敗,它會返回一個"cal",TextBox中的字符串會變為"cal":這時候你要堅持自己的想法!綁定確實很強大,但是它也同時具有負面效應。

最后一步操作中,代碼會檢查看我們是否獲取單獨的已選定鳥類。

或許,你對于自動完成輸入失敗的原因仍然感到很困惑。畢竟,我們正在逐步縮小項目列表。因此,如果你已經輸入了"cali",那么所有經過過濾的種類會以"cali"開頭,對嗎?如果你過濾的是一套單一名稱,情況就應該是這樣;但是我們是同時對兩套名稱執行搜索,那么就會產生矛盾。看看下例由"cali"過濾器選取的名稱組(英語,科學的):("Calandra Lark", "Melanocorypha calandra"), ("Dunlin", "Calidris alpina"), ("California Quail", "Callipepla californica")

另一個有意思的地方是findMatchPropertyGetter()。它必須猜測當前過濾器是否是以"英語"或"科學"名稱運行,而且它還會返回相關的屬性獲取函數。基本上,控制器已經獲取了matches()函數中的這一信息,但是我們會將其移走。可能會有人思考讓matches()函數返回一個以上的布林值,但是這是不可能的,因為它是由運算符 ︳過濾序列的時候使用的:該運算符需要一個布林值。或許我們可以為稍后調用信息的操作指定一個成員變量,不過此時的代碼應該會更具可讀性。

為了對文章進一步作補充說明,這里給大家列出了最后兩個忽略的函數:

  1. protected function commonLeadingSubstring (taxons: Taxon[], propertyGetter: function (:Taxon): String): String   
  2.   {  
  3.  
  4.   if (sizeof taxons == 0)  
  5.  
  6.   {  
  7.  
  8.   return "";  
  9.  
  10.   }  
  11.  
  12.   if (sizeof taxons == 1)  
  13.  
  14.   {  
  15.  
  16.   return propertyGetter(taxons[0]);  
  17.  
  18.   }  
  19.  
  20.   var common = propertyGetter(taxons[0]);  
  21.  
  22.   for (other in taxons[1..])  
  23.  
  24.   {  
  25.  
  26.   common = commonLeadingSubstring(common, propertyGetter(other));  
  27.  
  28.   if (common == "")  
  29.  
  30.   {  
  31.  
  32.   break// don't waste time in further iterations, "" it's for sure the final result  
  33.  
  34.   }  
  35.  
  36.   }  
  37.  
  38.   return root;  
  39.  
  40.   }  
  41.  
  42.   function commonLeadingSubstring (string1 : String, string2 : String): String  
  43.  
  44.   {  
  45.  
  46.   return if (string1.length() > string2.length())  
  47.  
  48.   {  
  49.  
  50.   commonLeadingSubstring(string2, string1);  
  51.  
  52.   }  
  53.  
  54.   else if (string1 == "")  
  55.  
  56.   {  
  57.  
  58.   "";  
  59.  
  60.   }  
  61.  
  62.   else if (string2.startsWith(string1))  
  63.  
  64.   {  
  65.  
  66.   string1;  
  67.  
  68.   }  
  69.  
  70.   else 
  71.  
  72.   {  
  73.  
  74.   commonLeadingSubstring(string1.substring(0, string1.length() - 1), string2);  
  75.  
  76.   }  
  77.  
  78.   } 

這里的邏輯很簡單。通常主要的字符串搜索被分解成了臨近字符串對;而對于單一對的搜索則有遞歸執行。

這里顯示了視圖類是如何綁定到控制器的:

  1. package it.tidalwave.bluebillmfx.taxon.view;   
  2.   public class TaxonSearchScreen  
  3.  
  4.   {  
  5.  
  6.   public var taxons : Taxon[];  
  7.  
  8.   var filter = "";  
  9.  
  10.   public-read def controller = TaxonSearchController  
  11.  
  12.   {  
  13.  
  14.   taxons: bind taxons  
  15.  
  16.   filter: bind filter  
  17.  
  18.   }  
  19.  
  20.   def autoCompleted = bind controller.autoCompleted on replace  
  21.  
  22.   {  
  23.  
  24.   if (autoCompleted != "")  
  25.  
  26.   {  
  27.  
  28.   filter = autoCompleted;  
  29.  
  30.   }  
  31.  
  32.   }  
  33.  
  34.   def list = ListBox  
  35.  
  36.   {  
  37.  
  38.   items: bind controller.filteredTaxons  
  39.  
  40.   };  
  41.  
  42.   def searchBox = TextBox  
  43.  
  44.   {  
  45.  
  46.   text: bind filter with inverse  
  47.  
  48.   };  
  49.  
  50.   } 

你必須用所有可得的種類加載taxon;ListBox會隨著過濾的種類自動更新,TextBox與過濾器是雙重指令型綁定。之所以需要雙重綁定是因為向搜索欄中輸入時,一個指令用于給控制器發出新的選擇命令,另一個則是自動完成輸入時的更新。

 

【編輯推薦】

  1. JavaFX 1.2中的三大重要特性
  2. Silverlight、JavaFX、Flex技術比較
  3. JavaFX和Java之間的互操作性
  4. JavaFX對Java開發者到底意味著什么
  5. RIA之爭 JavaFX是否能后來居上?
責任編輯:佚名 來源: IT專家網
相關推薦

2011-07-14 10:28:54

額外域控制器

2015-08-07 15:28:46

選取城市控制器源碼

2023-08-13 18:31:45

SDN控制器

2011-06-21 13:57:43

2011-08-02 18:40:14

域控制器

2011-07-12 09:29:10

主域控制器備份域控制器

2015-02-02 09:37:42

SDN控制器

2024-09-27 16:28:07

2011-08-01 16:59:27

活動目錄域控制器

2015-10-20 14:52:50

Steam控制器Ubuntu

2009-01-12 11:16:58

控制器控制器行為行為結果

2019-11-17 22:58:03

Spring MVC控制器編寫

2013-12-19 09:32:01

SDN南向網絡控制

2015-07-20 11:34:06

2013-06-08 09:50:30

SDN控制器應用OpenFlow軟件定義網絡

2011-07-07 17:15:52

2015-05-26 10:16:27

SDNSDN控制器

2013-12-06 15:18:18

2015-07-14 11:09:26

SDN

2021-11-25 14:44:51

Kubernetes復制控制器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 999久久久 | 国产精品久久久久久久久久久久久久 | 成人精品一区亚洲午夜久久久 | 欧美视频xxx | 欧美爱爱视频 | 综合网伊人| 一区二区久久电影 | 一级黄片一级毛片 | 精品99爱视频在线观看 | 一级午夜aaa免费看三区 | 国产免费一区二区 | 成人久久 | 亚洲精品2| 久久精品国产一区二区电影 | 蜜桃视频一区二区三区 | 欧美中文字幕一区二区三区亚洲 | www.色五月.com | 天堂网avav| 国产精品国产a级 | 国产欧美一区二区三区日本久久久 | 久久一二 | 中文字幕在线观看av | 伊人狼人影院 | 亚洲www.| 国产一二三视频在线观看 | 国产精品视频一二三区 | 日韩欧美高清dvd碟片 | 青青草一区 | 欧美视频成人 | 精品国产色 | 91看片网| 欧美日韩国产在线观看 | 午夜精品久久久久久久久久久久久 | 日韩欧美中文 | 天天躁日日躁性色aⅴ电影 免费在线观看成年人视频 国产欧美精品 | 成人精品鲁一区一区二区 | 黄色毛片在线播放 | 91黄色免费看| 亚洲国产精品成人 | 99久久精品国产一区二区三区 | 日韩欧美高清 |