Swing/JTable 06

JTable 06

Soul-Learner 2014. 6. 10. 00:10

JTable 셀에 이미지 넣기


JTable에 포함할 수 있는 데이터는 Object 형이면 되므로 문자열, 숫자, Boolean, Image 등 모든 데이터가 해당된다

JTable은 셀에 출력할 데이터가 어떤 자료형에 해당하는지 확인하여 해당 데이터를 셀에 출력하는데, 이 때 각 셀의 자료형을 확인할 때 사용하는 메소드가 getColumnClass() 이다. 그러므로 개발자가 AbstractTableModel 클래스의 getColumnClass()를 적절하게 오버로드하면 JTable은 아래처럼 셀에 이미지도 출력할 수 있다


 

 

 

 

 

 


import java.awt.*;

import javax.swing.*;

import javax.swing.event.*;

import javax.swing.table.*;


public class TableDemo06 extends JPanel implements TableModelListener {


    private boolean DEBUG = false;


    public TableDemo06() {
        super(new GridLayout(1,0));

        JTable table = new JTable(new MyTableModel());
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true);
        table.getModel().addTableModelListener(this); // 테이블모델이 변경될 때 fireTableCellUpdated() 에 의해 통보됨

        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //Add the scroll pane to this panel.
        add(scrollPane);
    }


    // JTable의 셀을 편집하고 엔터를 치면 호출되는 이벤트 핸들러 메소드(TableModelListener)
    public void tableChanged(TableModelEvent e) { // 모델 클래스의 setValueAt() 보다 나중에 호출됨. 
        int row = e.getFirstRow();
        int column = e.getColumn();
        TableModel model = (TableModel)e.getSource();
        String columnName = model.getColumnName(column);
        Object data = model.getValueAt(row, column);
        System.out.println("Table Changed:"+data);
        //... Do something with the data...
    }

   

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("TableDemo02");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        TableDemo02 newContentPane = new TableDemo02();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }


    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                 createAndShowGUI();
            }
        });
    }
}



MyTableModel.java


import java.awt.*;

import java.awt.image.*;

import java.io.*;

import java.sql.Date;

import java.util.Calendar;

import javax.imageio.*;

import javax.swing.*;

import javax.swing.table.*;


class MyTableModel extends AbstractTableModel 

{

    boolean DEBUG = true;

    ImageIcon [] icon = new ImageIcon[6];

    

    private String[] columnNames;

    private Object[][] data;


    MyTableModel() {

        

        BufferedImage image;

        

        try { // 이미지 파일은 클래스가 포함된 패키지에 위치한다. 즉, 프로젝트 내에 이미지 파일이 있을 때 다음과 같이 로드할 수 있다

            image = ImageIO.read(getClass().getResourceAsStream("smile1.jpg"));

            icon[0] = new ImageIcon((Image)image);

            image = ImageIO.read(getClass().getResourceAsStream("smile2.jpg"));

            icon[1] = new ImageIcon((Image)image);

            image = ImageIO.read(getClass().getResourceAsStream("smile3.jpg"));

            icon[2] = new ImageIcon((Image)image);

            image = ImageIO.read(getClass().getResourceAsStream("smile4.jpg"));

            icon[3] = new ImageIcon((Image)image);

            image = ImageIO.read(getClass().getResourceAsStream("smile5.jpg"));

            icon[4] = new ImageIcon((Image)image);

            image = ImageIO.read(getClass().getResourceAsStream("smile6.jpg"));

            icon[5] = new ImageIcon((Image)image);

        } catch (IOException ex) {

            ex.printStackTrace();

        }


        columnNames = new String[]{"EMPNO","ENAME","HIREDATE","PICTURE","SELECT"};

        

        Calendar cal = Calendar.getInstance();

        

        data = new Object[5][];

        cal.set(2001, 0, 12);

        data[0] = new Object[]{ 5, "SMITH",new Date(cal.getTimeInMillis()), icon[0], new Boolean(false) };

        cal.set(2002, 2, 16);

        data[1] = new Object[]{ 3, "JONES",new Date(cal.getTimeInMillis()), icon[1], new Boolean(true) };

        cal.set(2003, 3, 21);

        data[2] = new Object[]{ 4, "WARD",new Date(cal.getTimeInMillis()), icon[2], new Boolean(false) };

        cal.set(2005, 5, 24);

        data[3] = new Object[]{ 6, "FORD",new Date(cal.getTimeInMillis()), icon[3], new Boolean(true) };

        cal.set(2010, 9, 27);

        data[4] = new Object[]{ 7, "MARY",new Date(cal.getTimeInMillis()), icon[4], new Boolean(false) };

    }

        

    public int getColumnCount() {

        return columnNames.length;

    }


    public int getRowCount() {

        return data.length;

    }


    public String getColumnName(int col) {

        return columnNames[col];

    }


    // 한개의 셀을 그릴 때마다 호출됨

    public Object getValueAt(int row, int col) {

        //System.out.print("getValueAt("+row+","+col+")");

        return data[row][col];

    }


    /*

     * JTable uses this method to determine the default renderer/

     * editor for each cell.  If we didn't implement this method,

     * then the last column would contain text ("true"/"false"),

     * rather than a check box.

     */

    public Class getColumnClass(int c) {

        return getValueAt(0, c).getClass();

    }


    /*

     * Don't need to implement this method unless your table's

     * editable.

     */

    public boolean isCellEditable(int row, int col) {

        return col==1 || col==4 ? true : false;

    }


    /*

     * Don't need to implement this method unless your table's

     * data can change.

    */

    // JTable의 셀을 편집하고 엔터를 치면 호출되는 메소드

    public void setValueAt(Object value, int row, int col) {

        System.out.println("테이블모델.setValueAt("+value+","+row+", "+col+")"); 

        if (DEBUG) {

            System.out.println("Setting value at " + row + "," + col

                               + " to " + value

                               + " (an instance of "

                               + value.getClass() + ")");

        }


        data[row][col] = value;


        fireTableCellUpdated(row, col);//모든 리스너에게 셀 데이터 변경을 알린다


        if (DEBUG) {

            System.out.println("New value of data:");

            printDebugData();

        }

    }


    private void printDebugData() {

        int numRows = getRowCount();

        int numCols = getColumnCount();


        for (int i=0; i < numRows; i++) {

            System.out.print("    row " + i + ":");

            for (int j=0; j < numCols; j++) {

                System.out.print("  " + data[i][j]);

            }

            System.out.println();

        }

        System.out.println("--------------------------");

    }

} // End of MyTableModel class