這幾天,因為工作的需求必須要修改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的時候,數字會自動被wrapInteger Object,而文字當然還是以String來表示,最後還是會交給DefaultTableCellRenderer這個JLabelsubclass做顯示的動作。進入要自訂getTableCellRendererComponent()的階段之後,必須要藉由parameter list上的Object value這個parameter取得cell的所存放的內容,之後就可以依據這個值做程式邏輯的判斷。

  如果想要自訂cell的顯示方式,可以參考parameter list上的row, col這兩個值來判斷是不是想要的cell,接著呼叫super.getTableCellRendererComponent()取得這個cell的Renderer Component,並且把它castJLabel,藉由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();
    }
}


台南小新 發表在 痞客邦 PIXNET 留言(1) 人氣()


留言列表 (1)

發表留言
  • 貓熊
  • 很實用 感謝您 = )