利用JavaFX工具構(gòu)建Reactive系統(tǒng)
JavaFX 是Java中用來(lái)構(gòu)建圖形應(yīng)用程序的新的標(biāo)準(zhǔn)庫(kù), 但許多程序員仍然堅(jiān)持在使用Swing甚至AWT。關(guān)于如何利用JavaFX工具集中的新的超棒特性來(lái)構(gòu)建響應(yīng)式的快速應(yīng)用程序,這里有一些建議!
1. 屬性值
如果你對(duì)JavaFX組件做過(guò)完整的了解,移動(dòng)遇到過(guò)屬性(Property)這個(gè)東西。FX庫(kù)中幾乎每個(gè)值都可以被觀察,分區(qū)(divider)的寬度,圖片的尺寸,文本標(biāo)識(shí)(label)中的文字,一個(gè)列表中的子項(xiàng)以及復(fù)選框(checkbox)的狀態(tài)。屬性分成另類:可寫屬性和可讀屬性。可寫值可以被修改,使用設(shè)置器方法或者直接修改。 JavaFX 會(huì)處理事件處置過(guò)程并確保每個(gè)依賴于此屬性的組件都會(huì)被通知到??勺x屬性擁有能讓你在其值被修改時(shí)接收到通知的方法。
示例:
// 可讀-且可寫
StringProperty name = new SimpleStringProperty("Emil");
// 只讀
ObservableBooleanValue nameIsEmpty = name.isEmpty();
2. 綁定值
當(dāng)你擁有一個(gè)可寫和可讀值的時(shí)候,你可以開(kāi)始就這些值如何關(guān)聯(lián)定義規(guī)則。一個(gè)可寫屬性可以被綁定到一個(gè)可讀屬性,如此其值總是會(huì)匹配到可讀的這個(gè)。綁定并不會(huì)立即發(fā)生,不過(guò)它們會(huì)在值被觀察之前進(jìn)行(看看我在那里做的就明白了)。 綁定可以是單向或者雙向的。當(dāng)然,如果它們之間是雙向的,就需要兩個(gè)屬性都是可寫的。
示例:
TextField fieldA = new TextField(); TextField fieldB = new TextField(); fieldA.prefWidthProperty().bind(fieldB.widthProperty());
3. 可觀察的列表
屬性并不是唯一可以被觀察的東西。如果列表是被封裝到了一個(gè) ObservableList 中,那么列表的成員同樣也是可以被觀察到的。ObservableList 的響應(yīng)模型是相當(dāng)先進(jìn)的。你不僅能在列表被修改時(shí)收到通知,也可以看到列表具體是如何被修改的。
示例:
List<String> otherList = Arrays.asList("foo", "bar", "bar");
ObservableList<String> list = FXCollections.observableList(otherList);
list.addListener((ListChangeListener.Change<? extends String> change) -> {
System.out.println("Received event.");
while (change.next()) {
if (change.wasAdded()) {
System.out.println(
"Items " + change.getAddedSubList() + " was added.");
}
if (change.wasRemoved()) {
System.out.println(
"Items " + change.getRemoved() + " was removed.");
}
}
});
System.out.println("Old list: " + list);
list.set(1, "foo");
System.out.println("New list: " + list);
上面代碼的運(yùn)行輸出如下:
Old list: [foo, bar, bar] Received event. Items [foo] was added. Items [bar] was removed. New list: [foo, foo, bar]
如你所見(jiàn),設(shè)置操作只會(huì)觸發(fā)一次事件。
4. StringConverter
有時(shí)你會(huì)發(fā)現(xiàn)自己要?jiǎng)?chuàng)建一個(gè)綁定時(shí)無(wú)需去提取一個(gè)組件中的值。 這個(gè)的典型示例就是你有了一個(gè)從一個(gè)文本域(TextField)獲取到的帶有path 的 StringProperty。如果你想要有一個(gè)帶有表示為Path的這個(gè)值的可觀察屬性,就需要去為它創(chuàng)建一個(gè)StringConverter。
示例:
TextField fileLocation = new TextField();
StringProperty location = fileLocation.textProperty();
Property<Path> path = new SimpleObjectProperty<>();
Bindings.bindBidirectional(location, path, new StringConverter<Path>() {
@Override
public String toString(Path path) {
return path.toString();
}
@Override
public Path fromString(String string) {
return Paths.get(string);
}
});
對(duì)象屬性并不是跟文本域的值進(jìn)行的雙向綁定。
5. Expressions
使用上述的 Bindings類,你可以創(chuàng)建出任何類型的表達(dá)式。比如說(shuō)你有了兩個(gè)可以讓用戶輸入信息的文本域?,F(xiàn)在想要定義一個(gè)只讀域,其中總是會(huì)包含一個(gè)字符串,如果兩個(gè)串的長(zhǎng)度相等,將會(huì)是兩個(gè)串逐個(gè)字符間隔混在一起進(jìn)行顯示。如果長(zhǎng)度不等,則顯示一條幫助信息。
示例:
TextField first = new TextField();
TextField second = new TextField();
TextField mix = new TextField();
mix.textProperty().bind(
Bindings.when(
first.lengthProperty().isEqualTo(second.lengthProperty())
).then(Bindings.createStringBinding(
() -> {
int length = first.lengthProperty().get();
String firstText = first.textProperty().get();
String secondText = second.textProperty().get();
char[] result = new char[length * 2];
for (int i = 0; i < length; i++) {
result[i * 2] = firstText.charAt(i);
result[i * 2 + 1] = secondText.charAt(i);
}
return new String(result);
},
first.textProperty(),
second.textProperty()
)).otherwise("Please enter two strings of exactly the same length.")
);
這里只是JavaFX諸多特性的其中一點(diǎn)點(diǎn)。希望你可以找到更多利用這個(gè)事件系統(tǒng)的創(chuàng)造性方式!
相關(guān)文章
Springboot 全局時(shí)間格式化三種方式示例詳解
時(shí)間格式化在項(xiàng)目中使用頻率是非常高的,當(dāng)我們的 API? 接口返回結(jié)果,需要對(duì)其中某一個(gè) date? 字段屬性進(jìn)行特殊的格式化處理,通常會(huì)用到 SimpleDateFormat? 工具處理,這篇文章主要介紹了3 種 Springboot 全局時(shí)間格式化方式,需要的朋友可以參考下2024-01-01
SpringBoot整合Flink CDC實(shí)現(xiàn)實(shí)時(shí)追蹤mysql數(shù)據(jù)變動(dòng)
我們將整合Spring Boot和Apache Flink CDC(Change Data Capture)來(lái)實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)追蹤,下面是一個(gè)基本的實(shí)踐流程代碼,包括搭建Spring Boot項(xiàng)目、整合Flink CDC以及實(shí)現(xiàn)數(shù)據(jù)變動(dòng)的實(shí)時(shí)追蹤,需要的朋友可以參考下2024-07-07
springboot2.0整合logback日志的詳細(xì)代碼
這篇文章主要介紹了springboot2.0整合logback日志的應(yīng)用場(chǎng)景分析,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02
Java圖形化編程中的鍵盤事件設(shè)計(jì)簡(jiǎn)介
這篇文章主要介紹了Java圖形化編程中的鍵盤事件設(shè)計(jì),是Java的GUI編程當(dāng)中的基礎(chǔ)部分,需要的朋友可以參考下2015-10-10
Spring session實(shí)現(xiàn)共享單點(diǎn)登錄案例過(guò)程解析
這篇文章主要介紹了Spring session實(shí)現(xiàn)共享單點(diǎn)登錄案例過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
Java8 HashMap的實(shí)現(xiàn)原理分析
Java8之后新增挺多新東西,接下來(lái)通過(guò)本文給大家介紹Java8 HashMap的實(shí)現(xiàn)原理分析,對(duì)java8 hashmap實(shí)現(xiàn)原理相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-03-03
解決Request.getParameter獲取不到特殊字符bug問(wèn)題
這篇文章主要介紹了解決Request.getParameter獲取不到特殊字符bug問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
Java深度優(yōu)先遍歷解決排列組合問(wèn)題詳解
這篇文章主要介紹了Java深度優(yōu)先遍歷解決排列組合問(wèn)題詳解,深度優(yōu)先搜索是遞歸過(guò)程,帶有回退操作,因此需要使用棧存儲(chǔ)訪問(wèn)的路徑信息,當(dāng)訪問(wèn)到的當(dāng)前頂點(diǎn)沒(méi)有可以前進(jìn)的鄰接頂點(diǎn)時(shí),需要進(jìn)行出棧操作,將當(dāng)前位置回退至出棧元素位置,需要的朋友可以參考下2024-01-01

