自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用JavaFX編寫用戶界面控制器

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

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

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

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

按照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];  

類托架外面定義的函數(shù)和變量相當(dāng)于Java靜態(tài)分析。

這里我們省略了一些不相關(guān)的實際項目?;旧?,該模式暴露了三個屬性,其中有意思的兩個分別是displayName和scientificName。我們也可以定義兩個函數(shù)來處理這兩個問題,我們會把這些函數(shù)放在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獲取了一個觸發(fā)事件,也就是變量值更改時所執(zhí)行的代碼。觸發(fā)器用JavaFX運算符 ︳執(zhí)行了過濾操作:我們可以將觸發(fā)事件的第一行當(dāng)作分配到taxons序列中的filteredTaxons來讀取,在這一序列中,matches()函數(shù)返回值為true。第二行的代碼調(diào)用了接下來要介紹的update()函數(shù)。

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

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

創(chuàng)建獲得屬性值函數(shù)的序列的一大好處是我們可以通過定義新的函數(shù)輕松添加新的匹配標準:例如,其他語言中的本地化名稱??刂破骺赡軙褂迷谒阉鬟^程中使用這些名稱,而我們則不需要再做多余修改。

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

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

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

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

另一個有意思的地方是findMatchPropertyGetter()。它必須猜測當(dāng)前過濾器是否是以"英語"或"科學(xué)"名稱運行,而且它還會返回相關(guān)的屬性獲取函數(shù)。基本上,控制器已經(jīng)獲取了matches()函數(shù)中的這一信息,但是我們會將其移走??赡軙腥怂伎甲宮atches()函數(shù)返回一個以上的布林值,但是這是不可能的,因為它是由運算符 ︳過濾序列的時候使用的:該運算符需要一個布林值?;蛟S我們可以為稍后調(diào)用信息的操作指定一個成員變量,不過此時的代碼應(yīng)該會更具可讀性。

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

  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.   } 

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

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

  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與過濾器是雙重指令型綁定。之所以需要雙重綁定是因為向搜索欄中輸入時,一個指令用于給控制器發(fā)出新的選擇命令,另一個則是自動完成輸入時的更新。

 

【編輯推薦】

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

2011-07-14 10:28:54

額外域控制器

2011-06-21 13:57:43

2023-08-13 18:31:45

SDN控制器

2015-08-07 15:28:46

選取城市控制器源碼

2015-02-02 09:37:42

SDN控制器

2011-08-02 18:40:14

域控制器

2011-07-12 09:29:10

主域控制器備份域控制器

2024-09-27 16:28:07

2015-10-20 14:52:50

Steam控制器Ubuntu

2011-08-01 16:59:27

活動目錄域控制器

2019-11-17 22:58:03

Spring MVC控制器編寫

2009-01-12 11:16:58

控制器控制器行為行為結(jié)果

2013-12-19 09:32:01

SDN南向網(wǎng)絡(luò)控制

2017-11-23 17:27:35

Yii框架IntelYii框架深度剖析

2015-02-27 10:52:17

SDN

2011-07-18 13:55:08

2011-07-13 10:29:44

域控制器

2012-02-24 10:57:43

2011-07-07 15:01:02

2013-06-08 09:50:30

SDN控制器應(yīng)用OpenFlow軟件定義網(wǎng)絡(luò)
點贊
收藏

51CTO技術(shù)棧公眾號