Java界面設(shè)計(jì)應(yīng)該是一項(xiàng)充滿創(chuàng)造性、富有樂趣的工作,但是卻往往被認(rèn)為非常的枯燥和繁瑣。究其原因,是因?yàn)榻缑娌季诸I(lǐng)域所采用的描述概念和具體的實(shí)現(xiàn)語(yǔ)言之間存在很大的語(yǔ)義隔閡。而一般的界面開發(fā)工具提供的所見即所得以及界面布局管理器等方案也無法很好地解決這個(gè)問題。
在本文中,我們會(huì)給出一種更好的解決方案,我們不是去試圖把界面設(shè)計(jì)者頭腦中的設(shè)計(jì)概念和樣式逐步降級(jí)、分解成所使用的實(shí)現(xiàn)語(yǔ)言能夠理解的低層概念,也不是提供一些已經(jīng)完成的、確定的但難以擴(kuò)充和更改的布局樣式庫(kù)供界面設(shè)計(jì)者使用。我們所提供的是一種專門用于描述高層界面設(shè)計(jì)樣式的語(yǔ)言。通過這種語(yǔ)言,界面設(shè)計(jì)者可以直接、明確地描述出他們頭腦中的布局設(shè)計(jì)樣式;通過這種語(yǔ)言,界面設(shè)計(jì)者可以自己方便地、靈活地制定自己需要的布局樣式。此外,本文中給出的設(shè)計(jì)思想對(duì)于其他領(lǐng)域的設(shè)計(jì)也有很好的借鑒作用。
創(chuàng)造性,還是乏味?
界面設(shè)計(jì)是一項(xiàng)非常有創(chuàng)造性,甚至富有藝術(shù)性的工作,一個(gè)簡(jiǎn)潔、易用、漂亮的界面在帶給使用者方便的同時(shí),也會(huì)給界面設(shè)計(jì)者帶來極大的成就感。但是,在現(xiàn)實(shí)中,情況似乎并非如此,很多人都認(rèn)為做界面是一項(xiàng)非常繁瑣、機(jī)械、乏味的工作,并千方百計(jì)地去逃避界面相關(guān)的工作。這是為什么呢?
原因很簡(jiǎn)單,因?yàn)樽鼋缑嫫鋵?shí)涉及兩項(xiàng)工作,一項(xiàng)是界面的一些設(shè)計(jì)創(chuàng)意,包括界面的布局樣式以及和使用者的交互方式,這項(xiàng)工作充滿挑戰(zhàn)和樂趣。但是,這些設(shè)計(jì)創(chuàng)意最終是要落實(shí)到實(shí)現(xiàn)上的,這就是第二項(xiàng)工作。此時(shí),你頭腦中那些清晰、完整的設(shè)計(jì)概念開始變得瑣碎,你不得不和那些低層次的坐標(biāo)位置打交道。更糟糕的是,當(dāng)你好不容易做好了一個(gè)界面,但是發(fā)現(xiàn)其中某些元素的布局需要一些調(diào)整時(shí),這個(gè)你本應(yīng)認(rèn)為是一個(gè)很簡(jiǎn)單的改變卻造成大量重復(fù)的低層次坐標(biāo)位置更改時(shí),你肯定會(huì)認(rèn)為做界面是多么的機(jī)械和乏味呀!
其實(shí),造成這種認(rèn)識(shí)的根源在于界面設(shè)計(jì)創(chuàng)意和實(shí)現(xiàn)這些創(chuàng)意概念的語(yǔ)言之間存在很大的斷層。這樣,在具體實(shí)現(xiàn)時(shí),你就必須得把這些清晰、完整的布局樣式降級(jí)成一些瑣碎、沒有什么意義的低層次的坐標(biāo)值,使得實(shí)現(xiàn)語(yǔ)言能夠理解。這項(xiàng)工作不僅乏味,而且最終的實(shí)現(xiàn)也非常的脆弱 —— 一個(gè)在布局樣式層面非常簡(jiǎn)單的更改,就會(huì)造成實(shí)現(xiàn)層面的巨大變動(dòng)。比如:我們可以說把一組元素同時(shí)按比例縮小 10%,做過界面的朋友肯定知道這個(gè)更改意味著什么。
為了應(yīng)對(duì)這個(gè)斷層的問題,目前幾乎所有的涉及界面制作的開發(fā)工具都提供了相同的解決方法:可視化的界面設(shè)計(jì)工具以及布局管理器。但是這兩種方法都沒有從根本上解決這個(gè)問題。
可視化界面設(shè)計(jì)工具確實(shí)避免了不少繁瑣的界面元素?cái)[放工作,但是對(duì)于專業(yè)的界面設(shè)計(jì)來說,通過拖放設(shè)計(jì)出來的界面在準(zhǔn)確度和規(guī)范性上都有待提高,此外還有更為重要的一點(diǎn),那就是存在于設(shè)計(jì)者頭腦中的布局樣式仍然沒有被明確地描述出來,而是被降級(jí)成一個(gè)個(gè)擺放在一起的零散的組件,雖然這些組件本身是可視的。這個(gè)語(yǔ)義斷層的存在同樣會(huì)使得通過可視化界面設(shè)計(jì)工具設(shè)計(jì)出來的界面非常脆弱。
布局管理器試圖通過提供一些常用的布局樣式來解決這個(gè)問題。但是,這種做法非常僵化,也就是說你只能使用現(xiàn)有的布局管理器,如果它們無法滿足你的要求,你也無法自己定制。此外,這些布局管理器僅僅適合于一些簡(jiǎn)單的情況。對(duì)于一些復(fù)雜的布局樣式來說,它們的描述能力就顯得非常的不足。那些曾經(jīng)和 GridBagLayOut 斗爭(zhēng)過的朋友對(duì)此肯定深有體會(huì)。
在本文中,我們會(huì)給出一種更好的解決方案,我們不是去試圖把界面設(shè)計(jì)者頭腦中的設(shè)計(jì)概念和樣式逐步降級(jí)、分解成所使用的實(shí)現(xiàn)語(yǔ)言能夠理解的低層概念,也不是提供一些已經(jīng)完成的、確定的但難以擴(kuò)充和更改的布局樣式庫(kù)供界面設(shè)計(jì)者使用。我們所提供的是一種專門用于描述高層界面設(shè)計(jì)樣式的語(yǔ)言。通過這種語(yǔ)言,界面設(shè)計(jì)者可以直接、明確地描述出他們頭腦中的布局設(shè)計(jì)樣式,通過這種語(yǔ)言,界面設(shè)計(jì)者可以自己方便地、靈活地制定自己需要的布局樣式。也就是說,本來僅存在于界面設(shè)計(jì)者頭腦中的抽象布局樣式,現(xiàn)在也變得可描述,可編程了。
界面布局語(yǔ)言介紹
在學(xué)習(xí)界面布局語(yǔ)言的設(shè)計(jì)之前,先來了解一下該語(yǔ)言的使用是非常有幫助的。我們的界面布局語(yǔ)言非常簡(jiǎn)單,簡(jiǎn)單到只有一種原子:Component。Component 是一種基本的布局元素,可以對(duì) Component 進(jìn)行平移和伸縮,使其和給定的一個(gè)布局空間 Rectangle 匹配。比如對(duì)于 Button 這個(gè) Component 來講,它具有傳統(tǒng)按鈕的外觀,但是它在布局上所占的實(shí)際空間則是由為其指定的 Rectangle 決定的。此外,Component 要最終在界面上顯示出來,就必須有一個(gè)物理上的 Container。也就是說,界面設(shè)計(jì)應(yīng)該是一項(xiàng)充滿創(chuàng)造性、富有樂趣的工作,但是卻往往被認(rèn)為非常的枯燥和繁瑣。究其原因,是因?yàn)榻缑娌季诸I(lǐng)域所采用的描述概念和具體的實(shí)現(xiàn)語(yǔ)言之間存在很大的語(yǔ)義隔閡。而一般的界面開發(fā)工具提供的所見即所得以及界面布局管理器等方案也無法很好地解決這個(gè)問題。
在本文中,我們會(huì)給出一種更好的解決方案,我們不是去試圖把界面設(shè)計(jì)者頭腦中的設(shè)計(jì)概念和樣式逐步降級(jí)、分解成所使用的實(shí)現(xiàn)語(yǔ)言能夠理解的低層概念,也不是提供一些已經(jīng)完成的、確定的但難以擴(kuò)充和更改的布局樣式庫(kù)供界面設(shè)計(jì)者使用。我們所提供的是一種專門用于描述高層界面設(shè)計(jì)樣式的語(yǔ)言。通過這種語(yǔ)言,界面設(shè)計(jì)者可以直接、明確地描述出他們頭腦中的布局設(shè)計(jì)樣式;通過這種語(yǔ)言,界面設(shè)計(jì)者可以自己方便地、靈活地制定自己需要的布局樣式。此外,本文中給出的設(shè)計(jì)思想對(duì)于其他領(lǐng)域的設(shè)計(jì)也有很好的借鑒作用。
創(chuàng)造性,還是乏味?
界面設(shè)計(jì)是一項(xiàng)非常有創(chuàng)造性,甚至富有藝術(shù)性的工作,一個(gè)簡(jiǎn)潔、易用、漂亮的界面在帶給使用者方便的同時(shí),也會(huì)給界面設(shè)計(jì)者帶來極大的成就感。但是,在現(xiàn)實(shí)中,情況似乎并非如此,很多人都認(rèn)為做界面是一項(xiàng)非常繁瑣、機(jī)械、乏味的工作,并千方百計(jì)地去逃避界面相關(guān)的工作。這是為什么呢?
原因很簡(jiǎn)單,因?yàn)樽鼋缑嫫鋵?shí)涉及兩項(xiàng)工作,一項(xiàng)是界面的一些設(shè)計(jì)創(chuàng)意,包括界面的布局樣式以及和使用者的交互方式,這項(xiàng)工作充滿挑戰(zhàn)和樂趣。但是,這些設(shè)計(jì)創(chuàng)意最終是要落實(shí)到實(shí)現(xiàn)上的,這就是第二項(xiàng)工作。此時(shí),你頭腦中那些清晰、完整的設(shè)計(jì)概念開始變得瑣碎,你不得不和那些低層次的坐標(biāo)位置打交道。更糟糕的是,當(dāng)你好不容易做好了一個(gè)界面,但是發(fā)現(xiàn)其中某些元素的布局需要一些調(diào)整時(shí),這個(gè)你本應(yīng)認(rèn)為是一個(gè)很簡(jiǎn)單的改變卻造成大量重復(fù)的低層次坐標(biāo)位置更改時(shí),你肯定會(huì)認(rèn)為做界面是多么的機(jī)械和乏味呀!
其實(shí),造成這種認(rèn)識(shí)的根源在于界面設(shè)計(jì)創(chuàng)意和實(shí)現(xiàn)這些創(chuàng)意概念的語(yǔ)言之間存在很大的斷層。這樣,在具體實(shí)現(xiàn)時(shí),你就必須得把這些清晰、完整的布局樣式降級(jí)成一些瑣碎、沒有什么意義的低層次的坐標(biāo)值,使得實(shí)現(xiàn)語(yǔ)言能夠理解。這項(xiàng)工作不僅乏味,而且最終的實(shí)現(xiàn)也非常的脆弱 —— 一個(gè)在布局樣式層面非常簡(jiǎn)單的更改,就會(huì)造成實(shí)現(xiàn)層面的巨大變動(dòng)。比如:我們可以說把一組元素同時(shí)按比例縮小 10%,做過界面的朋友肯定知道這個(gè)更改意味著什么。
為了應(yīng)對(duì)這個(gè)斷層的問題,目前幾乎所有的涉及界面制作的開發(fā)工具都提供了相同的解決方法:可視化的界面設(shè)計(jì)工具以及布局管理器。但是這兩種方法都沒有從根本上解決這個(gè)問題。
可視化界面設(shè)計(jì)工具確實(shí)避免了不少繁瑣的界面元素?cái)[放工作,但是對(duì)于專業(yè)的界面設(shè)計(jì)來說,通過拖放設(shè)計(jì)出來的界面在準(zhǔn)確度和規(guī)范性上都有待提高,此外還有更為重要的一點(diǎn),那就是存在于設(shè)計(jì)者頭腦中的布局樣式仍然沒有被明確地描述出來,而是被降級(jí)成一個(gè)個(gè)擺放在一起的零散的組件,雖然這些組件本身是可視的。這個(gè)語(yǔ)義斷層的存在同樣會(huì)使得通過可視化界面設(shè)計(jì)工具設(shè)計(jì)出來的界面非常脆弱。
布局管理器試圖通過提供一些常用的布局樣式來解決這個(gè)問題。但是,這種做法非常僵化,也就是說你只能使用現(xiàn)有的布局管理器,如果它們無法滿足你的要求,你也無法自己定制。此外,這些布局管理器僅僅適合于一些簡(jiǎn)單的情況。對(duì)于一些復(fù)雜的布局只要給定了一個(gè) Rectangle 和一個(gè) Container,一個(gè) Component 就可以在界面上指定的布局位置呈現(xiàn)出來。
例如,當(dāng)我們使用布局語(yǔ)言在一個(gè) JFrame 上坐標(biāo)位置為 (0,0) 展示一個(gè) width 為 200,height 為 60 的按鈕時(shí),我們可以這樣來描述(為了簡(jiǎn)潔起見,后面的代碼實(shí)例中均略去 Layout 名字空間前綴):
Button().title(“button1”).at(0,0,200,60).in(this.getContentPane());
僅僅提供這樣一種原子元素的語(yǔ)言顯然無法滿足我們前面提到的目標(biāo)。在我們的界面布局語(yǔ)言中,還提供了兩種在布局中非常常用的兩種從已有組件構(gòu)造新組件的組合手段:above 和 beside。其中 above 組合子接收 3 個(gè)參數(shù):兩個(gè)現(xiàn)有 Component 以及一個(gè)比例,它會(huì)產(chǎn)生出一個(gè)新的復(fù)合 Component,其中按照給定的比例把第一個(gè) Component 擺放在第二個(gè) Component 之上。Beside 組合子接收同樣的 3 個(gè)參數(shù),并且也產(chǎn)生出一個(gè)新的復(fù)合 Component,其中按照給定的比例把第一個(gè) Component 擺放在第二個(gè)Component左邊。
例如,如果我們希望在一個(gè)給定的 Container C 上的 Rectangle(0,0,300,40) 中,平行擺放一個(gè) TextField 和一個(gè) Button,且希望 TextField 占據(jù) 80% 的比例時(shí),可以這樣來描述:
beside(TextField(), Button().title(“ok”), 0.8).at(0,0,300,40).in(C)
同樣,我們可以使用 above 來進(jìn)行如下描述:
above(TextField(), Button().title(“ok”), 0.5).at(0,0,300,60).in(C)
值得注意的是,在我們的界面布局語(yǔ)言中,Component 在 beside 和 above 操作下是封閉的,也就是說 beside 和 above 操作的結(jié)果同樣也是 Component,并完全可以作為基本的 Component 來再次進(jìn)行 beside 和 above 組合。這樣我們就可以使用這兩個(gè)簡(jiǎn)單的操作生成更加復(fù)雜的 Component 來,從而完成復(fù)雜的界面布局。比如,我們可以這樣來進(jìn)行描述:
Component L = beside(TextField (), Button().title(“…”), 0.8);
above(L, Button().title(“ok”), 0.5). at(0,0,300,60).in(C)
為了保證界面布局語(yǔ)言的完備性,我們?cè)黾恿艘环N特殊的原子元素:Empty。它的作用只是占據(jù)一定的布局空間。比如,如果我們希望在一個(gè)布局空間中右半邊放置一個(gè) Button,左半邊空置,就可以這些描述:
beside(Empty(), Button(), 0.5).at(0,0,200,40).in(C)
讀者在后面可以看到,正是這個(gè) Empty 以及 beside 和 above 操作的閉包性質(zhì)為我們描述任意復(fù)雜的布局樣式提供了可能。
在本文中,我們會(huì)給出一種更好的解決方案,我們不是去試圖把界面設(shè)計(jì)者頭腦中的設(shè)計(jì)概念和樣式逐步降級(jí)、分解成所使用的實(shí)現(xiàn)語(yǔ)言能夠理解的低層概念,也不是提供一些已經(jīng)完成的、確定的但難以擴(kuò)充和更改的布局樣式庫(kù)供界面設(shè)計(jì)者使用。我們所提供的是一種專門用于描述高層界面設(shè)計(jì)樣式的語(yǔ)言。通過這種語(yǔ)言,界面設(shè)計(jì)者可以直接、明確地描述出他們頭腦中的布局設(shè)計(jì)樣式;通過這種語(yǔ)言,界面設(shè)計(jì)者可以自己方便地、靈活地制定自己需要的布局樣式。此外,本文中給出的設(shè)計(jì)思想對(duì)于其他領(lǐng)域的設(shè)計(jì)也有很好的借鑒作用。
創(chuàng)造性,還是乏味?
界面設(shè)計(jì)是一項(xiàng)非常有創(chuàng)造性,甚至富有藝術(shù)性的工作,一個(gè)簡(jiǎn)潔、易用、漂亮的界面在帶給使用者方便的同時(shí),也會(huì)給界面設(shè)計(jì)者帶來極大的成就感。但是,在現(xiàn)實(shí)中,情況似乎并非如此,很多人都認(rèn)為做界面是一項(xiàng)非常繁瑣、機(jī)械、乏味的工作,并千方百計(jì)地去逃避界面相關(guān)的工作。這是為什么呢?
原因很簡(jiǎn)單,因?yàn)樽鼋缑嫫鋵?shí)涉及兩項(xiàng)工作,一項(xiàng)是界面的一些設(shè)計(jì)創(chuàng)意,包括界面的布局樣式以及和使用者的交互方式,這項(xiàng)工作充滿挑戰(zhàn)和樂趣。但是,這些設(shè)計(jì)創(chuàng)意最終是要落實(shí)到實(shí)現(xiàn)上的,這就是第二項(xiàng)工作。此時(shí),你頭腦中那些清晰、完整的設(shè)計(jì)概念開始變得瑣碎,你不得不和那些低層次的坐標(biāo)位置打交道。更糟糕的是,當(dāng)你好不容易做好了一個(gè)界面,但是發(fā)現(xiàn)其中某些元素的布局需要一些調(diào)整時(shí),這個(gè)你本應(yīng)認(rèn)為是一個(gè)很簡(jiǎn)單的改變卻造成大量重復(fù)的低層次坐標(biāo)位置更改時(shí),你肯定會(huì)認(rèn)為做界面是多么的機(jī)械和乏味呀!
其實(shí),造成這種認(rèn)識(shí)的根源在于界面設(shè)計(jì)創(chuàng)意和實(shí)現(xiàn)這些創(chuàng)意概念的語(yǔ)言之間存在很大的斷層。這樣,在具體實(shí)現(xiàn)時(shí),你就必須得把這些清晰、完整的布局樣式降級(jí)成一些瑣碎、沒有什么意義的低層次的坐標(biāo)值,使得實(shí)現(xiàn)語(yǔ)言能夠理解。這項(xiàng)工作不僅乏味,而且最終的實(shí)現(xiàn)也非常的脆弱 —— 一個(gè)在布局樣式層面非常簡(jiǎn)單的更改,就會(huì)造成實(shí)現(xiàn)層面的巨大變動(dòng)。比如:我們可以說把一組元素同時(shí)按比例縮小 10%,做過界面的朋友肯定知道這個(gè)更改意味著什么。
為了應(yīng)對(duì)這個(gè)斷層的問題,目前幾乎所有的涉及界面制作的開發(fā)工具都提供了相同的解決方法:可視化的界面設(shè)計(jì)工具以及布局管理器。但是這兩種方法都沒有從根本上解決這個(gè)問題。
可視化界面設(shè)計(jì)工具確實(shí)避免了不少繁瑣的界面元素?cái)[放工作,但是對(duì)于專業(yè)的界面設(shè)計(jì)來說,通過拖放設(shè)計(jì)出來的界面在準(zhǔn)確度和規(guī)范性上都有待提高,此外還有更為重要的一點(diǎn),那就是存在于設(shè)計(jì)者頭腦中的布局樣式仍然沒有被明確地描述出來,而是被降級(jí)成一個(gè)個(gè)擺放在一起的零散的組件,雖然這些組件本身是可視的。這個(gè)語(yǔ)義斷層的存在同樣會(huì)使得通過可視化界面設(shè)計(jì)工具設(shè)計(jì)出來的界面非常脆弱。
布局管理器試圖通過提供一些常用的布局樣式來解決這個(gè)問題。但是,這種做法非常僵化,也就是說你只能使用現(xiàn)有的布局管理器,如果它們無法滿足你的要求,你也無法自己定制。此外,這些布局管理器僅僅適合于一些簡(jiǎn)單的情況。對(duì)于一些復(fù)雜的布局樣式來說,它們的描述能力就顯得非常的不足。那些曾經(jīng)和 GridBagLayOut 斗爭(zhēng)過的朋友對(duì)此肯定深有體會(huì)。
在本文中,我們會(huì)給出一種更好的解決方案,我們不是去試圖把界面設(shè)計(jì)者頭腦中的設(shè)計(jì)概念和樣式逐步降級(jí)、分解成所使用的實(shí)現(xiàn)語(yǔ)言能夠理解的低層概念,也不是提供一些已經(jīng)完成的、確定的但難以擴(kuò)充和更改的布局樣式庫(kù)供界面設(shè)計(jì)者使用。我們所提供的是一種專門用于描述高層界面設(shè)計(jì)樣式的語(yǔ)言。通過這種語(yǔ)言,界面設(shè)計(jì)者可以直接、明確地描述出他們頭腦中的布局設(shè)計(jì)樣式,通過這種語(yǔ)言,界面設(shè)計(jì)者可以自己方便地、靈活地制定自己需要的布局樣式。也就是說,本來僅存在于界面設(shè)計(jì)者頭腦中的抽象布局樣式,現(xiàn)在也變得可描述,可編程了。
界面布局語(yǔ)言介紹
在學(xué)習(xí)界面布局語(yǔ)言的設(shè)計(jì)之前,先來了解一下該語(yǔ)言的使用是非常有幫助的。我們的界面布局語(yǔ)言非常簡(jiǎn)單,簡(jiǎn)單到只有一種原子:Component。Component 是一種基本的布局元素,可以對(duì) Component 進(jìn)行平移和伸縮,使其和給定的一個(gè)布局空間 Rectangle 匹配。比如對(duì)于 Button 這個(gè) Component 來講,它具有傳統(tǒng)按鈕的外觀,但是它在布局上所占的實(shí)際空間則是由為其指定的 Rectangle 決定的。此外,Component 要最終在界面上顯示出來,就必須有一個(gè)物理上的 Container。也就是說,界面設(shè)計(jì)應(yīng)該是一項(xiàng)充滿創(chuàng)造性、富有樂趣的工作,但是卻往往被認(rèn)為非常的枯燥和繁瑣。究其原因,是因?yàn)榻缑娌季诸I(lǐng)域所采用的描述概念和具體的實(shí)現(xiàn)語(yǔ)言之間存在很大的語(yǔ)義隔閡。而一般的界面開發(fā)工具提供的所見即所得以及界面布局管理器等方案也無法很好地解決這個(gè)問題。
在本文中,我們會(huì)給出一種更好的解決方案,我們不是去試圖把界面設(shè)計(jì)者頭腦中的設(shè)計(jì)概念和樣式逐步降級(jí)、分解成所使用的實(shí)現(xiàn)語(yǔ)言能夠理解的低層概念,也不是提供一些已經(jīng)完成的、確定的但難以擴(kuò)充和更改的布局樣式庫(kù)供界面設(shè)計(jì)者使用。我們所提供的是一種專門用于描述高層界面設(shè)計(jì)樣式的語(yǔ)言。通過這種語(yǔ)言,界面設(shè)計(jì)者可以直接、明確地描述出他們頭腦中的布局設(shè)計(jì)樣式;通過這種語(yǔ)言,界面設(shè)計(jì)者可以自己方便地、靈活地制定自己需要的布局樣式。此外,本文中給出的設(shè)計(jì)思想對(duì)于其他領(lǐng)域的設(shè)計(jì)也有很好的借鑒作用。
創(chuàng)造性,還是乏味?
界面設(shè)計(jì)是一項(xiàng)非常有創(chuàng)造性,甚至富有藝術(shù)性的工作,一個(gè)簡(jiǎn)潔、易用、漂亮的界面在帶給使用者方便的同時(shí),也會(huì)給界面設(shè)計(jì)者帶來極大的成就感。但是,在現(xiàn)實(shí)中,情況似乎并非如此,很多人都認(rèn)為做界面是一項(xiàng)非常繁瑣、機(jī)械、乏味的工作,并千方百計(jì)地去逃避界面相關(guān)的工作。這是為什么呢?
原因很簡(jiǎn)單,因?yàn)樽鼋缑嫫鋵?shí)涉及兩項(xiàng)工作,一項(xiàng)是界面的一些設(shè)計(jì)創(chuàng)意,包括界面的布局樣式以及和使用者的交互方式,這項(xiàng)工作充滿挑戰(zhàn)和樂趣。但是,這些設(shè)計(jì)創(chuàng)意最終是要落實(shí)到實(shí)現(xiàn)上的,這就是第二項(xiàng)工作。此時(shí),你頭腦中那些清晰、完整的設(shè)計(jì)概念開始變得瑣碎,你不得不和那些低層次的坐標(biāo)位置打交道。更糟糕的是,當(dāng)你好不容易做好了一個(gè)界面,但是發(fā)現(xiàn)其中某些元素的布局需要一些調(diào)整時(shí),這個(gè)你本應(yīng)認(rèn)為是一個(gè)很簡(jiǎn)單的改變卻造成大量重復(fù)的低層次坐標(biāo)位置更改時(shí),你肯定會(huì)認(rèn)為做界面是多么的機(jī)械和乏味呀!
其實(shí),造成這種認(rèn)識(shí)的根源在于界面設(shè)計(jì)創(chuàng)意和實(shí)現(xiàn)這些創(chuàng)意概念的語(yǔ)言之間存在很大的斷層。這樣,在具體實(shí)現(xiàn)時(shí),你就必須得把這些清晰、完整的布局樣式降級(jí)成一些瑣碎、沒有什么意義的低層次的坐標(biāo)值,使得實(shí)現(xiàn)語(yǔ)言能夠理解。這項(xiàng)工作不僅乏味,而且最終的實(shí)現(xiàn)也非常的脆弱 —— 一個(gè)在布局樣式層面非常簡(jiǎn)單的更改,就會(huì)造成實(shí)現(xiàn)層面的巨大變動(dòng)。比如:我們可以說把一組元素同時(shí)按比例縮小 10%,做過界面的朋友肯定知道這個(gè)更改意味著什么。
為了應(yīng)對(duì)這個(gè)斷層的問題,目前幾乎所有的涉及界面制作的開發(fā)工具都提供了相同的解決方法:可視化的界面設(shè)計(jì)工具以及布局管理器。但是這兩種方法都沒有從根本上解決這個(gè)問題。
可視化界面設(shè)計(jì)工具確實(shí)避免了不少繁瑣的界面元素?cái)[放工作,但是對(duì)于專業(yè)的界面設(shè)計(jì)來說,通過拖放設(shè)計(jì)出來的界面在準(zhǔn)確度和規(guī)范性上都有待提高,此外還有更為重要的一點(diǎn),那就是存在于設(shè)計(jì)者頭腦中的布局樣式仍然沒有被明確地描述出來,而是被降級(jí)成一個(gè)個(gè)擺放在一起的零散的組件,雖然這些組件本身是可視的。這個(gè)語(yǔ)義斷層的存在同樣會(huì)使得通過可視化界面設(shè)計(jì)工具設(shè)計(jì)出來的界面非常脆弱。
布局管理器試圖通過提供一些常用的布局樣式來解決這個(gè)問題。但是,這種做法非常僵化,也就是說你只能使用現(xiàn)有的布局管理器,如果它們無法滿足你的要求,你也無法自己定制。此外,這些布局管理器僅僅適合于一些簡(jiǎn)單的情況。對(duì)于一些復(fù)雜的布局只要給定了一個(gè) Rectangle 和一個(gè) Container,一個(gè) Component 就可以在界面上指定的布局位置呈現(xiàn)出來。
例如,當(dāng)我們使用布局語(yǔ)言在一個(gè) JFrame 上坐標(biāo)位置為 (0,0) 展示一個(gè) width 為 200,height 為 60 的按鈕時(shí),我們可以這樣來描述(為了簡(jiǎn)潔起見,后面的代碼實(shí)例中均略去 Layout 名字空間前綴):
Button().title(“button1”).at(0,0,200,60).in(this.getContentPane());
僅僅提供這樣一種原子元素的語(yǔ)言顯然無法滿足我們前面提到的目標(biāo)。在我們的界面布局語(yǔ)言中,還提供了兩種在布局中非常常用的兩種從已有組件構(gòu)造新組件的組合手段:above 和 beside。其中 above 組合子接收 3 個(gè)參數(shù):兩個(gè)現(xiàn)有 Component 以及一個(gè)比例,它會(huì)產(chǎn)生出一個(gè)新的復(fù)合 Component,其中按照給定的比例把第一個(gè) Component 擺放在第二個(gè) Component 之上。Beside 組合子接收同樣的 3 個(gè)參數(shù),并且也產(chǎn)生出一個(gè)新的復(fù)合 Component,其中按照給定的比例把第一個(gè) Component 擺放在第二個(gè)Component左邊。
例如,如果我們希望在一個(gè)給定的 Container C 上的 Rectangle(0,0,300,40) 中,平行擺放一個(gè) TextField 和一個(gè) Button,且希望 TextField 占據(jù) 80% 的比例時(shí),可以這樣來描述:
beside(TextField(), Button().title(“ok”), 0.8).at(0,0,300,40).in(C)
同樣,我們可以使用 above 來進(jìn)行如下描述:
above(TextField(), Button().title(“ok”), 0.5).at(0,0,300,60).in(C)
值得注意的是,在我們的界面布局語(yǔ)言中,Component 在 beside 和 above 操作下是封閉的,也就是說 beside 和 above 操作的結(jié)果同樣也是 Component,并完全可以作為基本的 Component 來再次進(jìn)行 beside 和 above 組合。這樣我們就可以使用這兩個(gè)簡(jiǎn)單的操作生成更加復(fù)雜的 Component 來,從而完成復(fù)雜的界面布局。比如,我們可以這樣來進(jìn)行描述:
Component L = beside(TextField (), Button().title(“…”), 0.8);
above(L, Button().title(“ok”), 0.5). at(0,0,300,60).in(C)
為了保證界面布局語(yǔ)言的完備性,我們?cè)黾恿艘环N特殊的原子元素:Empty。它的作用只是占據(jù)一定的布局空間。比如,如果我們希望在一個(gè)布局空間中右半邊放置一個(gè) Button,左半邊空置,就可以這些描述:
beside(Empty(), Button(), 0.5).at(0,0,200,40).in(C)
讀者在后面可以看到,正是這個(gè) Empty 以及 beside 和 above 操作的閉包性質(zhì)為我們描述任意復(fù)雜的布局樣式提供了可能。

