<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
Ruby 目前被作為一種用于構(gòu)建 Web 應(yīng)用程序的編程語言而著稱,主要通過 Ruby on Rails 框架使用。但是,這種語言還可以用于開發(fā)圖形化桌面應(yīng)用程序。在本文中,您將學(xué)習(xí)更多關(guān)于使用 Ruby 進(jìn)行桌面應(yīng)用程序開發(fā)的知識(shí),并完成一個(gè)詳細(xì)的示例,這個(gè)示例使用 Monkeybars — 一個(gè)基于 Swing 和 JRuby 的開源庫 — 創(chuàng)建一個(gè) GUI 桌面應(yīng)用程序。
![]() |
|
標(biāo) 準(zhǔn)的 Ruby 發(fā)行版包括用于 Tk 綁定的代碼,Tk 是一組開源的、跨平臺(tái)部件集,用于創(chuàng)建圖形化桌面應(yīng)用程序。這可以帶來很大的方便。但是,在從源代碼安裝 Ruby 時(shí),應(yīng)確認(rèn)同時(shí)還有 Tk 依賴關(guān)系,并確保編譯設(shè)置包括 Tk。如果在 Windows? 上使用方便的 “一鍵式(one-click)” 安裝程序包安裝 Ruby,那么仍然需要采取額外步驟使 Tk 工作,因?yàn)樗辉僦С肿詣?dòng)安裝。
即使為 Ruby 設(shè)置了 Tk,它仍然有點(diǎn)沉悶。在某些目標(biāo)平臺(tái)上,它們看上去相當(dāng)丑陋。而且,創(chuàng)建復(fù)雜的接口令人生畏。Tk 最適合用于較小的 GUI 需求。
可用工具包 Tk 的這些弱點(diǎn)促使了其他面向 Ruby 的 GUI 工具包選項(xiàng)的開發(fā)(請(qǐng)參閱 參考資料 查看相關(guān)鏈接)。有些值得注意的選擇是:
-
FxRuby
:FxRuby 是用于 Fox 的 Ruby 綁定,這是一個(gè)用 C 編寫的 GUI 工具包。它可用于使用 RubyGems 的安裝。對(duì)于 Windows,有一個(gè)二進(jìn)制 gem;用于其他平臺(tái)的 gem 則需要編譯本地代碼。
-
WxRuby
: WxRuby 是用于跨平臺(tái) wxWidgets C++ GUI 工具包的一個(gè)綁定,通過它可以創(chuàng)建擁有本地外觀的桌面應(yīng)用程序。它可用于使用 gem 的安裝。
-
QtRuby
:QtRuby 提供對(duì) Qt 工具包(在 KDE 桌面系統(tǒng)中使用的工具包)的 Ruby 綁定。對(duì)于 Windows 安裝,有一個(gè) gem,但是對(duì)于其他平臺(tái)則只有源代碼。
-
GTK-Ruby
:GTK 是在 GNOME 中使用的 UI 工具包。要使之運(yùn)行,需要編譯本地代碼。
-
Shoes
:Shoes 是最近出現(xiàn)的一個(gè)與 Ruby GUI 部件有關(guān)的工具包。與這份列表中提到的其他工具包不同的是,它是專門為 Ruby 設(shè)計(jì)的??梢允褂锰囟ㄓ谄脚_(tái)的安裝程序來安裝它。
- Swing :Swing?是的,正是這個(gè)與每個(gè) Java 運(yùn)行時(shí)環(huán)境捆綁的 GUI 庫。如果您運(yùn)行 JRuby,那么可以使用 Swing。
除了其中一個(gè)外,所有這些都是用 C 或 C++ 編寫的 GUI 或部件庫,它們都有相應(yīng)的綁定,以允許在其他語言,例如 Ruby、Python 和 Perl 中調(diào)用它們。在幾乎所有情況下,您都要面對(duì)多種考慮,例如安裝和發(fā)行。
當(dāng)然,選擇使用哪個(gè) GUI 工具集取決于您的特定需要。需要考慮以下內(nèi)容:
- 一套豐富的部件或組件
- 可靠的實(shí)現(xiàn)
- 在多種平臺(tái)上的可用性(主要是 Macintosh、Win32、KDE 和 GNOME)
- 在托管平臺(tái)上的本地感觀
- 是否受到積極的維護(hù)
- 易于創(chuàng)建定制的部件
- 未受限的許可
- 可接受的成本
- 可用于加快開發(fā)的已有的框架和庫
- 成熟的 IDE 和窗體布局工具
- 測試工具和框架
- 易于打包和部署
如 果只需偶爾拋出消息框,或者請(qǐng)求用戶進(jìn)行某些簡單的輸入,那么前面列出的所有工具包都適用。對(duì)于簡單的需求,只需重點(diǎn)考慮平臺(tái)可用性、適合的部件以及適當(dāng) 的成本。如果打算發(fā)布應(yīng)用程序,那么需要檢查工具包許可。另外,還必須確保用戶已經(jīng)有所需的環(huán)境,或者很容易將所有需要的庫和部件放到一個(gè)獨(dú)立的應(yīng)用程序 或一個(gè)安裝包中。
但是,對(duì)于復(fù)雜的應(yīng)用程序,需求就變得嚴(yán)格起來。對(duì)于任何超越了簡單窗體的應(yīng)用程序,幾乎肯定需要有一個(gè)窗體設(shè)計(jì)工具。另外還需要一套豐富的可用部件;不過,可以重用一個(gè)已有的數(shù)據(jù)采集器或文件瀏覽器組件,而不必自己編寫它們。
每 個(gè)不同的基于 C 的 Ruby GUI 工具包都有其擅長的一面,但是它們當(dāng)中沒有明顯的勝者。對(duì)于常規(guī)的 Ruby 跨平臺(tái)桌面開發(fā),并沒有顯而易見的選擇。在不同程度上,它們都有安裝、文檔化、設(shè)計(jì)工具、打包和部署方面的問題。值得注意的是,逐一對(duì)比特性,它們當(dāng)中沒 有哪個(gè)能超過非 C 語言編寫的工具包。
![]() ![]() |
![]()
|
JRuby 是用于 Java 平臺(tái)的一個(gè) Ruby 實(shí)現(xiàn)(請(qǐng)參閱 參考資料 )。它使您可以通過 JVM 執(zhí)行 Ruby 代碼。在 JRuby 下運(yùn)行的 Ruby 代碼還可以裝載和使用 Java 庫,包括 Swing。
![]() |
|
Java 平臺(tái)的某些方面使得 JRuby 成為一個(gè)好的選擇:
- 它比較穩(wěn)定,并且經(jīng)過良好的測試
- 它有較強(qiáng)的社區(qū)和供應(yīng)商支持
- 它有很多良好的文檔
- 有很好的 IDE 和 UI 布局工具可供選擇
- 可免費(fèi)使用(不管是在成本方面還是許可方面)
- 用戶機(jī)器上可能已經(jīng)安裝了 Java 運(yùn)行時(shí)
如果用(J)Ruby 編寫應(yīng)用程序,并使用 Swing 實(shí)現(xiàn) UI,則只需確保用戶有最新版本的 Java 運(yùn)行時(shí),并在打包應(yīng)用程序時(shí)包括 JRuby JAR 文件。由于已經(jīng)有了用于 JRuby 應(yīng)用程序打包的 Ruby 工具,所以這些不成問題。
(J)Ruby + Swing 的開發(fā)人員選項(xiàng)
對(duì)于從 Ruby 中使用 Swing,有很多選項(xiàng):
-
原始的、手工編寫的對(duì) Swing 對(duì)象的內(nèi)聯(lián)調(diào)用
:在最簡單的情況下,可以像引用任何其他 Ruby 對(duì)象那樣引用 Swing 對(duì)象:
panel = Java::javax::swing::JFrame.new("JRuby panel")
panel.show
-
“Builder” 和領(lǐng)域特定語言(DSL)風(fēng)格的庫
:全部以手工代碼構(gòu)造面板和窗體,然后添加組件,這樣可以提高開發(fā)速度。有一些庫使 Swing 交互更具 Ruby 風(fēng)格。例如:
-
Cheri::Swing 使用 Ruby 塊語法生成 Swing 代碼。
- 另一個(gè)庫 Profligacy 則圍繞原始的 Swing 調(diào)用提供了一個(gè) Ruby 包裝器,它可以幫助您用更少的原始 Java 代碼編寫更多的 Swing 代碼。為了恰當(dāng)?shù)厥褂?Swing 組件,仍然需要熟悉 Swing API 文檔。
-
Cheri::Swing 使用 Ruby 塊語法生成 Swing 代碼。
- “我們不關(guān)心 Java 類來自何處” 方法 :第三種方法假設(shè)用于 Swing 對(duì)象的已編譯的 Java 類已經(jīng)存在,并試圖使用 Ruby 代碼簡化 Swing 對(duì)象的創(chuàng)建。
最后是 Monkeybars 庫采用的方法(請(qǐng)參閱 參考資料 )。 現(xiàn)在已經(jīng)有很多非常好的、免費(fèi)的圖形化 Swing UI 布局編輯器。和之前提到的 GUI 工具包(例如 Fox 和 GTK)的使用一樣,對(duì)于不常見的對(duì)話框,不需要 UI 編輯器。但是,除此之外,這類工具是不可替代的,對(duì)于一個(gè)高級(jí)的桌面應(yīng)用程序,無視這些工具而手工編寫 UI 并無益處。
![]() |
|
Monkeybars 是一個(gè)開源 Ruby 庫,它使用一種模型、視圖、控制器(MVC)設(shè)計(jì)模式將已有的 Java Swing 類(即定義 Swing UI 的已編譯 Java 類)與 Ruby 代碼連接起來。MVC 的目的在于將視圖邏輯和 UI 組件與應(yīng)用程序邏輯相分離。
由于使用 Java 語言和 Swing 庫,Monkeybars 建立在成熟、健壯的技術(shù)之上。與目前用于 JRuby 的其他 Swing 庫不同,它非常適合于構(gòu)造大型的、復(fù)雜的、多面板的應(yīng)用程序。您將看到,創(chuàng)建 Monkeybars 應(yīng)用程序需要承擔(dān)一定的開銷,所以對(duì)于簡單的窗體來說它可能不是最好的選擇。但是,對(duì)于有以下需求的 JRuby 桌面應(yīng)用程序來說,它是一個(gè)合理的選擇:
- 可靠的跨平臺(tái)部署(確保用戶安裝了最新的 JVM)
- 有大量具有任意復(fù)雜度的 UI 部件可供選擇
- 復(fù)雜的 UI 窗體和面板構(gòu)造和交互
![]() |
|
和 Profligacy 一樣,Monkeybars 不隱藏 Swing API。但是,由于它使用編譯過的 UI 類,因此可以充分利用任何工具或應(yīng)用程序來生成真正的布局。取決于應(yīng)用程序的復(fù)雜性,幾乎不可避免的是,在編寫 Ruby 代碼的過程中,某些時(shí)候需要參考 Swing 組件 API 文檔和代碼示例才能知道怎么做(但是由于 JRuby 與 Java 庫的良好集成,很容易將那樣的 Swing 代碼包裝在一個(gè) Ruby API 中,以便于重用)。使用 Monkeybars 構(gòu)建的程序可能有不同程度的復(fù)雜性,但是可以遵循一些基本的模式來使代碼易于維護(hù)。
實(shí)現(xiàn) MVC 的 Monkeybars 方法
MVC 模式已經(jīng)有很長的歷史了,并且有很多變體。對(duì)于 Monkeybars,基本前提是對(duì)于每個(gè) Swing 幀(也就是容納各種組件或 widget 的 UI 對(duì)象;在某些情況下,可能是一個(gè)模態(tài)面板),有 3 個(gè) Ruby 文件:一個(gè)模型、一個(gè)視圖和一個(gè)控制器。模型類存放實(shí)際的業(yè)務(wù)邏輯,并管理與應(yīng)用程序部分對(duì)應(yīng)的數(shù)據(jù)。視圖或控制器用于作為與模型進(jìn)行交互的手段,而模型 并不知道它們的存在。將對(duì)視圖和控制器的引用放在模型之外,可以使模型更易于開發(fā)和測試。
視圖是另一個(gè) Ruby 文件,它引用一個(gè)特定的 Java 類,這個(gè) Java 類包含編譯過的 Swing 代碼。視圖管理 Swing 組件與模型數(shù)據(jù)的交互。視圖可以直接與模型交互,但是它也使用模型的一個(gè)副本,以便將數(shù)據(jù)傳遞給控制器。在設(shè)計(jì)模型類時(shí)要謹(jǐn)記這一點(diǎn),因?yàn)樗罱K要為兩個(gè) 目的服務(wù)。模型的主實(shí)例保持長期狀態(tài),并提供應(yīng)用程序邏輯;而視圖使用的副本實(shí)際上是一個(gè)可任意使用的數(shù)據(jù)訪問對(duì)象。模型應(yīng)該易于實(shí)例化,并為視圖使用的 任何數(shù)據(jù)提供基本的訪問方法。
視圖并不直接與控制器交互。相反,有一個(gè)信號(hào)系統(tǒng)來抽象控制器與視圖之間的交互。這種解耦使得視圖和控制器更易于測試。
![]() |
|
在控制器類中,可以定義 Swing 事件(例如單擊按鈕或更改文本字段)的處理程序,并控制模型的狀態(tài)??刂破鞅A魧?duì)模型主實(shí)例的引用。它并不直接與視圖通信。
當(dāng)一個(gè)控制器需要從視圖獲取數(shù)據(jù)時(shí),視圖提供模型的一個(gè)副本,其中包含當(dāng)前的 UI 內(nèi)容。然后,控制器可以決定用該數(shù)據(jù)更新模型的主實(shí)例,或者根據(jù)這些值采取某種操作。控制器還可以告訴視圖更新自身,并傳回更新后的值。在示例應(yīng)用程序中,您將看到這一點(diǎn)。
![]() ![]() |
![]()
|
使用 Monkeybars 的一個(gè)示例 JRuby Swing 應(yīng)用程序
為了讓您感覺一下如何使用 Swing 和 Ruby 創(chuàng)建一個(gè)桌面應(yīng)用程序,我將帶您完成一個(gè)簡單的用 Monkeybars 創(chuàng)建的程序(要獲得完整的示例源代碼,請(qǐng)?jiān)L問 下載 中的鏈接)。
首先,需要準(zhǔn)備好一些東西:
-
獲得一個(gè) jruby-complete.jar(
參考資料
中有下載鏈接)。
-
安裝 Monkeybars 庫??梢宰鳛?gem 安裝它:
sudo gem install monkeybars
也可以從 gitorious.org 上的庫中獲取最新的源代碼(參見 參考資料 )。
-
安裝
rawr
gem:sudo gem install rawr
嚴(yán)格地講,rawr
對(duì)于編寫 Monkeybars 應(yīng)用程序不是必需的,但是它提供了很多有用的rake
任務(wù),可以將 JRuby 應(yīng)用程序轉(zhuǎn)換成可執(zhí)行的 JAR 文件。本文的示例將使用它。
示 例應(yīng)用程序是一個(gè) “flash card” 程序,它讀取一個(gè)文本文件,其中定義有很多 “卡片”。它循環(huán)運(yùn)行,直到被關(guān)閉,它周期性地短暫顯示和隱藏自己?;旧?,它是一個(gè)學(xué)習(xí)工具。對(duì)于這個(gè)示例,這些卡片是一組德語單詞和短語。該程序還讀 取一個(gè)配置文件,該文件定義一個(gè)卡片定義文件的位置和一些設(shè)置(顯示/隱藏速度,窗口大小)。
這個(gè)示例的目標(biāo)是:
- 展示 Monkeybars 代碼生成器的使用,它可以自動(dòng)創(chuàng)建普通的文件
- 展示 Monkeybars 應(yīng)用程序的基本結(jié)構(gòu)
- 演示 Monkeybars MVC 組每個(gè)部分的創(chuàng)建
- 展示 Monkeybars 如何處理應(yīng)用程序數(shù)據(jù)到 UI 組件的映射
- 展示如何將應(yīng)用程序打包為可執(zhí)行的 JAR 文件
安裝后,Monkeybars 提供一個(gè)命令行腳本,用于創(chuàng)建一組初始的應(yīng)用程序文件。要開始一個(gè)新的 Monkeybars 項(xiàng)目,可以執(zhí)行隨 gem 安裝的
monkeybars
腳本。將項(xiàng)目命名為
monkey_see
:
$ monkeybars monkey_see |
這樣會(huì)在給定的路徑下(或者,如果只提供應(yīng)用程序的名稱,則在當(dāng)前目錄下)創(chuàng)建一個(gè)新的目錄,并添加用于新應(yīng)用程序的核心文件和目錄。
rawr
是源于 Monkeybars 的另一個(gè) Ruby 庫。它處理各種打包任務(wù),并提供一個(gè)命令行腳本,用于創(chuàng)建一個(gè)基本的 Java 類,Monkeybars 應(yīng)用程序可以使用這個(gè) Java 類來作為 Java 程序執(zhí)行(而不是通過 JRuby 使應(yīng)用程序作為一個(gè) Ruby 程序運(yùn)行)。
對(duì)于這個(gè) Monkeybars 應(yīng)用程序,為了使用
rawr
,可進(jìn)入項(xiàng)目目錄,并執(zhí)行
rawr
腳本:
$ cd money_see; rawr install |
您已經(jīng)看到了 Monkeybars 如何劃分模型、視圖和控制器。慣例是將這些文件放在相同的目錄中。Monkeybars 提供了一個(gè)
rake
任務(wù),用于生成這些文件。您可以創(chuàng)建其中任何一個(gè)文件或全部 3 個(gè)文件(后者更常見):
$ rake generate ALL=src/flash |
該命令在 src/ 下創(chuàng)建一個(gè)名為 flash 的子目錄,其中有 3 個(gè)文件:flash_controller.rb、flash_view.rb 和 flash_model.rb。前兩個(gè)文件有從基本 Monkeybars 類繼承而來的骨架類。模型代碼則不是這樣;Monkeybars 并不假定您如何管理應(yīng)用程序邏輯和數(shù)據(jù);那完全由您決定。
![]() ![]() |
![]()
|
對(duì) 于應(yīng)用程序的界面,需要一個(gè) Swing 類,以顯示 flash-card 數(shù)據(jù)。如何創(chuàng)建這個(gè) Swing 類由您決定。Monkeybars 中沒有任何東西使它與任何特定的 UI 工具或 Swing 代碼生成器綁定。按照慣例,Swing 文件與它的相關(guān)元組放在同一個(gè)目錄中(src/flash/FlashFrame.java)。您需要知道類包,以便將它傳給視圖類(使用
flash
包,并將類命名為
FlashFrame
)。
您的屏幕布局看上去應(yīng)該如圖 1 所示:
圖 1. 應(yīng)用程序的屏幕布局

一些關(guān)鍵點(diǎn):應(yīng)該使用一個(gè)
JTextPane
來顯示 flash-card 的內(nèi)容,以便使用 HTML 來格式化所呈現(xiàn)的文本。另外,對(duì)于文本面板和按鈕,還應(yīng)該使用容易理解的名稱。這樣一來,在處理視圖時(shí),就更容易知道一些關(guān)于 UI 組件的信息。這個(gè)程序的代碼是用 Ruby 編寫的,所以應(yīng)使用 Ruby 命名慣例:將文本命名為
pane card_pane
,將兩個(gè)菜單項(xiàng)命名為
edit_menu_item
和
quit_menu_item
。另外再為它們提供快捷鍵。
幀本身的名稱并不重要。視圖類可以直接按名稱引用組件。
模 型管理指定 UI 背后的應(yīng)用程序邏輯和數(shù)據(jù)。一個(gè) Monkeybars 程序通常對(duì)于每個(gè) Java 窗體有一個(gè)模型。示例應(yīng)用程序只有一個(gè)模型,用于處理 flash-card 數(shù)據(jù)。模型代碼需要能夠從一個(gè)已知的位置裝載數(shù)據(jù),并提供一個(gè)公共方法用于提供那些數(shù)據(jù)。
為簡單起見,將數(shù)據(jù)存儲(chǔ)在應(yīng)用程序運(yùn)行時(shí)所在子目錄下的一個(gè)文本文件中。這里不要硬編碼 HTML,而是使用 Textile 標(biāo)記,并使用 RedCloth Ruby 庫來轉(zhuǎn)換它。每個(gè)卡片條目由一個(gè)分隔字符串分隔開。
Textile 是一個(gè)文本標(biāo)記格式,用于使用簡單的純文本慣例定義 HTML。例如,為了表示
<em>italicized</em>
,可以編寫
_italicized_
。RedCloth 是一個(gè)以 gem 的形式提供的 Ruby 庫,它可以將 Textile 格式的文本轉(zhuǎn)換成 HTML。
Rubygems 使得安裝和使用第三方的庫變得非常容易,但是,由于您想將代碼打包到一個(gè) JAR 中,并且還可能發(fā)布它,所以需要確保與應(yīng)用程序相關(guān)的所有代碼都被打包。為此,解壓 RedCloth gem,并將 redcloth.rb 文件復(fù)制到項(xiàng)目的 ruby/lib/ 目錄中:
$ cd /tmp; gem unpack RedCloth |
這將創(chuàng)建 /tmp/RedCloth-3.0.4 /(除非安裝了不同版本的 gem)。將 /tmp/RedCloth-3.0.4/lib/redcloth.rb 復(fù)制到
monkey_see
項(xiàng)目的 lib/ruby/ 目錄。
通常,不屬于應(yīng)用程序核心部分的任何 Ruby 庫都應(yīng)該放在 lib/ruby/ 中(這是慣例)。如果使用 gem,那么需要解壓實(shí)際的庫文件,并將它們添加到項(xiàng)目中。在本文的后面,您將看到怎樣告訴程序如何發(fā)現(xiàn)這些文件。
load_cards
方法從磁盤讀取文本文件,劃分出每個(gè)卡片,并將結(jié)果賦給
@cards
實(shí)例變量。
select_card
方法隨機(jī)選取一張卡片,并將它賦給
@current_card
實(shí)例變量。您將使用
attr_accessor
來定義用于讀取和設(shè)置這個(gè)變量的方法。
無論 UI 中顯示哪張卡片,都可以在那里編輯它。經(jīng)過編輯之后,
update_current_card
方法獲取
@current_card
的內(nèi)容,并重新將它插入到
@cards
數(shù)組中。
save
方法將
@cards
數(shù)組寫回到磁盤。
current_card
方法的值就是要呈現(xiàn)的值,為了呈現(xiàn)這個(gè)值,需要一個(gè)視圖類。
Monkeybars 視圖類是 Java Swing 類的所有者。如果打開
flash_view.rb
,可以看到,它調(diào)用了一個(gè)類方法
set_java_class
。這應(yīng)該被設(shè)置成為這個(gè)視圖定義的 Swing 類。在您的代碼中,這是
flash.FlashFrame
。
通常,一個(gè) Monkeybars 視圖類需要做 3 件事:
- 將數(shù)據(jù)傳入和傳出 Swing 組件
- 管理各種以視圖為中心的行為(例如大小和位置)
- 對(duì)控制器發(fā)出的信號(hào)做出響應(yīng)
Monkeybars 提供了一個(gè)
map
方法,通過該方法可以定義如何將模型方法連接到 Swing 控件。最簡單的用法是連接一個(gè) UI 組件方法和一個(gè)模型方法:
map :view => :card_pane.text, :model => :current_card |
該映射使用默認(rèn)行為,即使之成為一個(gè)直接的、雙向的關(guān)聯(lián)。也就是說,card_pane 組件的
text
方法的結(jié)果被傳遞到模型的
current_card=
方法。當(dāng)根據(jù)模型更新視圖時(shí),這個(gè)過程又反過來了:
model.current_card
填充
card_pane.text.
(注意:JRuby 處理 Ruby/Java 命名轉(zhuǎn)換,所以實(shí)際的 Swing 方法
setText
可以使用
set_text =
來調(diào)用。)
這種簡單的映射常常很好用,但是在某些時(shí)候,由于數(shù)據(jù)類型、格式或某個(gè)應(yīng)用程序邏輯的不同,您不希望直接進(jìn)行數(shù)據(jù)交換。Monkeybars 允許在數(shù)據(jù)交換中使用中介。可以為映射傳遞一個(gè)
:using
參數(shù)(即指向一個(gè)數(shù)組的一個(gè) hash 鍵),該參數(shù)表明當(dāng)將數(shù)據(jù)從模型轉(zhuǎn)移到視圖和從視圖轉(zhuǎn)移到模型時(shí)所使用的替代方式(使用
:using
的另一個(gè)原因是處理這樣的情況,即需要用不符合常規(guī)的
getProperty
和
setProperty
模式的組件方法或子對(duì)象來操縱 Swing 組件的值或狀態(tài))。
對(duì)于您的代碼,需要從模型中獲取一個(gè) Textile 格式的字符串,并在將它賦給
card_pane
text
屬性之前將它轉(zhuǎn)換成 HTML。為此,您將創(chuàng)建
to_html
方法。另外,您不想直接從視圖中更新模型的
current_card
值。在視圖中,您將有專門的代碼用于編輯卡片,所以在本應(yīng)使用 view-to-model 之類的方法名的地方,您將使用
nil
。
結(jié)果就是這樣的映射:
map :view => :content_pane.text, |
您還希望 Swing 幀以特定的方式顯示。默認(rèn)情況下,Swing 幀出現(xiàn)在屏幕的左上角。對(duì)于您的應(yīng)用程序,您希望它顯示在屏幕的右上角。您還將給它一個(gè)幻燈片效果,使它不至于突然地出現(xiàn)和消失。
視圖類有一個(gè)專用的實(shí)例變量
@main_view_component
,它引用相應(yīng)的 Swing 類。視圖代碼通過這個(gè)對(duì)象與 Swing 組件交互。例如,為了更改 flash-card 文本面板的內(nèi)容,可以編寫:
@main_view_component.card_pane.text = "Some new text" |
但是,這種代碼實(shí)際上正是需要視圖類存在的理由,所以 Monkeybars 讓您不必顯式地使用
@main_view_component
,而是直接引用它的組件:
card_pane.text = "Some new text" |
基本
Monkeybars::View
類使用
method_missing
來攔截那樣的代碼,看它是不是一個(gè)組件引用,如果是,則將請(qǐng)求委托給
@main_view_component
。
方法是在 Swing 類上調(diào)用的,不過需要顯式的引用:
@main_view_component.width = 500 |
為了取得精美的幻燈片效果,視圖類有一些用于操縱 Swing 幀的高度和位置的方法,以便圖形化地對(duì)它進(jìn)行縮放,使得在每個(gè)呈現(xiàn)周期中,它從屏幕的頂端滑下,然后又縮回。
Monkeybars 被設(shè)計(jì)用來解耦 MVC 元組的關(guān)鍵部分。由于視圖有對(duì) Java Swing 對(duì)象的直接引用,因此它通常是最難以測試的部分。Monkeybars 的目的是減少視圖與模型和控制器的直接交互。但是,控制器負(fù)責(zé)處理 UI 事件。不可避免的是,這意味著控制器需要指導(dǎo)視圖做出響應(yīng)。但是,控制器并不直接與視圖類通信。相反,它使用信號(hào)。
稍后您將看到控制器端的情況。在視圖中,您需要使用
define_signal
方法定義信號(hào)處理程序。它帶有 2 個(gè)參數(shù),一個(gè)是信號(hào)名稱,另一個(gè)是用于處理那個(gè)信號(hào)的視圖方法:
define_signal :name => :initialize, |
處理程序方法必須帶 2 個(gè)參數(shù):一個(gè)是模型(從控制器傳入),另一個(gè)是傳輸對(duì)象。傳輸對(duì)象是一個(gè)短暫的 hash,用于在控制器與視圖之間來回移動(dòng)數(shù)據(jù)。視圖中有為 UI 的初始位置、幻燈片出現(xiàn)、幻燈片消失定義的信號(hào),還有 2 個(gè)分別為開始和結(jié)束卡片編輯而定義的信號(hào)。每種信號(hào)的處理程序都很短。下面是
do_roll_up method
:
def do_roll_up model, transfer |
編輯序列是通過菜單事件觸發(fā)的。
Edit
菜單項(xiàng)控制編輯。在視圖中,編輯序列意味著設(shè)置
card_pane.editable = true
,然后用原始的 Textile 卡片文本換出用 HTML 呈現(xiàn)的內(nèi)容。另外還需要更改組件的內(nèi)容類型,以便它正確地呈現(xiàn)純文本。
當(dāng)編輯完成時(shí),則執(zhí)行相反的過程。面板呈現(xiàn) HTML,而
editable
則被設(shè)置為
false
。視圖只負(fù)責(zé)管理 Swing 組件的狀態(tài);控制器則指示模型執(zhí)行文本更新和保存。
![]() |
|
您 的 Swing 對(duì)象有一些菜單項(xiàng),但是不必將任何用于這些菜單項(xiàng)的代碼放到視圖類中。那些代碼屬于控制器??刂破魈幚硭?UI 事件,例如單擊按鈕、選擇菜單以及更改文本字段。Monkeybars 為此作了安排,在默認(rèn)情況下,來自 Swing 代碼的所有事件都被毫無察覺地處理。對(duì)于您關(guān)心的那些事件,必須定義事件處理程序。在這個(gè)示例應(yīng)用程序中,需要捕捉的事件是單擊菜單。
事件處理程序的形式如下:
def your_component_name_action_performed |
(如果想在代碼中使用實(shí)際的 Swing 事件,也可以在定義處理程序時(shí)以實(shí)際的 Swing 事件作為參數(shù)。)
要處理 Quit 菜單項(xiàng),只需退出:
def quit_menu_item_action_performed |
Edit 菜單動(dòng)作則復(fù)雜一點(diǎn):
def edit_menu_item_action_performed |
以上代碼通過使用信號(hào)驅(qū)動(dòng)視圖來處理編輯模式的開關(guān)。要注意的關(guān)鍵一點(diǎn)是,卡片文本是如何通過使用控制器的模型實(shí)例(通過信號(hào)暗中傳遞給視圖)和
view_model
方法提供的視圖的模型副本進(jìn)行轉(zhuǎn)移的。
每當(dāng)控制器需要用戶界面的當(dāng)前狀態(tài)時(shí),它可以使用
view_state
方法來引用視圖的模型副本和當(dāng)前的傳輸對(duì)象。由于從
view_state
獲取模型副本非常常見,所以 Monkeybars 提供了
view_model
方法。
您的控制器還有一個(gè)用于實(shí)現(xiàn)初始呈現(xiàn)的方法和一個(gè)用于顯示/隱藏顯示序列的方法。這兩個(gè)方法都使用信號(hào)將實(shí)際的顯示代碼交給視圖處理。
![]() ![]() |
![]()
|
除了一個(gè)或多個(gè) MVC 元組外,Monkeybars 應(yīng)用程序還使用 2 個(gè)關(guān)鍵的助手文件來準(zhǔn)備和運(yùn)行代碼。
這 2 個(gè)文件都在 src/ 目錄中。manifest.rb 文件設(shè)置庫裝載路徑,并允許根據(jù)程序是直接從文件系統(tǒng)運(yùn)行還是從一個(gè) JAR 文件運(yùn)行來定義包括哪些文件。
之前,您已將
redcloth.rb
添加到 lib/ruby/ 中。為了讓應(yīng)用程序能找到這個(gè)文件,需要將那個(gè)目錄添加到裝載路徑中。對(duì)于 lib/java/ 目錄也是如此。所以,應(yīng)確保 manifest.rb 包括以下幾行:
add_to_load_path "../lib/java" |
main.rb 也是在 src/ 中。這是應(yīng)用程序的 Ruby 入口點(diǎn)。除了其他事情外,它定義一個(gè)全局錯(cuò)誤處理程序,在此將放置在執(zhí)行主應(yīng)用程序邏輯之前要運(yùn)行的特定于平臺(tái)的代碼。
示例程序使用一個(gè)簡單的循環(huán):
begin |
![]() ![]() |
![]()
|
![]() |
|
有了代碼以及合適的數(shù)據(jù)文件后,就可以運(yùn)行程序。使用一個(gè)
rawr rake
任務(wù)創(chuàng)建一個(gè)可執(zhí)行的 JAR 文件。如果在項(xiàng)目的一開始運(yùn)行了
rawr install
,那么它會(huì)在 src/org/rubyforge/rawr/ 下創(chuàng)建一個(gè) Main.java 文件。從 JAR 運(yùn)行程序需要一個(gè) Main Java 類;
rawr
可以生成這個(gè)文件,它包含查找和解釋 main.rb 文件的基本代碼(或者,如果沒有找到該文件,它將創(chuàng)建一個(gè)這樣的文件,并使用該文件)。
rake
rawr:jar
任務(wù)編譯該代碼,并將文件打包到一個(gè) JAR 中。build_configuration.yaml 文件用于協(xié)調(diào)此過程。在創(chuàng)建 JAR 之前,要先編輯這個(gè)文件,以反映應(yīng)用程序的細(xì)節(jié)。
要啟動(dòng)程序,首先構(gòu)建 JAR 文件:
$ rake rawr:jar |
然后調(diào)用它:
$ java -jar package/deploy/monkey_see.jar |
應(yīng)該可以看到 flash-card 屏幕從右上角滾下,停留一會(huì)兒,然后又向上滾回。
當(dāng)窗口可見時(shí),可以使用菜單項(xiàng)編輯當(dāng)前顯示的卡片。如果要退出,可以使用 Quit 菜單項(xiàng)(如果添加了快捷鍵 Alt+Q 的話,也可以使用該快捷鍵)。
![]() ![]() |
![]()
|
作 為 Ruby 的傳統(tǒng) C 實(shí)現(xiàn)的健壯的、可用的替代品,JRuby 意味著 Ruby GUI 工具包可以超越其他使用 C 實(shí)現(xiàn)的工具包,而使用為 Java 平臺(tái)提供的 UI 工具。由于 Swing 是 Java 運(yùn)行時(shí)安裝的一個(gè)標(biāo)準(zhǔn)部分,Swing 組件為 (J)Ruby 提供了一個(gè)成熟的、可立即使用的圖形工具包。使用 Java 平臺(tái)意味著應(yīng)用程序很容易在多個(gè)平臺(tái)上構(gòu)建、打包和發(fā)布給用戶。通過使用 Monkeybars 庫,Ruby 開發(fā)人員可以更輕松地構(gòu)建易于測試和維護(hù)的復(fù)雜的桌面應(yīng)用程序。
本文的示例非常簡單,它主要介紹在 JRuby Swing GUI 開發(fā)中可以做什么事情。在 Monkeybars 站點(diǎn)可以找到更多的信息和更復(fù)雜的示例(參見 參考資料 )。
![]() ![]() |
![]()
|
描述 名字 大小 下載方法 本文的樣例代碼
j-monkeybars.zip | 25KB | HTTP |
![]() |
||
![]() |
關(guān)于下載方法的信息 |
![]() |
學(xué)習(xí)
-
Monkeybars
:用于 Monkeybars 庫的 API 文檔、教程和示例。
-
JRuby
:訪問 JRuby 站點(diǎn)。
-
“
脫離 Rails 看 Ruby
”(Andrew Glover,developerWorks,2005 年 12 月):這篇文章概述了除 Ruby on Rails 以外,Java 開發(fā)人員可以使用 Ruby 做什么事情。
-
訪問
Ruby and Rails 技術(shù)資源中心
,這里整理了和 Ruby 動(dòng)態(tài)語言以及十分流行的開源 Web 開發(fā)框架 Ruby on Rails 相關(guān)的技術(shù)文章、教程和相關(guān)資源。
-
FxRuby
、
WxRuby
、
QtRuby
、
GTK-Ruby
和
Shoes
:找到更多關(guān)于這些面向 Ruby 的 GUI 工具包的信息。
-
Profligacy
和
Cheri::Swing
:這些庫使 Swing 交互更具 Ruby 風(fēng)格,但是不能處理復(fù)雜的 UI。
-
Swing
:查看 Swing 包文檔。
-
瀏覽
技術(shù)書店
,找到關(guān)于這些技術(shù)主題和其他技術(shù)專題的書籍。
-
developerWorks Java 技術(shù)專區(qū)
:這里有數(shù)百篇關(guān)于 Java 編程方方面面的文章。
獲得產(chǎn)品和技術(shù)
-
JRuby
:下載 jruby-complete.jar。
-
Monkeybars
:下載最新的 Monkeybars 源代碼。
![]() |
||
![]() |
James Britt 是 Happy Camper Studios 的負(fù)責(zé)人,這是位于亞利桑那州菲尼克斯市的一家 Ruby 應(yīng)用程序開發(fā)公司。作為 Ruby 社區(qū)的活躍分子,James 曾在美國和歐洲的 Ruby 會(huì)議上發(fā)表演講,并在 Dr. Dobbs 和 Linux Journal 等出版物上發(fā)表了多篇技術(shù)文章。他為 Hal Fulton 所著的書籍 The Ruby Way 的第 2 版撰寫了大部分有關(guān) Web 開發(fā)的內(nèi)容。James 還創(chuàng)建和維護(hù)了 Ruby-doc.org 網(wǎng)站,這是 Ruby 語言的主要文檔站點(diǎn)。 |
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
