星期一, 12月 06, 2004

The Terminal

或許試試在對一部片子完全沒有認識的情況下進場觀賞也蠻有意思的,
就在這樣想法下,我竟然看到了一部在進場前讓我完全沒有期待的好片,
講真的,中文片名翻成【航站情緣】還真的是讓人有點沒力。

不過這部片真的很妙,出場後仔細看了一下海報上英文副標是Life is waiting。
回想一下的確在淡淡的劇情裡卻無時無刻不隱含這中心思想,
像Tom老爸等了一輩子的偶像簽名,Catherine等了一輩子的真愛,
老印清潔員每天唯一的樂事是等著看人滑倒 XD

其實愛情的成份在這部片子中著墨不多,但其中還是有段對話蠻有意思的。
或許執著於一段沒有未來的感情的人都是因為患了遠視的關係而看不清身邊的好人 :p

不過最扯的還是看著Tom扮演著無助,英語又不通的外勞?!
最後竟然也能把上Catherine這種超級美女。靠~這果然是美國夢的極致表現 XD

--
雖然像劇中主角這樣的遭遇很令人同情,想一想若是發生在現實中…
我咧~死老共,我出國時你可別亂來呀~ XD

星期一, 11月 01, 2004

邂逅日本美眉

話說今天原本想乘著最近換季折扣添購幾件新行頭,
走著走著不覺已到了傍晚,進了T大附近某G牌服飾店內閒逛時。
剛進去沒多久拿起一件外套正準備試穿時,
突然查覺到左後方有一陣不尋常的腳步聲接近著。

轉頭回去一看,不其然地跟一個小美眉四目相交望了一眼。
呵~小小被電了一下,不過還是馬上鎮靜下來裝著若無其事的繼續試穿。
小美眉突然走近問了句:
'請問你踢OX嗎?' 註:OX是因為她發音太奇怪一時聽不懂她在講啥。

怔了一下,"呣~妳說啥米?"
'喔~soccer、soccer,你有在踢足球嗎?'
重覆又問了一次,終於聽懂她在講啥。
"呃~沒有耶,我打籃球的…"

'喔~不好意思呢,因為你跟我男友身材有點像。'
'我想要買一件外套給他當禮物。'
'因為他現在人在日本所以可以請你幫我試一試這件外套嗎?'

"喔~沒問題呀~"
開玩笑美眉的指示怎敢不從。馬上以最快的速度脫了身上的外套,
試了試美眉手中所拿的外套。

'呣~你覺得這件外套怎麼樣呢?'
"呃~還不錯呀,蠻舒適的。"
心中OS:靠~我又不是你男友,問我覺得怎樣有啥用 :P

"對了,你是日本人嗎?"
'喔~是呀,我來台灣學中文的。'
"呵~那你中文算講得還不錯的哩~"
經由夜店之神Roberto的指導,我愈來愈能把握講謊…喔~不是,
是講甜言蜜語的時機及技巧。

接著哈啦了一陣有的沒的,沒想到這日本小美眉倒也挺龜毛的,
衣服是一件拿了又一件,搞的老子是脫了又換、換了又脫。
總是試不出一件她覺得滿意的。

當我心下正有所狐疑,四處觀望察看是否有攝影機存在。
該不會最近又出現啥米新型態的整人節目單元吧~
突然看到女店員在一旁偷笑,還虧我叫我不要臉紅。
呿~老子是因為被這小女生整得脫來換去,
搞得全身熱了起來,啥米臉紅不紅的。

最後我暗自下了個決定,看她又開始對這件外套猶豫不決想轉頭再去挑時,
趕緊鼓起三吋不爛之舌跟她推薦身上這件是有多舒適多好穿。
'呣~可是我男友好像比你矮一點點耶~'
'你再幫我試試這件size L的好嗎?'

靠~老子已經快受不了妳的龜毛了....
即將爆發的我還是耐著性子,裝著和顏悅色地神情幫她試了試M號的size。
"不過M號的好像袖子會短了點喔~"
'喔~應該還好,你好像還比我男友高一點點的樣子。'
"對了,你男友多高呀?"
'呣~好像是175的樣子。'
心中再度OS:小姐~我咧這叫身材很像嗎?我比你男友高了不止一個頭吧 \(╯▽╰)/

看到旁邊女店員幾乎已到了臨界點開始忍俊不禁爆笑起來。
我想也是時刻該結束這場鬧劇了。
直接拉著她往櫃台走去,強力推薦就是這件沒錯了。
"不然妳男朋友不喜歡妳買的禮物,妳乾脆跟他分手來找我好了" XD
總算在跟她約定了這個一生一世的誓言後,她滿意地買下了這件外套。
在門口與她說了聲"撒喲那啦~",互道珍重再會。

一陣雲淡風輕後,名偵探小P終於又了結了一件Case…
經此事件後得證,美眉們嬌縱任性的程度果然是不分國界呀~ XD

--

【以上故事中所提及任何個人、團體、場所,如有雷同,純屬虛構!!!】

星期日, 10月 31, 2004

【蛀蟲時間】老鼠起舞,大象當心

老鼠起舞,大象當心

剛在華納看完午夜場電影,興頭一起想著反正也睡不著了,
心裡想著想著就順道轉往蹲男誠品蹲蹲吧,或許有啥米新書剛出來也說不定。

雖然已是凌晨二點多,店裡人潮依舊擁擠,
嘿~突然在新書區發現令人期盼已久熟悉的封面。
原來洪老大的新書已經出來啦~

趕緊先A一本起來翻翻,內容果然十分精彩,一翻下去就停不了手哩。
尤其看到後來那段神奇公式:-1 + 1 > 0 時才發現,
原來還與前段提攜部屬的故事有前後呼應呀~

若以部屬比喻為水的話,正說明了水可載舟、亦可覆舟的道理。
適時給予部屬機會、激勵使得部屬得以水漲自然也得以船高囉~
不汲汲於爭功諉過更是顯現主事者管理技巧上的高明。

講起神奇公式還真有那麼點神來一筆的味道,
相信洪老二次在書中提到這個事件不是偶然。
應該算是職場生涯上蠻滿意的一次經驗分享。
再仔細想想作回頭客的生意,後續服務好壞與否可真是重要呀~
(雖然這又讓我想起買ViewSonic液晶螢幕時慘痛的送修經驗 >_< )

不過不曉得是否因有編輯介入,抑或是洪老已離開昇陽的緣故,
比起Java週報時期洪老專欄時常火力四射,引起許多話題。
感覺這次洪老大火力尚未全開,批判M牌公司的力道似乎小了許多 :p

俗話雖講外來的和尚會唸經,但比起啥米管理剩經,
笑佛學不到的管理之類的書籍。
洪老本土化的管理及職場經驗分享反而更值得一讀喔。

--
看起來存書並不多,手腳再不快的朋友可能得等二刷囉~

星期五, 10月 29, 2004

Embedded a Scripting Engine in Java Apps

在開發應用系統時,使用者有時往往會需要動態地執行程序或更新某些參數。
例如像是電信業的計費公式為了因應三不五時要推出特惠方案而更動、
或是銀行業核准信用貸款的判斷準則等。

但這個時候您可能又不想大費周章地自已搞一套Parser
來解析處理這些公式或規則,
嘿嘿~那麼最好的選擇就是內嵌一個Scripting Engine進來。
而且目前開源項目中已有許多使用Java實作出來各種語法的
Scripting Engine可供我們選擇囉~

更棒的是不但如此,大部份開放源碼的Scripting Engine
還支援了BSF(Bean Scripting Framework)。
http://jakarta.apache.org/bsf/index.html
不過講起來Java的世界就這點很奇怪,Framework特別多,
啥米東東不來個Framework這些人身上好像是會癢 :p

好了~再廢話我怕您會想扁我。言歸正傳…而這個BSF又是個啥米東東哩?
簡單講嘛沒啥就是提供一個共通的介面
將各家不同實作的Scripting Engine包裝起來。
於是乎我們可以很輕易地在系統中切換各種不同Scripting語法,
不過有個前提是這些Scripting Engine有支援BSF。

如此一來便可輕鬆提供多種不同語法供使用者選擇,
這一點相信可帶給系統使用者很大的便利。
甚或是我們可以內建一些predefine function
讓使用者能更直覺地用邏輯概念來組合出其所需的功能出來。

下面介紹一下,小弟實驗過確認可在BSF下執行正常的幾個Scripting Engine:

Rhino: JavaScript for Java

http://www.mozilla.org/rhino/index.html

註記:
雖說目前FAQ上寫支援BSF的版本為Rhino 1.5R2 or Rhino 1.5R3。
但經實測似乎只有Rhino 1.5R2這版可運行正常。


JRuby: Ruby for Java

http://jruby.sourceforge.net/index.shtml


Jython: Python for Java

http://www.jython.org/index.html


BeanShell: Lightweight Scripting for Java

http://www.beanshell.org

註記:
若是您覺得您不太想去重新學習或適應另一套Scripting語法,
想使用一個支援Java語法的Scripting Engine的話。
您可以選擇使用BeanShell。


最後提供一個Expression Evaluator的範例程式,大家可以參考試試看囉 ^_^
對了!!!執行前要記得將各個要用到的
Scripting Engine相對應的jar檔設定到classpath下喔~

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import org.apache.bsf.*;

public class ExpressionEvaluator
extends JFrame implements java.awt.event.ActionListener {
private JPanel ivjContentsPane = null;
private BorderLayout ivjContentsPaneBorderLayout = null;
private JLabel ivjLabel1 = null;
private JPanel ivjPanel1 = null;
private GridLayout ivjPanel1GridLayout = null;
private JPanel ivjPanel2 = null;
private BorderLayout ivjPanel2BorderLayout = null;
private JPanel ivjPanel3 = null;
private GridLayout ivjPanel3GridLayout = null;
private JPanel ivjPanel4 = null;
private JButton ivjButtonClearResults = null;
private JButton ivjButtonClearScript = null;
private JButton ivjButtonEvaluate = null;
private JComboBox ivjLanguageChoice = null;
private JTextArea ivjTextAreaResults = null;
private JTextArea ivjTextAreaScript = null;
private String language = "javascript";
BSFManager _mgr = null;
Hashtable _htEngines = null;

public ExpressionEvaluator() {
super();
initialize();
}

public ExpressionEvaluator(String title) {
super(title);
initialize();
}

public void actionPerformed(java.awt.event.ActionEvent e) {
if ( (e.getSource() == getButtonClearResults())) {
try {
getTextAreaResults().setText("");
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}

}
if ( (e.getSource() == getButtonEvaluate())) {
try {
this.buttonEvaluateClick();
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}

}
if ( (e.getSource() == getButtonClearScript())) {
try {
getTextAreaScript().setText("");
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}

}

}

public void buttonEvaluateClick() {
evaluate();
}

public void evaluate() {

language = getLanguageChoice().getName();
String scriptText = getTextAreaScript().getText();

System.out.println("Evaluating: {\n" + scriptText + "\n}");
System.out.println("Language: " + language);
Object oResult = null;
try {
getTextAreaResults().setForeground(java.awt.Color.black);
oResult = _mgr.eval(language, "Evaluator", 0, 0, scriptText);
}
catch (Exception ex) {
getTextAreaResults().setForeground(java.awt.Color.red);
oResult = "Exception: " + ex.getMessage();
ex.printStackTrace();
}
System.out.println("oResult:’" + oResult + "’");
getTextAreaResults().setText(oResult.toString());
}

private JButton getButtonClearResults() {
if (ivjButtonClearResults == null) {
try {
ivjButtonClearResults = new JButton();
ivjButtonClearResults.setName("ButtonClearResults");
ivjButtonClearResults.setText("Clear results");
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjButtonClearResults;
}

private JButton getButtonClearScript() {
if (ivjButtonClearScript == null) {
try {
ivjButtonClearScript = new JButton();
ivjButtonClearScript.setName("ButtonClearScript");
ivjButtonClearScript.setText("Clear script");
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjButtonClearScript;
}

private JButton getButtonEvaluate() {
if (ivjButtonEvaluate == null) {
try {
ivjButtonEvaluate = new JButton();
ivjButtonEvaluate.setName("ButtonEvaluate");
ivjButtonEvaluate.setBackground(Color.lightGray);
ivjButtonEvaluate.setText("Evaluate");
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjButtonEvaluate;
}

private JPanel getContentsPane() {
if (ivjContentsPane == null) {
try {
ivjContentsPane = new JPanel();
ivjContentsPane.setName("ContentsPane");
ivjContentsPane.setLayout(getContentsPaneBorderLayout());
ivjContentsPane.setBackground(new Color(172, 179, 191));
getContentsPane().add(getPanel2(), "North");
getContentsPane().add(getPanel1(), "Center");
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjContentsPane;
}

private java.awt.BorderLayout getContentsPaneBorderLayout() {
java.awt.BorderLayout ivjContentsPaneBorderLayout = null;
try {
ivjContentsPaneBorderLayout = new java.awt.BorderLayout();
ivjContentsPaneBorderLayout.setVgap(10);
ivjContentsPaneBorderLayout.setHgap(10);
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}

return ivjContentsPaneBorderLayout;
}

public BSFEngine getEngine(String langname) {
if (_htEngines != null) {
return (BSFEngine) (_htEngines.get(langname));
}
return null;
}

private JLabel getLabel1() {
if (ivjLabel1 == null) {
try {
ivjLabel1 = new JLabel();
ivjLabel1.setName("Label1");
ivjLabel1.setFont(new java.awt.Font("dialog", 1, 12));
ivjLabel1.setText("Language");
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjLabel1;
}

private JComboBox getLanguageChoice() {
if (ivjLanguageChoice == null) {
try {
ivjLanguageChoice = new JComboBox();
ivjLanguageChoice.setName("javascript");
ivjLanguageChoice.setBackground(Color.white);
ivjLanguageChoice.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox) e.getSource();
ivjLanguageChoice.setName( (String) cb.getSelectedItem());

}
});
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjLanguageChoice;
}

private JPanel getPanel1() {
if (ivjPanel1 == null) {
try {
ivjPanel1 = new JPanel();
ivjPanel1.setName("Panel1");
ivjPanel1.setLayout(getPanel1GridLayout());
getPanel1().add(getTextAreaScript(),
getTextAreaScript().getName());
ivjPanel1.add(getTextAreaResults());
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjPanel1;
}

private java.awt.GridLayout getPanel1GridLayout() {
java.awt.GridLayout ivjPanel1GridLayout = null;
try {
ivjPanel1GridLayout = new java.awt.GridLayout(2, 1);
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}

return ivjPanel1GridLayout;
}

private JPanel getPanel2() {
if (ivjPanel2 == null) {
try {
ivjPanel2 = new JPanel();
ivjPanel2.setName("Panel2");
ivjPanel2.setLayout(getPanel2BorderLayout());
getPanel2().add(getPanel3(), "South");
getPanel2().add(getPanel4(), "North");
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjPanel2;
}

private java.awt.BorderLayout getPanel2BorderLayout() {
java.awt.BorderLayout ivjPanel2BorderLayout = null;
try {
ivjPanel2BorderLayout = new java.awt.BorderLayout();
ivjPanel2BorderLayout.setVgap(5);
ivjPanel2BorderLayout.setHgap(5);
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}

return ivjPanel2BorderLayout;
}

private JPanel getPanel3() {
if (ivjPanel3 == null) {
try {
ivjPanel3 = new JPanel();
ivjPanel3.setName("Panel3");
ivjPanel3.setLayout(getPanel3GridLayout());
getPanel3().add(getButtonEvaluate(),
getButtonEvaluate().getName());
getPanel3().add(getButtonClearScript(),
getButtonClearScript().getName());
getPanel3().add(getButtonClearResults(),
getButtonClearResults().getName());
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjPanel3;
}

private java.awt.GridLayout getPanel3GridLayout() {
java.awt.GridLayout ivjPanel3GridLayout = null;
try {
ivjPanel3GridLayout = new java.awt.GridLayout();
ivjPanel3GridLayout.setColumns(3);
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}

return ivjPanel3GridLayout;
}

private JPanel getPanel4() {
if (ivjPanel4 == null) {
try {
ivjPanel4 = new JPanel();
ivjPanel4.setName("Panel4");
ivjPanel4.setLayout(new java.awt.BorderLayout());
getPanel4().add(getLabel1(), "West");
getPanel4().add(getLanguageChoice(), "Center");
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjPanel4;
}

private JTextArea getTextAreaResults() {
if (ivjTextAreaResults == null) {
try {
ivjTextAreaResults = new JTextArea();
ivjTextAreaResults.setName("TextAreaResults");
ivjTextAreaResults.setBackground(Color.lightGray);
ivjTextAreaResults.setFont(new java.awt.Font(
"monospaced", 1, 12));
ivjTextAreaResults.setEditable(false);
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjTextAreaResults;
}

private JTextArea getTextAreaScript() {
if (ivjTextAreaScript == null) {
try {
ivjTextAreaScript = new JTextArea();
ivjTextAreaScript.setName("TextAreaScript");
ivjTextAreaScript.setBackground(Color.white);
ivjTextAreaScript.setEditable(true);
}
catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjTextAreaScript;
}

private void handleException(Throwable exception) {

System.out.println(
"--------- UNCAUGHT EXCEPTION ---------");
exception.printStackTrace(System.out);
}

private void initConnections() {
getButtonClearResults().addActionListener(this);
getButtonEvaluate().addActionListener(this);
getButtonClearScript().addActionListener(this);
}

private void initialize() {
setName("ExpressionEvaluator");
setTitle("BSF Expression Evaluator");
setSize(426, 240);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container cp = this.getContentPane();

cp.setLayout(new BorderLayout());
cp.setBackground(new java.awt.Color(228, 223, 228));
cp.setForeground(new java.awt.Color(0, 48, 104));
cp.add(getContentsPane(), "Center");

initConnections();
initializeBSF();
}

protected void initializeBSF() {
if (_mgr == null) {

System.out.println("Initializing");
_mgr = new BSFManager();
_mgr.registerScriptingEngine("", "", new String[] {});
getLanguageChoice().addItem("javascript");
getLanguageChoice().addItem("ruby");
getLanguageChoice().addItem("jython");
getLanguageChoice().addItem("beanshell");
}
}

public static void main(java.lang.String[] args) {
try {
ExpressionEvaluator aExpressionEvaluator = new
ExpressionEvaluator();
aExpressionEvaluator.setVisible(true);
}
catch (Throwable exception) {
exception.printStackTrace();
}
}
}

星期日, 10月 10, 2004

願景VS畫大餅

夢想總是美好的而夢醒後的現實卻是那麼地殘酷。
描繪美好願景與畫大餅之間往往只是一線之隔。
但其實有沒有開誠佈公把如何實踐願景的部份,
拿出來與整個團隊討論是很重要的一件事。

往往看到一些領導者講好聽是在描繪願景,講難聽點就是畫大餅。
如果無法與伙伴們一起挽著袖口下來實踐,思想上的巨人、行動上的侏儒,
面對一意孤行的領導者最終我們只能對他說:千山您獨行、不必相送囉~

當然民主的討論對公司發展未必是件好事,
人多嘴雜往往導引而來天馬行空的意見更多。
但是一個好的領導者應該要像傳教士般不停地傳達自已的信仰,
慢慢引導及轉化讓追隨者真心相信這個願景,
接著才能一起努力實踐,
不是領導者的、你的、也不是我的,而是大家共同的願景。

若是上下交相賊,同床異夢的團隊。
那難保每個人的心態不會如同國共抗日時,
共產黨所謂七分發展,二分應付、一分抗日囉~
理想的狀況應該是讓理念相同的人自然結合,
而有不同理想的人就讓他去尋別的夢吧。
當每個人都為自已的理念奮鬥的時候,整個團隊自然能發揮最大效益。
即使最後不見得能到達夢中的彼岸,但至少大家一起努力過也能使心中無悔吧。