JTable 에서 AbstractTableModel 을 상속하여 모델 클래스를 정의하고 사용하는 예
JTable의 테이블 모델 클래스에서 데이터 변경을 인지하고 다른 리스너에게 통보하는 내용
모델 클래스의 setValueAt(row, col) 메소드 안에서 fireTableCellUpdated(row,col) 를 호출하는 예
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.event.*;
import javax.swing.table.TableModel;
/**
* TableDemo is just like SimpleTableDemo, except that it
* uses a custom TableModel.
*/
public class TableDemo02 extends JPanel implements TableModelListener {
private boolean DEBUG = false;
public TableDemo02() {
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...
}
class MyTableModel extends AbstractTableModel {
private String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};
private Object[][] data = {
{"Mary", "Campione",
"Snowboarding", new Integer(5), new Boolean(false)},
{"Alison", "Huml",
"Rowing", new Integer(3), new Boolean(true)},
{"Kathy", "Walrath",
"Knitting", new Integer(2), new Boolean(false)},
{"Sharon", "Zakhour",
"Speed reading", new Integer(20), new Boolean(true)},
{"Philip", "Milne",
"Pool", new Integer(10), new Boolean(false)},
};
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return data.length;
}
public String getColumnName(int col) {
return columnNames[col];
}
// 한개의 셀을 그릴 때마다 호출됨( 데이터이동, Model -> View )
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) { // 이 메소드가 true 를 리턴한 경우에는 해당 셀을 편집가능하게 설정함
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
if (col < 2) {
return false;
} else {
return true;
}
}
/*
* Don't need to implement this method unless your table's
* data can change.
*/
// JTable의 셀을 편집하고 엔터를 치면 호출되는 메소드( 데이터이동, View -> Model )
public void setValueAt(Object value, int row, int col) { // TableModelListener.tableChanged()보다 먼저 호출됨
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
/**
* 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();
}
});
}
}