2007年2月10日 星期六
2007年2月7日 星期三
我織的第一條圍巾
經過一個多禮拜的努力,我織的第一條圍巾終於正式地完成了,在這期間真的要大大地感謝靜嵐老師的幫忙,讓我從什麼都不會開始,慢慢從下針織法學起,拆線、接線、收線、編流蘇,每個步驟都是一門藝術。雖然過程並不容易,但是完成作品之後的成就感實在無法言喻,我覺得我好像也漸漸喜歡上了編織,只是編織藝術這種東西如果想要以看書、網路教學等方式自修似乎不太容易,以我的情況而言,要去外面上課學習好像也很怪(我無法想像要和一群職業主婦阿姨們一起學習編織的情形,而且如果我有錢、有閒,還是應該先去學吉他吧)。
這條圍巾總共在編織的過程中,總共用了三顆毛線球,織了一百六十八排,總共四千七百零四針。雖然出來的成品在我這個作者眼中好像處處是漏洞,常常看到有沒織好的地方,也覺得成品有點硬,但是我真的很用心、也盡了全力,對我來說,這是一次很棒的體驗(我想應該也不會是唯一的一次體驗)。
2007年2月6日 星期二
[Java] 自訂JTable的cell內容
這幾天,因為工作的需求必須要修改JTable的cell型態,讓他不只能顯示純文字,而能依照自己想要的方式顯示,因為JTable的架構設計得有點複雜,所以這個問題實在花了我不少時間研究,既然有了點研究結果,那就順便寫下來,這樣以後應該會比較方便。
根據官方API文件的說法,JTable設計架構裡面的TableCellRenderer就像是個印章一樣,JTable中的每個cell都是依照被設定好的TableCellRenderer呈現內容,如果想要自訂JTable裡面的cell,有幾個不同的方法可以達成同樣的目的。比較常見的作法就是繼承Java API裡面已經設計好的DefaultTableCellRenderer並且override其中的public Component getTableCellRendererComponent( JTable,Object,boolean,boolean,int,int) method或是和我下面示範的作法一樣,直接拿內建的DefaultTableCellRenderer來使用,但是自訂其中的getTableCellRendererComponent()。
其實DefaultTableCellRenderer也就是一個JLabel,當我們把數字丟進JTable的時候,數字會自動被wrap成Integer Object,而文字當然還是以String來表示,最後還是會交給DefaultTableCellRenderer這個JLabel的subclass做顯示的動作。進入要自訂getTableCellRendererComponent()的階段之後,必須要藉由parameter list上的Object value這個parameter取得cell的所存放的內容,之後就可以依據這個值做程式邏輯的判斷。
如果想要自訂cell的顯示方式,可以參考parameter list上的row, col這兩個值來判斷是不是想要的cell,接著呼叫super.getTableCellRendererComponent()取得這個cell的Renderer Component,並且把它cast成JLabel,藉由JLabel的setForeground()、setBackground()等各項method更改顯示的樣式(使用setBackground()之前必須要先呼叫setOpaque(true))。甚至也可以不要用JLabel顯示,只要先使用java.awt.Component以下可以顯示的subclass自訂自己想要的顯示樣式,然後在return的時候丟回去給上層的架構就好了。
以下的sample code示範了在JTable中傳入字串和數字,但是顯示出來的字串根據內容的不同有不同的顏色,而數字也是用JSlider的形式表示。

根據官方API文件的說法,JTable設計架構裡面的TableCellRenderer就像是個印章一樣,JTable中的每個cell都是依照被設定好的TableCellRenderer呈現內容,如果想要自訂JTable裡面的cell,有幾個不同的方法可以達成同樣的目的。比較常見的作法就是繼承Java API裡面已經設計好的DefaultTableCellRenderer並且override其中的public Component getTableCellRendererComponent( JTable,Object,boolean,boolean,int,int) method或是和我下面示範的作法一樣,直接拿內建的DefaultTableCellRenderer來使用,但是自訂其中的getTableCellRendererComponent()。
其實DefaultTableCellRenderer也就是一個JLabel,當我們把數字丟進JTable的時候,數字會自動被wrap成Integer Object,而文字當然還是以String來表示,最後還是會交給DefaultTableCellRenderer這個JLabel的subclass做顯示的動作。進入要自訂getTableCellRendererComponent()的階段之後,必須要藉由parameter list上的Object value這個parameter取得cell的所存放的內容,之後就可以依據這個值做程式邏輯的判斷。
如果想要自訂cell的顯示方式,可以參考parameter list上的row, col這兩個值來判斷是不是想要的cell,接著呼叫super.getTableCellRendererComponent()取得這個cell的Renderer Component,並且把它cast成JLabel,藉由JLabel的setForeground()、setBackground()等各項method更改顯示的樣式(使用setBackground()之前必須要先呼叫setOpaque(true))。甚至也可以不要用JLabel顯示,只要先使用java.awt.Component以下可以顯示的subclass自訂自己想要的顯示樣式,然後在return的時候丟回去給上層的架構就好了。
以下的sample code示範了在JTable中傳入字串和數字,但是顯示出來的字串根據內容的不同有不同的顏色,而數字也是用JSlider的形式表示。
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class CellRendererDemo {
public CellRendererDemo() {
JFrame frame = new JFrame("JTable CellRenderer Demo");
JScrollPane scrollPane;
JTable table;
String [] columnNames = {"String value", "Slider value"};
DefaultTableModel tableModel =
new DefaultTableModel(columnNames, 0);
/* pseudo data */
Object data [][] = {
{"One", 1}, {"Two", 2}, {"Three", 3}, {"Four", 4},
{"Five", 5}, {"Six", 6}, {"Seven", 7}, {"Eight", 8},
{"Night", 9}, {"Ten", 10}
};
for(int i = 0 ; i < data.length ; i++) {
tableModel.addRow(data[i]);
}
table = new JTable(tableModel);
scrollPane = new JScrollPane(table);
scrollPane = new JScrollPane(table,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
DefaultTableCellRenderer renderer =
new DefaultTableCellRenderer() {
public Component getTableCellRendererComponent(
JTable table,Object value,
boolean isSelected, boolean hasFocus,
int row,int col) {
JLabel label = (JLabel)
super.getTableCellRendererComponent(
table, value, isSelected,
hasFocus, row, col);
label.setForeground(Color.black);
/* return value */
JComponent retComponent = null;
if( value instanceof String && col == 0 ) {
if( row < 5 ) {
label.setForeground(Color.blue);
}else {
label.setForeground(Color.red);
}
retComponent = label;
}else if( value instanceof Integer && col == 1) {
JSlider slider = new JSlider(0, 10);
slider.setValue(
((Integer)value).intValue() );
retComponent = slider;
}
return retComponent;
}
};
/* register the TableCellRenderer */
for(int i=0 ; i < table.getColumnCount() ; i++) {
table.getColumnModel().getColumn(i).
setCellRenderer(renderer);
}
frame.getContentPane().add(scrollPane);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String [] args) {
new CellRendererDemo();
}
}
2007年2月5日 星期一
再一次乘上地鐵 もういちどメトロに乗って
2007年2月4日 星期日
頂尖對決 The Prestige
今天看了這部前陣子很知名的片,內容非常有趣、精彩,但是並不建議去電影院看,或許租DVD在家裡看感受不到電影院裡的氣氛和音效,可是對於這種充滿了疑惑的電影,如果能夠兩個人邊看邊討論應該會更有趣些。
片中的兩位主角心機都非常重,不看到最後實在很難猜測兩者的勝敗,兩個人都打著各自的算盤,也背負著各自的痛苦,看完之後換個角度來想,這根本是一部悲劇,為什麼要爭鬥到這種地步呢?
另一方面,這部片也有很好笑的地方,片中的學者Nikola Tesla本來只是想要發明可以瞬間傳送的機器,卻誤打誤撞地發明了可以製造複製人的機器,就好像本來只是想製造小刀卻不小心做出了核子彈一樣。
2007年2月3日 星期六
2007台北國際書展
今天去逛了一年一度的台北國際書展。今年書展的內容感覺起來好像沒有過去兩年來得豐富,折扣也不是很誘人,但是我還是買了四本書,分別是我的名字叫做紅、時空旅人之妻、博士熱愛的算式和米奇鰻的首部作品毛球寶兒,還有一本原本也打算要買的丈量世界後來並沒有購入,因為我慫恿與我同行的友人買了下來。
同一天的下午,米奇鰻和隋棠等model各自都有在世貿辦簽書會,但是因為我下午還要趕著去故宮,所以並沒有留下來參加這兩邊的活動。沒有親眼看到隋棠好像有點可惜,不過轉念一想後其實也還好,畢竟我也不可能去買她們的出版品,留下來也只是當個圍觀路人甲;至於米奇鰻...負責幫他辦簽書會的LiveABC工作人員竟然還問我他是誰,這實在相當驚奇,為什麼反而會是我比工作人員還了解呢?面對這樣的詢問,我也只能支支吾吾地告訴他,米奇鰻應該算是個藝術家吧。
雖然覺得今年書展的內容比不上往年,但我還是逛了不少攤位,可是讓我覺得今年的書展沒那麼精彩的原因是不是因為往年和我一起去的人已經不在我身邊了呢?
同一天的下午,米奇鰻和隋棠等model各自都有在世貿辦簽書會,但是因為我下午還要趕著去故宮,所以並沒有留下來參加這兩邊的活動。沒有親眼看到隋棠好像有點可惜,不過轉念一想後其實也還好,畢竟我也不可能去買她們的出版品,留下來也只是當個圍觀路人甲;至於米奇鰻...負責幫他辦簽書會的LiveABC工作人員竟然還問我他是誰,這實在相當驚奇,為什麼反而會是我比工作人員還了解呢?面對這樣的詢問,我也只能支支吾吾地告訴他,米奇鰻應該算是個藝術家吧。
雖然覺得今年書展的內容比不上往年,但我還是逛了不少攤位,可是讓我覺得今年的書展沒那麼精彩的原因是不是因為往年和我一起去的人已經不在我身邊了呢?
訂閱:
文章 (Atom)