淺談Swing支持透明和不規(guī)則窗口
讓Swing支持透明和不規(guī)則窗口已經(jīng)成為 AWT 和 Swing 團隊長久以來夢寐以求的功能。盡管本機應用程序在主要操作系統(tǒng)上使用這項功能已經(jīng)為時已久,但在核心 Java 中還不能使用它。即將發(fā)布的 “Consumer JRE”正在進行修改,也就是對 Java SE 6 進行重大更新。Java SE 6 將為創(chuàng)建不規(guī)則、全透明和每個像素透明的***窗口提供 API.
歷史本機應用程序的開發(fā)人員通常在開發(fā) UI 應用程序中享受了更高級的靈活性。但是為此而付出的代價是將應用程序限制在某一特定平臺上,在許多情況中,這種靈活性不如獲得更為豐富的 UI 體驗和桌面緊密集成那么重要。從傳統(tǒng)上講,跨平臺 UI 工具箱,例如 Swing、SWT、QT 和 wxWidgets 趨向于被動應付眾所周知的兩難問題。當只有某些目標平臺支持所要求的功能時怎么辦?在這種情況下,模擬缺失的功能可能只會讓您南轅北轍。
透明和不規(guī)則窗口是跨平臺 UI 工具箱局限性的***例子。如果在特定目標平臺不支持此項功能,那么在該平臺上就沒有什么更多事情要做了,此項功能可能用作強有力的參數(shù)向工具箱添加該項功能。但是,Swing 開發(fā)人員社區(qū)長久以來一直爭論主要目標平臺不久就會提供這些功能。事實上,Windows 自從 Windows 95 (參見 MSDN 上的 SetWindowRgn 文檔 )就已經(jīng)支持不規(guī)則窗口了。在 X11 中匹配功能自從 1989 年 ( 參見 X Nonrectangular Window Shape Extension Library PDF 文檔 )就已經(jīng)可用了。在 OS X 中您僅能在 JFrame 上設(shè)置透明的背景顏色。
直到現(xiàn)在,對跨平臺透明和不規(guī)則窗口有興趣的 Swing支持應用程序有三種主要可選方式。
在顯示目標窗口之前使用 java.awt.Robot 捕獲桌面。這種方法在 Joshua Marinacci 和 Chris Adamson 編寫的 《 Swing Hacks 》 書中的 第 41 章 中已經(jīng)進行了評述。
使用 JNI 包裝目標平臺的本機 API.使用由 Timothy Wall 開發(fā)的 JNA 庫。該庫在 2007 年問世,Timothy 對于 不規(guī)則窗口 和 字母掩碼透明度 已經(jīng)發(fā)表過博客。
***種方法的主要問題是要使用 Robot 類。即使您有權(quán)限獲得屏幕截圖,您也必須在顯示窗口之前完成。此外,如何保持桌面后臺同步?假設(shè)在后臺正在播放 YouTube 視頻。與窗口生成的事件不同( 調(diào)整大小,移動 ),AWT 并不在任何交叉窗口的重畫上提供注冊偵聽器的任何方式。雖然 Chris 和 Joshua 通過在至少每秒內(nèi)進行快照提供解決方法,這對于覆蓋后臺視頻播放還不夠。而且在每次快照前需要對窗口加以隱藏;這可能導致可見的閃爍。
使用 JNI 和 JNA 導致顯著的視覺保真性改進。純 JNI 會帶來開銷的急劇下降:您必須將目標平臺的每一個相關(guān)的 API 綁定,還要捆綁本機庫。JNA 為您分擔這項重任; 它捆綁主機庫并提供能在運行時提取并加載它們的類加載器。它支持 Linux、 OS X、 Windows、 Solaris 和 FreeBSD.
Consumer JRE Java SE 6 Update N, 通常稱作 Consumer JRE, 是 Sun 公司的努力成果,為重新配置 Java 將其作為開發(fā)富桌面應用程序的可行方法。在 Consumer JRE 中的新功能和主要改進列表相當廣泛,并將特別閃耀的寶石隱藏在***一周構(gòu)建代碼之一的發(fā)行說明中。Bug 6633275 被簡單地賦予“需要支持不規(guī)則/透明窗口”的標題。但是該實現(xiàn)核心 JDK 新功能的可能性所帶給 Swing 開發(fā)人員的意義是深遠的。本文的剩余部分將顯示能夠?qū)崿F(xiàn)和如何實現(xiàn)該功能的幾個示例。
在進一步研究之前,有一個非常重要的注意事項。由于 Consumer JRE 被官方認為是對穩(wěn)定 JDK 發(fā)行的一個次要更新,因此在“公共”包中不能添加任何新的 API( 類、方法等等 ),例如 java.awt 或 javax.swing. 在本文中討論的所有 API 在新 com.sun.awt.AWTUtilities 類中出現(xiàn),該類不是官方支持的部分 API.它在 Java SE 7 中的位置最有可能發(fā)生改變,簽名方法可能在現(xiàn)在和最終的 Consumer JRE 發(fā)行之間發(fā)生輕微變化。所以當這種改變發(fā)生時準備更改您自己的代碼。
AWTUtilities 類我首先討論 com.sun.awt.AWTUtilities 類,請參見Swing支持透明和不規(guī)則窗口 博客條目。
不規(guī)則的窗口看起來不是很好。窗口的邊緣呈鋸齒狀并且整體印象也不是很干凈。要獲得不規(guī)則窗口的更佳視覺效果,您必須使用 AWTUtilities.setWindowOpaque(Window, boolean) API,并使用柔性裁剪繪畫窗口背景。這在后續(xù)的 Swing 窗口的柔性裁剪和每像素透明度 博客條目中進行了闡明。對于窗口的左上角和右上角,該條目采用 Chris Campbell 的 柔性裁剪教程 以及 Romain Guy 的 反射教程, 其中包括 Sebastien Petrucci 的改進。
現(xiàn)在我們手頭上已經(jīng)有了這些 API,我們打算做些什么呢?對它們進行探索這種可能性當然是另人好奇的,我們正打算看看幾個多樣混合的示例。
工具提示讓我們使應用工具提示變得透明怎么樣?對于輕量級工具提示,實現(xiàn)這一目標是相當容易的,因為它們被作為 Swing ***窗口的一部分加以繪畫。( 要獲得關(guān)于輕量級彈出菜單的詳細信息,請參見 玻璃窗格和輕量級彈出菜單條目。)但是,一旦工具提示成為重量級并“打破”窗口綁定,您必須繼續(xù)采用 Robot 或 JNI/JNA.現(xiàn)在讓我們看一看使用 AWTUtilities API 如何完成這項任務。
【編輯推薦】