JTable 에서사용하는 Model 객체 JTable - JTable은데이터베이스의검색결과를 GUI에보여주기위해사용되는컴포넌트이다. 가로와세로로구성된테이블을을사용해서행과열에데이터를위치시킨다. - JTable을사용하는방법은다음과같다. 1 테이블에출력될데이터를 2차원배열에저장한다. Object[][] records = { {..., {..., {... ; 2 제목으로사용할문제열을 1차원배열에저장한다. String[] titles = { 제목1, 제목2,..., 제목n ; 3 위의 1과 2를사용해서 JTable을생성한다. JTable table = new JTable(records, titles); 4 위의 3에서생성한테이블을스크롤이있는패널에붙인다. 테이블에출력되는데이터의갯수가많으면한화면을넘기게되는데, 이런경우에는스크롤을사용해서다음화면의데이터를볼수있도록해야한다. 그래서, 일반적으로테이블을스크롤이있는패널 (JScrollPane) 에붙인다. JScrollPane scrollpanel = new JScrollPane(); 5 위의 4에서생성된스크롤이있는패널을윈도우프레임에붙인다. add(scrollpanel); - 테이블사용예제 public class TableExam extends JFrame { Object[][] data = { {" 홍길동 ", "hong@mail.com", "1221", 15, {" 박길동 ", "park@mail.com", "1245", 30, {" 최길동 ", "choi@mail.com", "2332", 20 ;// 테이블에출력할데이터 String[] columnname = {" 이름 ", " 이메일주소 ", " 암호 ", " 나이 ";// 열의제목으로사용될문자열 JTable table; public TableExam() { table = new JTable(data, columnname); add(new JScrollPane(table)); setdefaultcloseoperation(jframe.exit_on_close); setsize(500, 200); setvisible(true); public static void main(string[] args) { new TableExam(); - 1 -
JTable과 MVC(Model-View-Controller) 구조 - 모델-뷰-컨트롤러구조는데이터의저장과접근에대한제공은모델이담당하고, 화면표시는뷰, 이벤트의처리는컨트롤러가하도록각역할을구분한구조이다. 즉, 역할의분담을통하여상호간의영향을최소화하고각요소의독립성을보장하여독자적인역할에충실할수있는형태이다. - 이구조를사용하면한개의데이터모델을사용해서다양한형태의뷰를사용해서보여줄수있다. - JTable을이용한데이터출력작업을 MVC 구조로분리하면, JTable은뷰역할만을수행하고테이블에출력되는데이터는모델역할만수행한다. 따라서, JTable은데이터에관여할필요가없어지고, 모델역할을하는데이터도 JTable에관여하지않는다. - JTable은단지데이터를보여주는역할을한다. - JTable은내부적으로 DefaultTableModel 객체를사용해서테이블에출력할모델로사용한다. - 모델객체를사용해서테이블을작성하는절차는다음과같다. 1 모델클래스설계 public class 클래스이름 extends AbstractTableModel { 2 모델객체생성클래스이름 model = new 클래스이름 (); 3 모델을사용해서 JTable 객체생성 JTable table = new JTable(model); 4 윈도우프레임에테이블을붙인다. add(new JScrollPane(table)); - JTable의개념도 (MVC) - 테이블은데이터의행의갯수와열의갯수, 열의제목등을읽어서데이터를테이블에출력한다. - JTable이기본적으로가지고있는모델이있는데, 이모델은 TableModel 이다. - 모델객체는테이블에서사용할수있도록 행의갯수, 열의갯수, 열의제목 등을알려주는메서드를가지고있다. 각각 getrowcount(), getcolumncount(), getcolumnname( 열의번호 ) 메서드이다. - 2 -
- JTable 의기본으로가지고있는 TableModel 을사용한예 class JTableTest1 { public static void main(string[] args) { JFrame frame = new JFrame(" 참가자명단프로그램 "); frame.setpreferredsize(new Dimension(300, 150)); frame.setlocation(500, 400); Container contentpane = frame.getcontentpane(); String colnames[] = { " 이름 ", " 나이 ", " 성별 " ; Object data[][] = { { " 김철수 ", 24, ' 남 ', { " 이순희 ", 21, ' 여 ', { " 박지영 ", 26, ' 여 ' ; JTable table = new JTable(data, colnames); JScrollPane scrollpane = new JScrollPane(table); contentpane.add(scrollpane, BorderLayout.CENTER); JButton button = new JButton(" 출력 "); button.addactionlistener(new PrintActionListener(table)); contentpane.add(button, BorderLayout.SOUTH); frame.setdefaultcloseoperation(jframe.exit_on_close); frame.pack(); frame.setvisible(true); class PrintActionListener implements ActionListener { JTable table; PrintActionListener(JTable table) { this.table = table; public void actionperformed(actionevent e) { TableModel model = table.getmodel(); int rownum = model.getrowcount(); 데이터의행의갯수를얻어온다. int colnum = model.getcolumncount(); 데이터의열의갯수를얻어온다. for (int col = 0; col < colnum; col++) { String colname = model.getcolumnname(col); 지정된열의제목을얻어온다. System.out.print(colName + "\t"); System.out.println(); for (int row = 0; row < rownum; row++) { for (int col = 0; col < colnum; col++) { - 3 -
Object obj = model.getvalueat(row, col); System.out.print(obj + "\t"); System.out.println(); System.out.println("-----------------------------"); 데이터베이스의조회결과를 JTable에출력 - 데이터베이스의조회결과를 JTable에출력하기위해서는우선 Model에조회결과데이터를저장해야한다. 그런데, JTable이기본적으로가지고있는 TableModel에는데이터베이스의조회결과를저장하는일을하는메서드가존재하지않는다.( 다음그림의? 부분 ) - 따라서, 조회결과를모델에저장하는메서드가있는모델이필요하다. - TableModel에는조회결과를저장하는메서드가존재하지않으므로, 새로운모델을만든후데이터베이스조회결과를모델에저장하는새로운메서드를정의해야한다. - 새로운모델객체를만드는방법은다음과같다. 1 AbstractTableModel 클래스를상속해서새로운이름의모델클래스를만든다. class NewModel extends AbstractTableModel { 2 모델객체가기본적으로가지고있는다음의메서드들을오버라이딩한다.(data는데이터베이스조회결과가저장될 2차원배열의이름 ) public int getcolumncount() {// 출력할데이터의열의갯수를알려주는메소드 return data[0].length;//4개열로구성되어있으므로 4를리턴한다. public int getrowcount() {// 출력할데이터의행의갯수를알려주는메소드 return data.length;//3 개의행으로구성되어있으므로 3 을리턴한다. - 4 -
public int getrowcount() {// 출력할데이터의행의갯수를알려주는메소드 return data.length;//3 개의행으로구성되어있으므로 3 을리턴한다. // 테이블에서해당열, 행을선택했을때그곳에저장된데이터를알려주는메소드 public Object getvalueat(int rowindex, int columnindex) { return data[rowindex][columnindex];// 해당위치의데이터를리턴한다. public String getcolumnname(int column) {// 지정된열 (column) 의제목을알려주는메서드 return columnname[column]; 3 데이터베이스의검색결과의건수를이용해서모델에저장될데이터의행의수를설정하는메서드를작성한다. void 메서드이름 (ResultSet resultset) { try { resultset.last(); 검색된결과의맨마지막행으로이동한다. rows = resultset.getrow(); 마지막행의번호를읽어온다. catch(exception e) { e.printstacktrace(); 위 3의메서드에서 ResultSet의 last() 메서드를사용하기위해서는 ResultSet이다음과같이생성되어야한다. - 데이터베이스로부터의검색결과는 ResultSet 객체에서관리한다. String str = "select * from employees"; ResultSet rs = stmt.executequery(str); rs.first() rs.next() 검색결과 ResultSet rs.previous() rs.last() - ResultSet 에서다음과같은메소드를사용해서검색결과를처리한다. 메소드이름 next() previous() first() last() 설명현재행에서한행다음으로이동현재행에서한행앞으로이동현재행에서첫번째행의위치로이동현재행에서마지막행의위치로이동 - 5 -
- 하지만, rs에서사용할수있는메서드는 next() 메서드만가능하다. 다른세개의메서드를모두사용하기위해서는다음과같이 ResultSet을생성해야한다. PreparedStatement pstmtscroll = con.preparestatement(str, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet rsscroll = pstmtscroll.executequery(sql); 4 데이터베이스의검색결과를모델에저장하는메서드를작성한다. void 메서드이름 (ResultSet resultset) { ResultSetMetaData rsmd; try { rsmd = resultset.getmetadata();// 검색된결과에서메타데이터를읽어온다. cols = rsmd.getcolumncount();// 메타데이터에서검색된데이터의열의갯수를읽는다. columnname = new String[cols];// 열의갯수만큼열제목을저장할문자열배열생성 for(int i = 0; i < cols; i++) {// 열의갯수만큼열의제목을읽어서배열에저장 columnname[i] = rsmd.getcolumnname(i+1); data = new Object[rows][cols]; // 검색된데이터의행과열값을이용해서데이터를저장할 2차원배열을생성한다. int r = 0;// 시작행의번호를설정 while(resultset.next()) { for(int c = 0; c < cols; c++) { data[r][c] = resultset.getobject(c + 1); // 검색된한행의데이터를읽어온후 data배열에저장한다. r++;// 행의번호를증가시킨다. resultset.close(); catch(exception e) { e.printstacktrace(); 5 Swing 의 GUI 화면에서 JTable 컴포넌트와모델객체를생성하고, 데이터베이스의검색결과를가지고있는 ResultSet 객체를두가지의버전 (next() 메서드만사용할수있는버전, next(), first(), last(), previous() 메서드를 사용할수있는버전 ) 으로생성한다. 6 위의 5 번과정에서생성한두개의 ResultSet 객체중 next() 메서드만사용할수있는 ResultSet 객체를 3 번 과정에서작성한메서드에전달하고, next(), first(), last(), previous() 메서드를사용할수있는 ResultSet 객체를 4 번과정에서작성한메서드에전달한다. - 6 -