Notice
Recent Posts
Recent Comments
관리 메뉴

Developer Gonie

[5주차] 100. AWT+SWING, JTable 원소 추가/삭제, 파일출력 본문

K-DigitalTraining 강의/1. Java

[5주차] 100. AWT+SWING, JTable 원소 추가/삭제, 파일출력

이대곤 2022. 6. 9. 16:55

import java.awt.Container;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

class Sub11 extends JFrame{
	
	JTable table;
	JScrollPane sPane;
	Container contentPane;
	
	Vector<String> columnName = null;   // String을 원소로 갖는 갖는 리스트
	Vector<Vector<String>> data = null; // String 여러개를 갖는 백터들을 원소로 갖는 리스트
	
	int cnt = 1;
	
	String[] caption = {"이름", "국어", "영어", "수학"};
	
	JTextField[] text_arr = new JTextField[4];
	
	Sub11(String title) {
		super(title);

		columnName = new Vector<String>();
		data = new Vector<Vector<String>>();

		getFile(); // 파일에서 한줄씩 읽어와 columnName과 data 객체를 완성시킴

		compose(); // 위에서 만들어진 JTable을 생성하고 Scrollbar panel에 올리고, 작업 영역에 올리는 메소드
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // X버튼 누르면 프로그램이 종료되게 하고 싶을 때
		setSize(700,300);
		setVisible(true);
	}

	private void compose() { // 화면 구성을 만드는 메소드
		table = new JTable(data, columnName);
		sPane = new JScrollPane(table);
		contentPane = getContentPane();
		
		//contentPane.add(sPane, BorderLayout.CENTER);
		contentPane.setLayout(null); // 어떤 배치 관리자도 쓰지 않겠다. 디폴트로 지정된 레이아웃 조차도
		contentPane.add(sPane);
		
		sPane.setBounds(250,30,400,200);
		
		for(int i = 0; i<4; i++) {
			JLabel lb = new JLabel();
			lb.setText(caption[i] + ":");
			lb.setBounds(10, 30*(i+1), 50, 20);
			contentPane.add(lb);
		}
		
		for(int i = 0; i<4; i++) {
			text_arr[i] = new JTextField();
			text_arr[i].setBounds(100, 30*(i+1), 100, 20);
			contentPane.add(text_arr[i]);
		}
		
		// 버튼추가
		JButton bt_add = new JButton("추가");
		JButton bt_delete = new JButton("삭제");
		JButton bt_fileSave = new JButton("파일출력");
		JButton bt_exit = new JButton("종료");
		
		bt_add.setBounds(20, 170, 90, 20);
		bt_delete.setBounds(120, 170, 90, 20);
		bt_fileSave.setBounds(20, 200, 90, 20);
		bt_exit.setBounds(120, 200, 90, 20);
		
		contentPane.add(bt_add);
		contentPane.add(bt_delete);
		contentPane.add(bt_fileSave);
		contentPane.add(bt_exit);
		
		bt_add.addActionListener(new AddSungjuk(table, text_arr));
		bt_delete.addActionListener(new DeleteSungjuk(table));
		bt_fileSave.addActionListener(new PrintFile(table));
		bt_exit.addActionListener(new Exit());
	}

	public void getFile() {

		File file = new File("C:\\Java_ldg\\12__AWT\\src\\table.txt");
		FileReader fr;
		try {
			fr = new FileReader(file);
			BufferedReader br = new BufferedReader(fr);

			String line;

			while ((line = br.readLine()) != null) { // 1줄씩 읽어들임
				tableMake(line);
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void tableMake(String line) {
		// line: 이름/국어/영어/수학
		// line: 써니/33/44/55
		
		String[] tokens = line.split("/");
		if (cnt++ == 1) { // 파일내용중 첫번째 줄은 column 명으로 사용
			for(int i = 0; i < tokens.length; i++) {
				columnName.add(tokens[i]);
			}
		}else {
			Vector<String> one = new Vector<String>();
			for(int i = 0; i < tokens.length; i++) {
				one.add(tokens[i]);
			}
			data.add(one);
		}
	}
}

public class Ex12_11_Main {
	public static void main(String[] args) {
		new Sub11("성적 처리");
	}
}

위 코드상에 존재하는 각각의 버튼 이벤트 처리

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;



public class AddSungjuk implements ActionListener{

	JTable table;
	JTextField[] text_arr;

	AddSungjuk(JTable table, JTextField[] text_arr){
		this.table = table;
		this.text_arr = text_arr;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("추가 클릭");
		String[] str = new String[4];
		
		for(int i = 0; i < text_arr.length ;i++)
			str[i] = text_arr[i].getText();

		// JTable은 행을 추가하는 addRow() 메서드가 없어서 getModel() 하여 얻은 객체를 통해 사용해야 한다.
		// table.getModel()은 TableModel 타입의 객체를 반환하는데 TableModel는 인터페이스임.
		// 인터페이스는 객체를 생성할 수 없는 것을 감안하면, 이 객체는 타입만 이렇지 내부는 TableModel 인터페이스를 구현한 클래스의 실 객체임
		// 그 실 객체가 무었이냐? TableModel 인터페이스를 구현한 DefaultModel의 객체이다.
		// DefaultModel는 TableModel를 상속받은 자식이라 자동형변환이 안이뤄지기 때문에 아래와 같이 캐스팅 필요하다.
		// DefaultModel 객체의 addRow()는 TableModel한테 물려받은 메소드가 아니라 DefaultModel만 가지는 메소드인거 같다.
		
		DefaultTableModel model = (DefaultTableModel)table.getModel(); 
		model.addRow(str);	// 추가하면 JTable은 자동으로 새로고침됨
		
		for(int i = 0; i < text_arr.length ;i++)
			text_arr[i].setText("");
	}
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class DeleteSungjuk implements ActionListener{

	JTable table;
	
	DeleteSungjuk(JTable table){
		this.table = table;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		
		System.out.println("삭제 클릭");
		
		int index = table.getSelectedRow();
		
		// 아래의 메소드에 대한 설명은 AddSungjuk 클래스에 언급해 두었으니 이를 참고해라.
		DefaultTableModel model = (DefaultTableModel)table.getModel();
		model.removeRow(index);		
	}
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.JTable;

public class PrintFile implements ActionListener {

	JTable table;

	PrintFile(JTable table) {
		this.table = table;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("파일출력 클릭");

		FileWriter fw = null;
		BufferedWriter bw = null;

		try {
			fw = new FileWriter("re_saved_table", false);
			bw = new BufferedWriter(fw);

			int columnCount = table.getColumnCount();
			int rowCount = table.getRowCount();

			// Column name 저장
			for (int i = 0; i < columnCount; i++) {
				bw.write(table.getColumnName(i));
				if (i != columnCount - 1) {
					bw.write("/");
				}
			}
			
			bw.newLine();
			
			// Rows 저장
			for (int i = 0; i < rowCount; i++) {
				for (int j = 0; j < columnCount; j++) {
					
					Object obj = table.getValueAt(i, j);
					bw.write(obj.toString());
					
					if (j != rowCount - 2) {
						bw.write("/");
					}
				}
				bw.newLine();
			}

			
		} catch (IOException e1) {
			e1.printStackTrace();
		} finally {
			try {
				bw.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}

	}

}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Exit implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("종료 클릭");
		System.exit(0);
	}
	
}
Comments