본문 바로가기
Data Structure

TableModel 만들기

by SuldenLion 2024. 1. 6.
반응형

Table을 MVC 패러다임으로 짠 것을 허접한 버전에서부터 발전시키는 과정까지 만들어 보겠다.

 

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

import javax.swing.*;
import javax.swing.filechooser.*;
import javax.swing.table.*;

class StudentModel extends AbstractTableModel {

	static class Student implements Serializable {
		String name;
		int kor;
		int eng;
		int math;
		int sum;
		boolean scholarship;

		Student (String name, int kor, int eng, int math) {
			this.name = name;
			this.kor = kor;
			this.eng = eng;
			this.math = math;
			sum = kor + eng + math;
			if (sum > 200) scholarship = true;
		}

		public String getName() {
			return name;
		}

		public int getKor() {
			return kor;
		}

		public int getEng() {
			return eng;
		}

		public int getMath() {
			return math;
		}

		public int getSum() {
			return sum;
		}

		public boolean getScholarship() {
			return scholarship;
		}

	}

	ArrayList<Student> list = new ArrayList<Student>();
	/*static int MAX = 100;
	String name[];
	int grade[][];
	boolean scholar[];
	int size;*/

	StudentModel() {
		/*name = new String[MAX];
		grade = new int[MAX][4];
		scholar = new boolean[MAX];
		size = 0;*/
		list.add(new Student("홍충표",70,100,40));
		list.add(new Student("고현규",80,30,60));
		list.add(new Student("김동혁",40,70,50));
		list.add(new Student("유승진",60,50,100));		
	}

	public int getColumnCount() {
		return 7;
	}

	public int getRowCount() {
		return list.size();
	}

	/*title = new Vector<String>(); //Vector
		title.add("순위");
		title.add("이름");
		title.add("국어");
		title.add("영어");
		title.add("수학");
		title.add("합계");
		title.add("장학금여부");*/

	public String getColumnName(int index) {
		if (index == 0) return "순서";
		else if (index == 1) return "이름";
		else if (index == 2) return "국어";
		else if (index == 3) return "영어";
		else if (index == 4) return "수학";
		else if (index == 5) return "합계";
		else if (index == 6) return "장학생";
		else return null;
	}

	public Class getColumnClass(int index) {
		if (index == 0) return Integer.class;
		else if (index == 1) return String.class;
		else if (index == 2) return Integer.class;
		else if (index == 3) return Integer.class;
		else if (index == 4) return Integer.class;
		else if (index == 5) return Integer.class;
		else if (index == 6) return Boolean.class;
		else return null;
	}

	public Object getValueAt(int r, int c) {
		Student st = list.get(r);
		if (c == 0) return r+1;
		else if (c == 1) return st.name;
		else if (c == 2) return st.getKor();
		else if (c == 3) return st.getEng();
		else if (c == 4) return st.getMath();
		else if (c == 5) return st.getSum();
		else if (c == 6) return st.getScholarship();
		else return null;
	}

	public void add(Student st) {
		list.add(st);
	}

	public void remove(String name) {
		Iterator<Student> it = list.iterator();
		while (it.hasNext()) {
			if (it.next().name.equals(name)) it.remove();
		}
	}

	public void addStudent(String name, int kor, int eng, int math) {
		Student s = new Student(name, kor, eng, math);
		add(s);
	}

	public void saveText(String fileName) {
		try {
			FileWriter fw = new FileWriter(new File(fileName));
			String str = "";

			ListIterator<Student> it = list.listIterator();
			while (it.hasNext()) {
				Student st = it.next();
				String aLine = st.name + " " + st.kor + " " + st.eng + " " + st.math + "\r\n"; // 파일 저장시 마지막 커서 위치 고려
				fw.write(aLine);
				fw.flush();
			}			
			/* for (int i = 0; i < table.getRowCount(); i++) {
				for (int j = 0; j < table.getColumnCount(); j++) {
					str = table.getValueAt(i, j) + " ";
					fw.write(str);
				}
				fw.write("\r\n");
			} */
			fw.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public void loadText(String fileName) {
		try {
			BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)));

			int n = 0; // Text File의 라인수 Table load하기위해 미리 알아야함. Text파일에 미리 라인수를 명시하거나 반복문을 두번돌려서 첫반복문에 line수를 얻는다.
			String aLine = null;
			while ((aLine = reader.readLine()) != null) {
				if (aLine.length() == 0) break;
				n++;
			}
			reader.close();

			list.clear();
			reader = new BufferedReader(new FileReader(new File(fileName)));
			for (int i = 0; i < n; i++) {
				aLine = reader.readLine();
				String[] token = aLine.split(" ");
				addStudent(token[0], Integer.parseInt(token[1]), Integer.parseInt(token[2]), Integer.parseInt(token[3]));
			}
			reader.close();

			/*String header = txtReader.readLine();
			String[] line = header.split("\n");
			StringTokenizer st;
			for (int i = 0; i < line.length; i++) {
				st = new StringTokenizer(line[i]);
				st.nextToken();
				String name = st.nextToken();
				int kor = Integer.parseInt(st.nextToken());
				int eng = Integer.parseInt(st.nextToken());
				int math = Integer.parseInt(st.nextToken());
				//Student s = new Student(name, kor, eng, math);
				//model.add(s);
			}

			table.updateUI();
			txtReader.close();*/
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public void serializeSave(String fileName) {
		try {
	    	FileOutputStream fos = new FileOutputStream(fileName);
	    	ObjectOutputStream oos = new ObjectOutputStream(fos);
	    	oos.writeObject(list);
	    	oos.flush();
	    	oos.close();
	    	fos.close();
	    } catch (Exception ex) {
	    	ex.printStackTrace();
		}
		//System.out.println(list);
	}

	public void serializeLoad(String fileName) {
		try {
	    	FileInputStream fis = new FileInputStream(fileName);
	    	ObjectInputStream ois = new ObjectInputStream(fis);	    	
	    	list = (ArrayList<Student>)ois.readObject();    // Reflection -> serialization 가능하게해줌	    	
	    	ois.close();
	    	fis.close();
	    } catch (Exception ex) {
	    	ex.printStackTrace();
		}
		//System.out.println(list);
	}

}

public class JTableEx extends JFrame implements ActionListener {

	JTable table;
	JButton addBtn, removeBtn;
	JMenuBar menuBar;
	JMenu menu;
	JMenu loadMenu;
	JMenu saveMenu;
	JMenuItem textLoadMenu, serialLoadMenu, textSaveMenu, serialSaveMenu;
	JTextField nameField, korField, engField, mathField;
	String fileName; //x
	StudentModel model;

	JTableEx() {
		menuBar = new JMenuBar();
		menu = new JMenu("File");
		menuBar.add(menu);

		menu.add(loadMenu = new JMenu("Load"));
		menu.add(saveMenu = new JMenu("Save"));
		loadMenu.add(textLoadMenu = new JMenuItem("Text"));
		textLoadMenu.addActionListener((e) -> loadTextFile());
		loadMenu.add(serialLoadMenu = new JMenuItem("Serialize"));
		serialLoadMenu.addActionListener((e) -> serializedLoad());
		saveMenu.add(textSaveMenu = new JMenuItem("Text"));
		textSaveMenu.addActionListener((e) -> saveTextFile());
		saveMenu.add(serialSaveMenu = new JMenuItem("Serialize"));
		serialSaveMenu.addActionListener((e) -> serializedSave());
		setJMenuBar(menuBar);

		table = new JTable(model = new StudentModel());
		JScrollPane sp = new JScrollPane(table);

		cellCenter(table);

		addBtn = new JButton("Add");
		removeBtn = new JButton("Remove");

		JPanel p = new JPanel();

		nameField = new JTextField();
		korField = new JTextField();
		engField = new JTextField();
		mathField = new JTextField();

		nameField.setPreferredSize(new Dimension(80, 30));
		korField.setPreferredSize(new Dimension(40, 30));
		engField.setPreferredSize(new Dimension(40, 30));
		mathField.setPreferredSize(new Dimension(40, 30));

		p.add(new JLabel("이름:"));
		p.add(nameField);
		p.add(new JLabel("국어:"));
		p.add(korField);
		p.add(new JLabel("영어:"));
		p.add(engField);
		p.add(new JLabel("수학:"));
		p.add(mathField);
		p.add(addBtn);
		p.add(removeBtn);

		Container c = getContentPane();
		c.add("Center", sp);
		c.add("South", p);

		setBounds(700, 300, 550, 400);
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		addBtn.addActionListener(this);
		removeBtn.addActionListener(this);
	}

	private void cellCenter(JTable table) {
		DefaultTableCellRenderer dtcr = new DefaultTableCellRenderer();
		dtcr.setHorizontalAlignment(SwingConstants.CENTER);	
		TableColumnModel tcm = table.getColumnModel();
		tcm.getColumn(0).setCellRenderer(dtcr);
		tcm.getColumn(1).setCellRenderer(dtcr);
	}

	private void saveTextFile() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
		FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt", "txt");
		chooser.setFileFilter(filter);
		int ret = chooser.showSaveDialog(null);
		if (ret != JFileChooser.APPROVE_OPTION) return;
		String fileName = chooser.getSelectedFile().getPath();

		model.saveText(fileName);

		/*JFileChooser chooser = new JFileChooser();

		FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt", "txt");
		chooser.setFileFilter(filter);
		int ret = chooser.showSaveDialog(null);
		if (ret != JFileChooser.APPROVE_OPTION) return;
		String fileName = chooser.getSelectedFile().getPath();

		try {
			FileWriter fw = new FileWriter(new File(fileName));
			fw.write(table.getAccessibleContext().toString());
			fw.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}*/

		/* JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.SAVE_DIALOG);
	    int returnVal = chooser.showSaveDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    String saveName = chooser.getSelectedFile().getPath();
	    if (saveName == null) return;
	    if (saveName.length() == 0) return;
	    fileName = saveName;
	    try {
	    	FileOutputStream fos = new FileOutputStream(fileName);
	    	ObjectOutputStream oos = new ObjectOutputStream(fos);
	    	oos.writeObject(model);
	    	oos.flush();
	    	oos.close();
	    	fos.close();
	    } catch (Exception ex) {
		} */
	}

	private void loadTextFile() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
		chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.OPEN_DIALOG);
	    int returnVal = chooser.showOpenDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    fileName = chooser.getSelectedFile().getPath();

	    model.loadText(fileName);
	    table.updateUI();
		/*JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.OPEN_DIALOG);
	    int returnVal = chooser.showOpenDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    fileName = chooser.getSelectedFile().getPath();
	    try {
	    	FileInputStream fis = new FileInputStream(fileName);
	    	ObjectInputStream ois = new ObjectInputStream(fis);
	    	ois.readObject();		    	
	    	ois.close();
	    	fis.close();
	    } catch (Exception ex) {
		}*/
	}

	private void serializedSave() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.SAVE_DIALOG);
	    int returnVal = chooser.showSaveDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    String fileName = chooser.getSelectedFile().getPath();
	    if (fileName == null) return;
	    if (fileName.length() == 0) return;

	    model.serializeSave(fileName);
	}

	private void serializedLoad() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.OPEN_DIALOG);
	    int returnVal = chooser.showOpenDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    String fileName = chooser.getSelectedFile().getPath();
	    if (fileName == null) return;
	    if (fileName.length() == 0) return;

	    model.serializeLoad(fileName);
	    table.updateUI();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == addBtn) {
			add();
		} else if (e.getSource() == removeBtn) {
			remove();
		}
	}

	public void add() {
		/* Student st = new Student(nameField.getText(),
				Integer.parseInt(korField.getText()),
				Integer.parseInt(engField.getText()),
				Integer.parseInt(mathField.getText()));
		model.add(st); */
		model.addStudent(nameField.getText(),
				Integer.parseInt(korField.getText()),
				Integer.parseInt(engField.getText()),
				Integer.parseInt(mathField.getText()));
		table.updateUI();
	}

	public void remove() {
		String name = nameField.getText();
		model.remove(name);
		table.updateUI();
	}

	public static void main(String[] args) {
		JFrame frame = new JTableEx();
		frame.setVisible(true);
	}

}

 

StudentModel을 만들어 주는데, Student 클래스를 모델안에 inner 클래스로 만들어 준다. 그리고 AbstractTableModel을 상속받을 것이다. Student 클래스는 간단하게 이름과 성적, 장학금 여부 등을 갖도록 한다. Model 안에는 Student들을 관리해주는 ArrayList를 하나 만들어 주겠다. 

모델의 constructor에는 테스트 sample로서 4명을 넣어주고, getColumnCount() 메서드는 7개의 열로 고정될 것이기 때문에 7을 리턴시킨다. getRowCount()는 list에 추가된 데이터의 크기와 같기 때문에 list.size()를 리턴해주고, getColumnName()은 인덱스 별로 Column Name이 고정되어 있기 때문에 각각의 것을 리턴해 줄수 있게 한다. getColumnClass()도 Name과 마찬가지 방식으로 Column의 Type에 대한 Wrapper Class를 class로 리턴해준다. getValueAt(row, col)은 row번째 Student의 column 값을 가져오도록 한다. add(student) 함수는 Student 객체를 list에 add해주는 작업. remove(name) 은 list를 traverse하면서 지우고자 하는 name이 나오면 지우는 작업을 한다. addStudent(name, kor, eng, math)는 이름과 성적을 받은후 Student 객체를 생성해서 add함수를 호출해준다.

saveText와 loadText는 table의 data를 txt파일 형식으로 저장하고 불러오는 함수이다. 저장시에 txt파일에서 커서의 위치가 마지막 데이터의 끝에 가있는가, 아니면 다음 라인으로 넘어가있는가가 load할때 라인을 읽는 과정에서 문제 될 수 있을지도 모른다고 생각하였다. Table을 로드할 때 라인 수를 알아야 테이블이 정상적으로 나올것이다.

그러므로 loadText에선 for문을 두번 돌려준다. 한 번은 전체 라인수를 알아내기 위한 것, 두번째는 데이터 값을 토큰으로 나눠서 String 배열에 넣은후 addStudent하여 테이블을 구현하기 위한 것. 

serializeSave와 serializeLoad는 Student들을 담고 있는 list를 저장하고 로드하는 함수이다.

 

View 영역의 JTableEx 클래스는 메뉴바 세팅, 각종 UI 배치 및 이벤트를 담아주었다. cellCenter 메서드는 DefaultTableCellRenderer을 사용해서 각 cell들의 alignment를 세팅해주는 함수인데 이후에 사용하지 않을 테스트용 함수이다. saveTextFile, loadTextFile, serializedSave, serializedLoad는 각각 Dialog 띄워주기 위한 함수이고, actionPerformed는 버튼 이벤트 핸들링을 위한 함수이다. add, remove를 각각 버튼에 맞게 호출한다. 

 

 

여기까지가 버전 1이다

============================================================================================

 

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

import javax.swing.*;
import javax.swing.filechooser.*;
import javax.swing.table.*;

class StudentNameCellRenderer extends DefaultTableCellRenderer {

	class StringStudentCell extends JPanel {
		JTable table;
		String value;
		boolean isSelected;
		boolean hasFocus;
		int row; int col;
		StringStudentCell(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
			this.table = table;
			this.value = (String)value;
			this.isSelected = isSelected;
			this.hasFocus = hasFocus;
			this.row = row;
			this.col = col;
		}

		public void paintComponent(Graphics g) {
			String s = value;
			Dimension d = getSize();
			if (isSelected) {
				g.setColor(table.getSelectionBackground());
				g.fillRect(0, 0, d.width, d.height);

				if (hasFocus) {
					g.setColor(table.getGridColor());
					g.drawRect(0, 0, d.width-1, d.height-1);
				}
			} else {
				g.setColor(table.getBackground());
				g.fillRect(0, 0, d.width, d.height);
			}

			if (model.isScholarship(row)) {
				g.setColor(Color.red);
			} else {
				g.setColor(Color.black);
			}
			g.drawString(s, 0, 11);
		}
	}	

	StudentModel model;
	StudentNameCellRenderer(StudentModel model) {
		this.model = model;
	}

	public Component getTableCellRendererComponent(JTable table, 
			Object value, boolean isSelected, boolean hasFocus, int row, int col) {
		if (col == 1) {
			return new StringStudentCell(table, value, isSelected, hasFocus, row, col);
		} else {
			Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
			return cell;
		}
	}

}

class StudentCellRenderer extends DefaultTableCellRenderer {

	class IntegerStudentCell extends JPanel {
		JTable table;
		int value;
		boolean isSelected;
		boolean hasFocus;
		int row; int col;

		IntegerStudentCell(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
			this.table = table;
			this.value = (Integer)value;
			this.isSelected = isSelected;
			this.hasFocus = hasFocus;
			this.row = row;
			this.col = col;
		}

		public void paintComponent(Graphics g) {
			int val = (Integer)value;
			String s = "" + val;
			Dimension d = getSize();
			if (isSelected) {
				g.setColor(table.getSelectionBackground());
				g.fillRect(0, 0, d.width, d.height);

				if (hasFocus) {
					g.setColor(table.getGridColor());
					g.drawRect(0, 0, d.width-1, d.height-1);
				}
			} else {
				g.setColor(table.getBackground());
				g.fillRect(0, 0, d.width, d.height);
			}

			if (val >= 200) {
				g.setColor(Color.blue);
			} else {
				g.setColor(Color.black);
			}

			g.drawString(s, 0, this.getHeight()/5*4);
		}

	}

	public Component getTableCellRendererComponent(JTable table,
			Object value, boolean isSelected, boolean hasFocus, int row, int col) {
		if (col == 5) {
			return new IntegerStudentCell(table, value, isSelected, hasFocus, row, col);
		} else {
			Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
			return cell;
		}
	}
}

class StudentModel extends AbstractTableModel {

	static class Student implements Serializable {
		String name;
		int kor;
		int eng;
		int math;
		int sum;
		boolean scholarship;

		Student (String name, int kor, int eng, int math) {
			this.name = name;
			this.kor = kor;
			this.eng = eng;
			this.math = math;
			sum = kor + eng + math;
			if (sum > 200) scholarship = true;
		}

		public String getName() {
			return name;
		}

		public int getKor() {
			return kor;
		}

		public int getEng() {
			return eng;
		}

		public int getMath() {
			return math;
		}

		public int getSum() {
			return sum;
		}

		public boolean getScholarship() {
			return scholarship;
		}

	}

	ArrayList<Student> list = new ArrayList<Student>();
	/*static int MAX = 100;
	String name[];
	int grade[][];
	boolean scholar[];
	int size;*/

	StudentModel() {
		/*name = new String[MAX];
		grade = new int[MAX][4];
		scholar = new boolean[MAX];
		size = 0;*/
		list.add(new Student("홍충표",70,100,40));
		list.add(new Student("고현규",80,30,60));
		list.add(new Student("김동혁",40,70,50));
		list.add(new Student("유승진",60,50,100));		
	}

	public boolean isScholarship(int row) {
		Student s = list.get(row);
		return s.getScholarship();
	}

	public int getColumnCount() {
		return 7;
	}

	public int getRowCount() {
		return list.size();
	}

	/*title = new Vector<String>(); //Vector
		title.add("순위");
		title.add("이름");
		title.add("국어");
		title.add("영어");
		title.add("수학");
		title.add("합계");
		title.add("장학금여부");*/

	public String getColumnName(int index) {
		if (index == 0) return "순서";
		else if (index == 1) return "이름";
		else if (index == 2) return "국어";
		else if (index == 3) return "영어";
		else if (index == 4) return "수학";
		else if (index == 5) return "합계";
		else if (index == 6) return "장학생";
		else return null;
	}

	public Class getColumnClass(int index) {
		if (index == 0) return Integer.class;
		else if (index == 1) return String.class;
		else if (index == 2) return Integer.class;
		else if (index == 3) return Integer.class;
		else if (index == 4) return Integer.class;
		else if (index == 5) return Integer.class;
		else if (index == 6) return Boolean.class;
		else return null;
	}

	public Object getValueAt(int r, int c) {
		Student st = list.get(r);
		if (c == 0) return r+1;
		else if (c == 1) return st.name;
		else if (c == 2) return st.getKor();
		else if (c == 3) return st.getEng();
		else if (c == 4) return st.getMath();
		else if (c == 5) return st.getSum();
		else if (c == 6) return st.getScholarship();
		else return null;
	}

	public void add(Student st) {
		list.add(st);
	}

	public void remove(String name) {
		Iterator<Student> it = list.iterator();
		while (it.hasNext()) {
			if (it.next().name.equals(name)) it.remove();
		}
	}

	public void addStudent(String name, int kor, int eng, int math) {
		Student s = new Student(name, kor, eng, math);
		add(s);
	}

	public void saveText(String fileName) {
		try {
			FileWriter fw = new FileWriter(new File(fileName));
			String str = "";

			ListIterator<Student> it = list.listIterator();
			while (it.hasNext()) {
				Student st = it.next();
				String aLine = st.name + " " + st.kor + " " + st.eng + " " + st.math + "\r\n"; // 파일 저장시 마지막 커서 위치 고려
				fw.write(aLine);
				fw.flush();
			}			
			/* for (int i = 0; i < table.getRowCount(); i++) {
				for (int j = 0; j < table.getColumnCount(); j++) {
					str = table.getValueAt(i, j) + " ";
					fw.write(str);
				}
				fw.write("\r\n");
			} */
			fw.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public void loadText(String fileName) {
		try {
			BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)));

			int n = 0; // Text File의 라인수 Table load하기위해 미리 알아야함. Text파일에 미리 라인수를 명시하거나 반복문을 두번돌려서 첫반복문에 line수를 얻는다.
			String aLine = null;
			while ((aLine = reader.readLine()) != null) {
				if (aLine.length() == 0) break;
				n++;
			}
			reader.close();

			list.clear();
			reader = new BufferedReader(new FileReader(new File(fileName)));
			for (int i = 0; i < n; i++) {
				aLine = reader.readLine();
				String[] token = aLine.split(" ");
				addStudent(token[0], Integer.parseInt(token[1]), Integer.parseInt(token[2]), Integer.parseInt(token[3]));
			}
			reader.close();

			/*String header = txtReader.readLine();
			String[] line = header.split("\n");
			StringTokenizer st;
			for (int i = 0; i < line.length; i++) {
				st = new StringTokenizer(line[i]);
				st.nextToken();
				String name = st.nextToken();
				int kor = Integer.parseInt(st.nextToken());
				int eng = Integer.parseInt(st.nextToken());
				int math = Integer.parseInt(st.nextToken());
				//Student s = new Student(name, kor, eng, math);
				//model.add(s);
			}

			table.updateUI();
			txtReader.close();*/
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public void serializeSave(String fileName) {
		try {
	    	FileOutputStream fos = new FileOutputStream(fileName);
	    	ObjectOutputStream oos = new ObjectOutputStream(fos);
	    	oos.writeObject(list);
	    	oos.flush();
	    	oos.close();
	    	fos.close();
	    } catch (Exception ex) {
	    	ex.printStackTrace();
		}
		//System.out.println(list);
	}

	public void serializeLoad(String fileName) {
		try {
	    	FileInputStream fis = new FileInputStream(fileName);
	    	ObjectInputStream ois = new ObjectInputStream(fis);	    	
	    	list = (ArrayList<Student>)ois.readObject();    // Reflection -> serialization 가능하게해줌	    	
	    	ois.close();
	    	fis.close();
	    } catch (Exception ex) {
	    	ex.printStackTrace();
		}
		//System.out.println(list);
	}

}

public class JTableEx extends JFrame implements ActionListener {

	JTable table;
	JButton addBtn, removeBtn;
	JMenuBar menuBar;
	JMenu menu;
	JMenu loadMenu;
	JMenu saveMenu;
	JMenuItem textLoadMenu, serialLoadMenu, textSaveMenu, serialSaveMenu;
	JTextField nameField, korField, engField, mathField;
	String fileName; //x
	StudentModel model;

	JTableEx() {
		menuBar = new JMenuBar();
		menu = new JMenu("File");
		menuBar.add(menu);

		menu.add(loadMenu = new JMenu("Load"));
		menu.add(saveMenu = new JMenu("Save"));
		loadMenu.add(textLoadMenu = new JMenuItem("Text"));
		textLoadMenu.addActionListener((e) -> loadTextFile());
		loadMenu.add(serialLoadMenu = new JMenuItem("Serialize"));
		serialLoadMenu.addActionListener((e) -> serializedLoad());
		saveMenu.add(textSaveMenu = new JMenuItem("Text"));
		textSaveMenu.addActionListener((e) -> saveTextFile());
		saveMenu.add(serialSaveMenu = new JMenuItem("Serialize"));
		serialSaveMenu.addActionListener((e) -> serializedSave());
		setJMenuBar(menuBar);

		table = new JTable(model = new StudentModel());
		JScrollPane sp = new JScrollPane(table);

		//cellCenter(table);
		table.setDefaultRenderer(Integer.class, new StudentCellRenderer());
		table.setDefaultRenderer(String.class, new StudentNameCellRenderer(model));

		addBtn = new JButton("Add");
		removeBtn = new JButton("Remove");

		JPanel p = new JPanel();

		nameField = new JTextField();
		korField = new JTextField();
		engField = new JTextField();
		mathField = new JTextField();

		nameField.setPreferredSize(new Dimension(80, 30));
		korField.setPreferredSize(new Dimension(40, 30));
		engField.setPreferredSize(new Dimension(40, 30));
		mathField.setPreferredSize(new Dimension(40, 30));

		nameField.setHorizontalAlignment(JTextField.RIGHT);
		korField.setHorizontalAlignment(JTextField.RIGHT);
		engField.setHorizontalAlignment(JTextField.RIGHT);
		mathField.setHorizontalAlignment(JTextField.RIGHT);

		p.add(new JLabel("이름:"));
		p.add(nameField);
		p.add(new JLabel("국어:"));
		p.add(korField);
		p.add(new JLabel("영어:"));
		p.add(engField);
		p.add(new JLabel("수학:"));
		p.add(mathField);
		p.add(addBtn);
		p.add(removeBtn);

		/*this.addMouseListener(new MouseListener() {

			@Override
			public void mouseClicked(MouseEvent e) {

			}

			@Override
			public void mousePressed(MouseEvent e) {

			}

			@Override
			public void mouseReleased(MouseEvent e) {

			}

			@Override
			public void mouseEntered(MouseEvent e) {

			}

			@Override
			public void mouseExited(MouseEvent e) {

			} 
		});*/

		Container c = getContentPane();
		c.add("Center", sp);
		c.add("South", p);

		setBounds(700, 300, 550, 400);
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		addBtn.addActionListener(this);
		removeBtn.addActionListener(this);
	}

	/*private void cellCenter(JTable table) {
		DefaultTableCellRenderer dtcr = new DefaultTableCellRenderer();
		dtcr.setHorizontalAlignment(SwingConstants.CENTER);	
		TableColumnModel tcm = table.getColumnModel();
		tcm.getColumn(0).setCellRenderer(dtcr);
		tcm.getColumn(1).setCellRenderer(dtcr);
	}*/

	private void saveTextFile() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
		FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt", "txt");
		chooser.setFileFilter(filter);
		int ret = chooser.showSaveDialog(null);
		if (ret != JFileChooser.APPROVE_OPTION) return;
		String fileName = chooser.getSelectedFile().getPath();

		model.saveText(fileName);

		/*JFileChooser chooser = new JFileChooser();

		FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt", "txt");
		chooser.setFileFilter(filter);
		int ret = chooser.showSaveDialog(null);
		if (ret != JFileChooser.APPROVE_OPTION) return;
		String fileName = chooser.getSelectedFile().getPath();

		try {
			FileWriter fw = new FileWriter(new File(fileName));
			fw.write(table.getAccessibleContext().toString());
			fw.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}*/

		/* JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.SAVE_DIALOG);
	    int returnVal = chooser.showSaveDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    String saveName = chooser.getSelectedFile().getPath();
	    if (saveName == null) return;
	    if (saveName.length() == 0) return;
	    fileName = saveName;
	    try {
	    	FileOutputStream fos = new FileOutputStream(fileName);
	    	ObjectOutputStream oos = new ObjectOutputStream(fos);
	    	oos.writeObject(model);
	    	oos.flush();
	    	oos.close();
	    	fos.close();
	    } catch (Exception ex) {
		} */
	}

	private void loadTextFile() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
		chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.OPEN_DIALOG);
	    int returnVal = chooser.showOpenDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    fileName = chooser.getSelectedFile().getPath();

	    model.loadText(fileName);
	    table.updateUI();
		/*JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.OPEN_DIALOG);
	    int returnVal = chooser.showOpenDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    fileName = chooser.getSelectedFile().getPath();
	    try {
	    	FileInputStream fis = new FileInputStream(fileName);
	    	ObjectInputStream ois = new ObjectInputStream(fis);
	    	ois.readObject();		    	
	    	ois.close();
	    	fis.close();
	    } catch (Exception ex) {
		}*/
	}

	private void serializedSave() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.SAVE_DIALOG);
	    int returnVal = chooser.showSaveDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    String fileName = chooser.getSelectedFile().getPath();
	    if (fileName == null) return;
	    if (fileName.length() == 0) return;

	    model.serializeSave(fileName);
	}

	private void serializedLoad() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.OPEN_DIALOG);
	    int returnVal = chooser.showOpenDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    String fileName = chooser.getSelectedFile().getPath();
	    if (fileName == null) return;
	    if (fileName.length() == 0) return;

	    model.serializeLoad(fileName);
	    table.updateUI();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == addBtn) {
			add();
			nameField.setText(" ");
			korField.setText(" ");
			engField.setText(" ");
			mathField.setText(" ");
		} else if (e.getSource() == removeBtn) {
			remove();
		}
	}

	public void add() {
		/* Student st = new Student(nameField.getText(),
				Integer.parseInt(korField.getText()),
				Integer.parseInt(engField.getText()),
				Integer.parseInt(mathField.getText()));
		model.add(st); */
		model.addStudent(nameField.getText(),
				Integer.parseInt(korField.getText()),
				Integer.parseInt(engField.getText()),
				Integer.parseInt(mathField.getText()));
		table.updateUI();
	}

	public void remove() {
		String name = nameField.getText();
		model.remove(name);
		table.updateUI();
	}

	public static void main(String[] args) {
		JFrame frame = new JTableEx();
		frame.setVisible(true);
	}

}

 

StudentNameCellRenderer 클래스로 현재 모델의 셀을 관리해 줄것이다. StringStudentCell 클래스는 StudentNameCellRenderer의 inner class이며 row 단위를 JPanel로써 표현해줄 것이다. cell을 호출할때마다 발생하는 paintComponent 함수는 선택된 row영역을 table의 getSelectionBackground 컬러로 칠해주고 focus 된 특정 cell은 테두리에 gridColor를 칠해준다. table 안의 boolean 값으로 표현된 장학생 영역은 checkBox 형식으로 표현된다. 장학생인 row의 학생이름은 빨간색으로 칠해준다. 

getTableCellRendererComponent() 메서드는 TableCellRenderer 인터페이스에서 필수로 구현해야 하는 함수이며, Returns the component used for drawing the cell, 즉 그려주고자 하는 셀을 가져오기 위함이다. 이걸 통해 특정 셀에 색을 입힌다던지 하는 효과를 줄수 있게 된다.

 

StudentCellRenderer 클래스는 테이블의 Integer 영역을 관리하기 위해서 만들어 준다. 클래스 형식은 StudentNameCellRenderer와 같고 합계가 200이 넘을시 파란색으로 나오게 해준다. 

 

StudentModel과 View(JTableEx) 부분은 딱히 손댄부분이 없다. 

 

 

여기까지가 버전 2이다.

============================================================================================

 

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

import javax.swing.*;
import javax.swing.filechooser.*;
import javax.swing.table.*;

class StudentNameCellRenderer extends DefaultTableCellRenderer {

	class StringStudentCell extends JPanel {
		JTable table;
		String value;
		boolean isSelected;
		boolean hasFocus;
		int row; int col;
		StringStudentCell(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
			this.table = table;
			this.value = (String)value;
			this.isSelected = isSelected;
			this.hasFocus = hasFocus;
			this.row = row;
			this.col = col;
		}

		public void paintComponent(Graphics g) {
			String s = value;
			Dimension d = getSize();
			if (isSelected) {
				g.setColor(table.getSelectionBackground());
				g.fillRect(0, 0, d.width, d.height);

				if (hasFocus) {
					g.setColor(table.getGridColor());
					g.drawRect(0, 0, d.width-1, d.height-1);
				}
			} else {
				g.setColor(table.getBackground());
				g.fillRect(0, 0, d.width, d.height);
			}

			if (model.isScholarship(row)) {
				g.setColor(Color.red);
			} else {
				g.setColor(Color.black);
			}
			g.drawString(s, 0, 11);
		}
	}	

	StudentModel model;
	StudentNameCellRenderer(StudentModel model) {
		this.model = model;
	}

	public Component getTableCellRendererComponent(JTable table, 
			Object value, boolean isSelected, boolean hasFocus, int row, int col) {
		if (col == 1) {
			return new StringStudentCell(table, value, isSelected, hasFocus, row, col);
		} else {
			Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
			return cell;
		}
	}

}

class StudentCellRenderer extends DefaultTableCellRenderer {

	class IntegerStudentCell extends JPanel {
		JTable table;
		int value;
		boolean isSelected;
		boolean hasFocus;
		int row; int col;

		IntegerStudentCell(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
			this.table = table;
			this.value = (Integer)value;
			this.isSelected = isSelected;
			this.hasFocus = hasFocus;
			this.row = row;
			this.col = col;
		}

		public void paintComponent(Graphics g) {
			int val = (Integer)value;
			String s = "" + val;
			Dimension d = getSize();
			if (isSelected) {
				g.setColor(table.getSelectionBackground());
				g.fillRect(0, 0, d.width, d.height);

				if (hasFocus) {
					g.setColor(table.getGridColor());
					g.drawRect(0, 0, d.width-1, d.height-1);
				}
			} else {
				g.setColor(table.getBackground());
				g.fillRect(0, 0, d.width, d.height);
			}

			if (val >= 200) {
				g.setColor(Color.blue);
			} else {
				g.setColor(Color.black);
			}

			g.drawString(s, 0, this.getHeight()/5*4);
		}

	}

	public Component getTableCellRendererComponent(JTable table,
			Object value, boolean isSelected, boolean hasFocus, int row, int col) {
		if (col == 5) {
			return new IntegerStudentCell(table, value, isSelected, hasFocus, row, col);
		} else {
			Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
			return cell;
		}
	}
}

class StudentModel extends AbstractTableModel {

	static class Student implements Serializable {
		String name;
		int kor;
		int eng;
		int math;
		int sum;
		boolean scholarship;

		Student (String name, int kor, int eng, int math) {
			this.name = name;
			this.kor = kor;
			this.eng = eng;
			this.math = math;
			sum = kor + eng + math;
			if (sum > 200) scholarship = true;
		}

		public String getName() {
			return name;
		}

		public int getKor() {
			return kor;
		}

		public int getEng() {
			return eng;
		}

		public int getMath() {
			return math;
		}

		public int getSum() {
			return sum;
		}

		public boolean getScholarship() {
			return scholarship;
		}

	}

	ArrayList<Student> list = new ArrayList<Student>();
	/*static int MAX = 100;
	String name[];
	int grade[][];
	boolean scholar[];
	int size;*/

	StudentModel() {
		/*name = new String[MAX];
		grade = new int[MAX][4];
		scholar = new boolean[MAX];
		size = 0;*/
		list.add(new Student("홍충표",70,100,40));
		list.add(new Student("고현규",80,30,60));
		list.add(new Student("김동혁",40,70,50));
		list.add(new Student("유승진",60,50,100));		
	}

	public boolean isScholarship(int row) {
		Student s = list.get(row);
		return s.getScholarship();
	}

	public int getColumnCount() {
		return 7;
	}

	public int getRowCount() {
		return list.size();
	}

	public void removeRow() {

	}

	/*title = new Vector<String>(); //Vector
		title.add("순위");
		title.add("이름");
		title.add("국어");
		title.add("영어");
		title.add("수학");
		title.add("합계");
		title.add("장학금여부");*/

	public String getColumnName(int index) {
		if (index == 0) return "순서";
		else if (index == 1) return "이름";
		else if (index == 2) return "국어";
		else if (index == 3) return "영어";
		else if (index == 4) return "수학";
		else if (index == 5) return "합계";
		else if (index == 6) return "장학생";
		else return null;
	}

	public Class getColumnClass(int index) {
		if (index == 0) return Integer.class;
		else if (index == 1) return String.class;
		else if (index == 2) return Integer.class;
		else if (index == 3) return Integer.class;
		else if (index == 4) return Integer.class;
		else if (index == 5) return Integer.class;
		else if (index == 6) return Boolean.class;
		else return null;
	}

	public Object getValueAt(int r, int c) {
		Student st = list.get(r);
		if (c == 0) return r+1;
		else if (c == 1) return st.name;
		else if (c == 2) return st.getKor();
		else if (c == 3) return st.getEng();
		else if (c == 4) return st.getMath();
		else if (c == 5) return st.getSum();
		else if (c == 6) return st.getScholarship();
		else return null;
	}

	public void add(Student st) {
		list.add(st);
	}

	public void removeRow(int selected) {
		list.remove(selected);
	}

	public void remove(String name) {
		Iterator<Student> it = list.iterator();
		while (it.hasNext()) {
			if (it.next().name.equals(name)) it.remove();
		}
	}

	public void addStudent(String name, int kor, int eng, int math) {
		Student s = new Student(name, kor, eng, math);
		add(s);
	}

	public void saveText(String fileName) {
		try {
			FileWriter fw = new FileWriter(new File(fileName));
			String str = "";

			ListIterator<Student> it = list.listIterator();
			while (it.hasNext()) {
				Student st = it.next();
				String aLine = st.name + " " + st.kor + " " + st.eng + " " + st.math + "\r\n"; // 파일 저장시 마지막 커서 위치 고려
				fw.write(aLine);
				fw.flush();
			}			
			/* for (int i = 0; i < table.getRowCount(); i++) {
				for (int j = 0; j < table.getColumnCount(); j++) {
					str = table.getValueAt(i, j) + " ";
					fw.write(str);
				}
				fw.write("\r\n");
			} */
			fw.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public void loadText(String fileName) {
		try {
			BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)));

			int n = 0; // Text File의 라인수 Table load하기위해 미리 알아야함. Text파일에 미리 라인수를 명시하거나 반복문을 두번돌려서 첫반복문에 line수를 얻는다.
			String aLine = null;
			while ((aLine = reader.readLine()) != null) {
				if (aLine.length() == 0) break;
				n++;
			}
			reader.close();

			list.clear();
			reader = new BufferedReader(new FileReader(new File(fileName)));
			for (int i = 0; i < n; i++) {
				aLine = reader.readLine();
				String[] token = aLine.split(" ");
				addStudent(token[0], Integer.parseInt(token[1]), Integer.parseInt(token[2]), Integer.parseInt(token[3]));
			}
			reader.close();

			/*String header = txtReader.readLine();
			String[] line = header.split("\n");
			StringTokenizer st;
			for (int i = 0; i < line.length; i++) {
				st = new StringTokenizer(line[i]);
				st.nextToken();
				String name = st.nextToken();
				int kor = Integer.parseInt(st.nextToken());
				int eng = Integer.parseInt(st.nextToken());
				int math = Integer.parseInt(st.nextToken());
				//Student s = new Student(name, kor, eng, math);
				//model.add(s);
			}

			table.updateUI();
			txtReader.close();*/
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public void serializeSave(String fileName) {
		try {
	    	FileOutputStream fos = new FileOutputStream(fileName);
	    	ObjectOutputStream oos = new ObjectOutputStream(fos);
	    	oos.writeObject(list);
	    	oos.flush();
	    	oos.close();
	    	fos.close();
	    } catch (Exception ex) {
	    	ex.printStackTrace();
		}
		//System.out.println(list);
	}

	public void serializeLoad(String fileName) {
		try {
	    	FileInputStream fis = new FileInputStream(fileName);
	    	ObjectInputStream ois = new ObjectInputStream(fis);	    	
	    	list = (ArrayList<Student>)ois.readObject();    // Reflection -> serialization 가능하게해줌	    	
	    	ois.close();
	    	fis.close();
	    } catch (Exception ex) {
	    	ex.printStackTrace();
		}
		//System.out.println(list);
	}

}

public class JTableEx extends JFrame implements ActionListener {

	JTable table;
	JButton addBtn, removeBtn;
	JMenuBar menuBar;
	JMenu menu;
	JMenu loadMenu;
	JMenu saveMenu;
	JMenuItem textLoadMenu, serialLoadMenu, textSaveMenu, serialSaveMenu;
	JTextField nameField, korField, engField, mathField;
	String fileName; //x
	StudentModel model;
	//boolean rowSelected;

	JTableEx() {
		menuBar = new JMenuBar();
		menu = new JMenu("File");
		menuBar.add(menu);

		menu.add(loadMenu = new JMenu("Load"));
		menu.add(saveMenu = new JMenu("Save"));
		loadMenu.add(textLoadMenu = new JMenuItem("Text"));
		textLoadMenu.addActionListener((e) -> loadTextFile());
		loadMenu.add(serialLoadMenu = new JMenuItem("Serialize"));
		serialLoadMenu.addActionListener((e) -> serializedLoad());
		saveMenu.add(textSaveMenu = new JMenuItem("Text"));
		textSaveMenu.addActionListener((e) -> saveTextFile());
		saveMenu.add(serialSaveMenu = new JMenuItem("Serialize"));
		serialSaveMenu.addActionListener((e) -> serializedSave());
		setJMenuBar(menuBar);

		table = new JTable(model = new StudentModel());
		JScrollPane sp = new JScrollPane(table);

		//cellCenter(table);
		table.setDefaultRenderer(Integer.class, new StudentCellRenderer());
		table.setDefaultRenderer(String.class, new StudentNameCellRenderer(model));

		addBtn = new JButton("Add");
		removeBtn = new JButton("Remove");

		JPanel p = new JPanel();

		nameField = new JTextField();
		korField = new JTextField();
		engField = new JTextField();
		mathField = new JTextField();

		nameField.setPreferredSize(new Dimension(80, 30));
		korField.setPreferredSize(new Dimension(40, 30));
		engField.setPreferredSize(new Dimension(40, 30));
		mathField.setPreferredSize(new Dimension(40, 30));

		nameField.setHorizontalAlignment(JTextField.RIGHT);
		korField.setHorizontalAlignment(JTextField.RIGHT);
		engField.setHorizontalAlignment(JTextField.RIGHT);
		mathField.setHorizontalAlignment(JTextField.RIGHT);

		p.add(new JLabel("이름:"));
		p.add(nameField);
		p.add(new JLabel("국어:"));
		p.add(korField);
		p.add(new JLabel("영어:"));
		p.add(engField);
		p.add(new JLabel("수학:"));
		p.add(mathField);
		p.add(addBtn);
		p.add(removeBtn);

		Container c = getContentPane();
		c.add("Center", sp);
		c.add("South", p);

		setBounds(700, 300, 550, 400);
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		addBtn.addActionListener(this);
		removeBtn.addActionListener(this);;
	}

	/*private void cellCenter(JTable table) {
		DefaultTableCellRenderer dtcr = new DefaultTableCellRenderer();
		dtcr.setHorizontalAlignment(SwingConstants.CENTER);	
		TableColumnModel tcm = table.getColumnModel();
		tcm.getColumn(0).setCellRenderer(dtcr);
		tcm.getColumn(1).setCellRenderer(dtcr);
	}*/

	private void saveTextFile() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
		FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt", "txt");
		chooser.setFileFilter(filter);
		int ret = chooser.showSaveDialog(null);
		if (ret != JFileChooser.APPROVE_OPTION) return;
		String fileName = chooser.getSelectedFile().getPath();

		model.saveText(fileName);

		/*JFileChooser chooser = new JFileChooser();

		FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt", "txt");
		chooser.setFileFilter(filter);
		int ret = chooser.showSaveDialog(null);
		if (ret != JFileChooser.APPROVE_OPTION) return;
		String fileName = chooser.getSelectedFile().getPath();

		try {
			FileWriter fw = new FileWriter(new File(fileName));
			fw.write(table.getAccessibleContext().toString());
			fw.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}*/

		/* JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.SAVE_DIALOG);
	    int returnVal = chooser.showSaveDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    String saveName = chooser.getSelectedFile().getPath();
	    if (saveName == null) return;
	    if (saveName.length() == 0) return;
	    fileName = saveName;
	    try {
	    	FileOutputStream fos = new FileOutputStream(fileName);
	    	ObjectOutputStream oos = new ObjectOutputStream(fos);
	    	oos.writeObject(model);
	    	oos.flush();
	    	oos.close();
	    	fos.close();
	    } catch (Exception ex) {
		} */
	}

	private void loadTextFile() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
		chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.OPEN_DIALOG);
	    int returnVal = chooser.showOpenDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    fileName = chooser.getSelectedFile().getPath();

	    model.loadText(fileName);
	    table.updateUI();
		/*JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.OPEN_DIALOG);
	    int returnVal = chooser.showOpenDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    fileName = chooser.getSelectedFile().getPath();
	    try {
	    	FileInputStream fis = new FileInputStream(fileName);
	    	ObjectInputStream ois = new ObjectInputStream(fis);
	    	ois.readObject();		    	
	    	ois.close();
	    	fis.close();
	    } catch (Exception ex) {
		}*/
	}

	private void serializedSave() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.SAVE_DIALOG);
	    int returnVal = chooser.showSaveDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    String fileName = chooser.getSelectedFile().getPath();
	    if (fileName == null) return;
	    if (fileName.length() == 0) return;

	    model.serializeSave(fileName);
	}

	private void serializedLoad() {
		JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
	    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
	    chooser.setDialogType(JFileChooser.OPEN_DIALOG);
	    int returnVal = chooser.showOpenDialog(null);
	    if (returnVal != JFileChooser.APPROVE_OPTION) return;
	    String fileName = chooser.getSelectedFile().getPath();
	    if (fileName == null) return;
	    if (fileName.length() == 0) return;

	    model.serializeLoad(fileName);
	    table.updateUI();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == addBtn) {
			add();
			nameField.setText("");
			korField.setText("");
			engField.setText("");
			mathField.setText("");
		} else if (e.getSource() == removeBtn) {
			int[] selected = table.getSelectedRows();

			for (int i = selected.length - 1; i >= 0; i--) {
				model.removeRow(selected[i]);
			}
			table.updateUI();
		}
	}

	public void add() {
		/* Student st = new Student(nameField.getText(),
				Integer.parseInt(korField.getText()),
				Integer.parseInt(engField.getText()),
				Integer.parseInt(mathField.getText()));
		model.add(st); */
		model.addStudent(nameField.getText(),
				Integer.parseInt(korField.getText()),
				Integer.parseInt(engField.getText()),
				Integer.parseInt(mathField.getText()));
		table.updateUI();
	}

	public void remove() {
		//if (rowSelected) model.remove();
		String name = nameField.getText();
		model.remove(name);
		table.updateUI();
	}

	public static void main(String[] args) {
		JFrame frame = new JTableEx();
		frame.setVisible(true);
	}

}

 

Model에 선택한 row들을 지워줄 removeRow 함수를 만들어준다. 여러 행들을 다중선택하여 지울수 있게 만들어 줄 것이다. view 쪽에서 remove버튼의 actionPerformed 부분을 수정해준다. 테이블에서 선택된 행들의 정보를 담아줄 selected 변수를 만들어주고 JTable의 getSelectedRows() 메서드를 통해 값을 저장한다. Returns the indices of all selected rows. 선택된 모든 행의 정보를 리턴하는 것이다. 그리고 removeRow는 테이블의 뒷부분부터 지워가는게 자연스럽다고 생각돼서 selected.length-1 부터 지워준다.

 

 

 

행 두개 선택후 Remove 버튼을 눌러주었고 잘 작동하는 것을 볼 수 있다.

반응형

댓글