跳到主要內容

Processing + Swing = Grider App


用Processing來處理一些連續圖像和影片實在相當方便,簡單幾行就可以搞定。對熟悉程式碼的人來說是這麼回事,但是要給不會看程式碼的人用,還是做個圖形界面會比較方便。適逢Processing釋出2.0 beta版,就順道把先前做的影片打格子程式,也就是那個姑且被我稱作Grider的程式做了一個小小的升級改版,整合Swing為它加上簡單的使用者界面。



之前評論道Processing所使用的函式庫有點過時,那個時候我使用的版本還是1.5,而2.x版則還在相當alpha的階段。不過,前些天重新逛了Processing.org的網站,發現幾乎所有的文件與範例,都已經更新成為2.x版本,便下載了2.0b7來改寫要為影片打格子的程式。

如果你只要使用Processing基本的功能,應該是不會碰到processing.video這個package。但既然我們處理的是影片,想不碰到這個也不太可能。Processing 1.5的video是直接呼叫QTJava,但它是32位元的,而且也被Apple宣告過時。在前一個Grider版本中,我使用另外一個函式庫來處理影片,也就是GSVideo。展開Processing 2.0b7後才看到,GSVideo這個函式庫已經被包到processing.video裡頭,並且能用64位元的方式來跑。對於Mac使用者來說,真是一大福音,因為現在比較常用的版本幾乎都是64位元的,起碼從我手邊還會用到的10.6開始。

只不過,升級倒也不是沒有缺點。在1.5的版本中,processing.video本來有一個MovieMaker的class,可以直接輸出QuickTime或avi影片,這在Processing 2.0裡頭好像被拿掉了。還好,這個class對我沒有影響。

大致弄清楚Processing更動的部分後,便開始修改程式碼。首先把之前GSMovie的物件全都換回Processing裡頭的Movie,反正兩者是相同的,沒必要再去匯入一個函式庫。接著,便要開始橋接Processing和Swing兩個東西,對我來說,這是個新的挑戰。

開發Java使用者界面大致上就是兩個選擇,一個是SWT (The Standard Widget Toolkit),另外一個就是Swing。至於AWT,那個實在太麻煩,完全不在我的考慮範圍之內。我比較熟悉的是SWT,可是偏偏在Mac上,想做個SWT_AWT的橋接,或是要內嵌個Swing物件,總是會碰到Java CocoaComponent compatibility mode的問題,更新到目前最新的版本依然沒辦法解決,只好硬著頭皮使用Swing來做使用者介面。

用WindowBuilder來拉界面節省了很多時間,免除了猜測物件長相和功能的困擾。但這得要在eclipse裡面做,意味著要將Processing的主要函式庫給拿出來。這部分在Processing.org官網上有教學,請自行參考Processing in Eclipse。比較麻煩的是processing.video裡頭的東西,除了要把幾個jar檔案一併拉出來外,還要把macosx64的資料夾一起拉出來,否則影片根本沒辦法載入。



解決影片播放的問題後,接下來要把Processing的PApplet納入Swing當中。在PApplet的技術文件裡面,有一個簡化的範例,示範如何從AWT的Frame裡面將PApplet初始化。Swing的JFrame繼承了AWT的Frame,也可以使用同樣的方式。說穿了,不過是將PApplet當做一個component塞進Swing裡頭,在最後要記得呼叫 init() 去執行PApplet的內容。

 public class ExampleFrame extends Frame {

     public ExampleFrame() {
         super("Embedded PApplet");

         setLayout(new BorderLayout());
         PApplet embed = new Embedded();
         add(embed, BorderLayout.CENTER);

         // important to call this whenever embedding a PApplet.
         // It ensures that the animation thread is started and
         // that other internal variables are properly set.
         embed.init();
     }
 }

 public class Embedded extends PApplet {

     public void setup() {
         // original setup code here ...
         size(400, 400);

         // prevent thread from starving everything else
         noLoop();
     }

     public void draw() {
         // drawing code goes here
     }

     public void mousePressed() {
         // do something based on mouse movement

         // update the screen (run draw once)
         redraw();
     }
 }

解決這些麻煩的問題之後,剩下的就是使用者介面各個功能的調整。雖說比較沒有技術上的障礙,但這個部分似乎花了最多時間,有太多觸發事件得要處理。在一陣辛勞之後,Grider算是可以用了,只要再花些時間做些測試與修正,應該就可以釋出了。


留言

熱門文章

差不多食譜實驗:小烤箱烤長茄子? Oven-roasted Long Aubergine?

發佈了「 差不多食譜:小烤箱烤茄子 Oven-roasted Aubergine 」之後,有位朋友在YouTube上留言問說,這個方法也可以用在市場上比較常看到的那種長茄子嗎?當時我只能回答不知道,因為沒試過。現在我有答案了!結果是一半一半!

差不多食譜:香煎南瓜片 Pan-fried Pumpkin

托爺爺的福,在萬聖節那碗「 南瓜盅飯 」後,我還有個老家的南瓜可以用。但要怎麼好好運用這顆南瓜,卻是個不小問題。差不多食譜曾經試過「 醋漬南瓜 」、「 牛奶南瓜 」,還有「 南瓜濃湯 」幾種運用新鮮南瓜的料理,難度雖然都不高,看起來卻都不像平時會出現在餐桌的家常菜。這次我們不妨搞得家常一點,用廚房裡都會有菜刀和煎鍋 (除非你家不開伙) ,來弄個超級家常的「香煎南瓜片」。

上車睡覺、下車尿尿

台灣人對於旅遊的形容,往往是「上車睡覺、下車尿尿」。這是因為行程被極度壓縮,試圖要在最短的時間裡面看最多的東西,於是每個景點都只是蜻蜓點水般匆匆帶過,停留的時間往往等同於排隊上廁所的時間。 這個紫南宮的行程已在「人山人海的紫南宮」當中提到過,只是當初沒寫到為什麼要去參觀紫南宮。事實上,紫南宮最富盛名的是可以借錢的土地公。然而,這點對我們家人而言一點吸引力都沒有,反倒是那號稱七星級的廁所,才是吸引我們前往參拜的重點。或許你會說:「有沒有搞錯,開一個鐘頭的車去上廁所!」沒錯,行程就是這麼規劃的。 在過年期間要到紫南宮上廁所還不是件容易的事。首先,你必須先開車到紫南宮,這大概是最容易的部份。接著,你就得面臨搶停車位窘境。 過年期間,不論哪個景點都是人山人海,免費停車位更是難找。紫南宮雖然提供一大片停車場,在過年期間卻也不敷使用,每台進入停車場的車都虎視眈眈,只要哪邊出現一個車位,起碼就有四、五台車等著。 好不容易停好車,接下來就得穿越那群要去借錢、還錢、拜拜的人群。在那個地方,怎麼前進的都不知道,反正總會有人把你向前推進。 好不容易到達造價上億的廁所,人山人海的盛況依舊。還好這群並非全部都來上廁所,要不然廁所早就被塞爆了。聽老爸老媽說,上次他們來的時候廁所裡面都沒人,還可以在裡面拍照、欣賞噴水。但這次裡面卻塞了不少人,我也不好意思拿著那麼大的一台相機拍人家上廁所的模樣,只能拍拍外觀。 由於是在盛產竹筍的竹山鎮,廁所的外觀也用竹筍作為造型,每個竹筍下方都是一間造價昂貴的廁所。一個令我覺得很貼心的設計在於,廁所不僅僅只是男廁/女廁,還有一個殘障廁所,方便行動不便的人。 雖然招牌寫著「金筍迎客」,但是看起來那個筍子明明就是不鏽鋼的,除非把它理解成金屬。我還特地爬上廁所的樓頂,想說能不能看到些什麼特別的風景。可是過年期間,看到的除了人群還是人群。 上完廁所後,簡單徒手祭拜了提供廁所的土地公,我們又再次穿越那重重的人群。不過,我還是偷偷跑去滾了一下那個象徵「財源滾滾」的金元寶。最後,又踏上那個停車戰場,從容地離去。 我不奢望有賺大錢的機會,只要生活能過得去,偶爾還能買些奢侈品犒賞自己就夠了。不過這個願望似乎也不簡單!