공부의 기록/자바 풀 스택 : 수업내용정리

자바 풀 스택 12/31 오후 기록 028-2

파티피플지선 2024. 12. 31. 17:59

<14:30 ~~ 오후 수업 과제>

[특정 주제를 정해서 JFrame으로 해당 주제를 사용할 수 있도록 프로그래밍 해보기]

1. 주제 정하기(점심 전에 완료)

2. 테이블 설계하기, 시퀀스도 필요하면 만들기(점심 전에 완료)

3. dto 클래스 만들기(점심 전에 완료)

------------------------------------------------------------------------------------

점심 먹고 와서 엄청 졸립다 ㅠ

dao 클래스 만들고 프레임 클래스 만들고 일찍 만들면 복습도 좀 해보자 어차피 집가서 안할거니까!

 

4. dao 클래스 만들기

일단 dao 클래스를 만들기는 했는데 엄청 따라 보면서 만들어서 어느 부분이 부족한지 그 내부 부분 나눠서 셀프 피드백 해보자

더보기
package test.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import test.dto.BtRDto;
import test.util.DBConnector;

public class BtRDao {
	public boolean insert(BtRDto dto) {
		Connection conn= null;
		PreparedStatement pstmt=null;
		int rowCount=0;
		try {
			conn=new DBConnector().getConn();
			String sql="""
					insert into BtR
					(no, title, writer)
					values(seq_BtR.nextval, ?, ?)
					""";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, dto.getTitle());
			pstmt.setString(2, dto.getWriter());
			rowCount=pstmt.executeUpdate();
		}catch(SQLException se){
			se.printStackTrace();
		}finally {
			try {
				if(pstmt!=null)pstmt.close();
				if(conn!=null)conn.close();
			}catch(Exception e) {}
		}
		if(rowCount>0) {
			return true;
		}else {
			return false;
		}
	}
	
	public boolean update(BtRDto dto) {
		Connection conn=null;
		PreparedStatement pstmt=null;
		int rowCount=0;
		try {
			conn= new DBConnector().getConn();
			String sql="""
					update BtR
					set title=?, writer=?
					where no=?
					""";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, dto.getTitle());
			pstmt.setString(2, dto.getWriter());
			pstmt.setInt(3, dto.getNo());
			rowCount=pstmt.executeUpdate();
		}catch(SQLException se) {
			se.printStackTrace();
		}finally {
			try {
				if(pstmt!=null)pstmt.close();
				if(conn!=null)conn.close();				
			}catch(Exception e){	}
		}
		if(rowCount>0) {
			return true;
		}else {
			return false;
		}
	}
	
	public boolean delete(int num) {
		Connection conn=null;
		PreparedStatement pstmt = null;
		int rowCount=0;
		try {
			conn = new DBConnector().getConn();
			String sql="""
					delete from BtR
					where no=?
					""";
			pstmt= conn.prepareStatement(sql);
			pstmt.setInt(1, num);
			rowCount=pstmt.executeUpdate();
		}catch(SQLException se) {
			se.printStackTrace();
		}finally {
			try {
				if(pstmt!=null)pstmt.close();
				if(conn!=null)conn.close();
			}catch(Exception e) {
				
			}
		}
		if (rowCount>0) {return true;}
		else {return false;}
		
	}
	
	public BtRDto getData(int no) {
		BtRDto dto=null;
		
		Connection conn=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		try {
			conn= new DBConnector().getConn();
			String sql="""
					select no, title, writer
					from BtR
					where no =?
					""";
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, no);
			rs=pstmt.executeQuery();
			if(rs.next()){
				dto=new BtRDto();
				dto.setNo(no);
				dto.setTitle(rs.getString("title"));
				dto.setWriter(rs.getString("writer"));
			}
			
		} catch(SQLException se) {
			se.printStackTrace();
		}finally {
			try {
				if(rs!=null)rs.close();
				if(pstmt!=null)pstmt.close();
				if(conn!=null)conn.close();
			}catch(Exception e) {}
			
		}
		return dto;
		
	}	
	
	public List<BtRDto> getList(){
		List<BtRDto> list = new ArrayList<>();
		Connection conn=null;
		PreparedStatement pstmt=null;
		ResultSet rs = null;
		try {
			conn =new DBConnector().getConn();
			String sql="""
					select no, title, writer
					from BtR
					order by no asc
					""";
			pstmt = conn.prepareStatement(sql);
			rs=pstmt.executeQuery();
			while(rs.next()) {
				BtRDto dto=new BtRDto();
				dto.setNo(rs.getInt("no"));
				dto.setTitle(rs.getString("title"));
				dto.setWriter(rs.getString("writer"));
				list.add(dto);
			}
		}catch(SQLException se) {
			se.printStackTrace();
		}finally {
			try {
				if(rs!=null)rs.close();
				if(pstmt!=null)pstmt.close();
				if(conn!=null)conn.close();
			}catch(Exception e) {}
		}
		return list;
	}
	
}

 

 

얘는 거의 통째로 흘긋 거리면서 함... 자주 틀리는 부위니까 다시 잘 살펴보자.

 

 

5. 프레임 클래스 만들기(기능 : 추가해서 저장, 삭제 기능) + 편집 기능

선생님이 주신 편집 기능 관련 코드

public class MemberFrame extends JFrame implements ActionListener, PropertyChangeListener{
	//필드
	JTextField inputName, inputAddr;
	DefaultTableModel model;
	JTable table;
	
	
	//생성자
	public MemberFrame() {
		setLayout(new BorderLayout());
		
		JLabel label1=new JLabel("이름");
		inputName=new JTextField(10);
		
		JLabel label2=new JLabel("주소");
		inputAddr=new JTextField(10);
		
		JButton saveBtn=new JButton("저장");
		saveBtn.setActionCommand("save");
		
		//삭제 버튼 추가
		JButton deleteBtn=new JButton("삭제");
		deleteBtn.setActionCommand("delete");
		
		JPanel panel=new JPanel();
		panel.add(label1);
		panel.add(inputName);
		panel.add(label2);
		panel.add(inputAddr);
		panel.add(saveBtn);
		panel.add(deleteBtn);
		
		add(panel, BorderLayout.NORTH);
		
		//표형식으로 정보를 출력하기 위한 JTable
		table=new JTable();
		//칼럼명을 String[] 에 순서대로 준비
		String[] colNames= {"번호", "이름", "주소"};
		//테이블에 출력할 정보를 가지고 있는 모델 객체 (칼럼명, row 갯수)
		model=new DefaultTableModel(colNames, 0) {
			@Override
			public boolean isCellEditable(int row, int column) {
				System.out.println(row+" | "+column);
				
				if(column==0) { // 0번째 칼럼은 
					return false; //수정 불가하게 false 를 리턴해 준다.
				}else { //다른 경우는 
					return true; //모두 수정 가능하게 true 를 리턴해 준다. 
				}
			}
		};
		
		//모델을 테이블에 연결한다.
		table.setModel(model);
		//스크롤이 가능 하도록 테이블을 JScrollPane 에 감싼다.
		JScrollPane scroll=new JScrollPane(table);
		//JScrollPane  을 프레임의 가운데에 배치하기 
		add(scroll, BorderLayout.CENTER);
		
		displayMember();
		
		//버튼에 액션리스너 등록
		saveBtn.addActionListener(this);
		deleteBtn.addActionListener(this);
		
		//테이블에 값이 바뀌었는지 감시할 리스너 등록
		table.addPropertyChangeListener(this);
	}
	
	//테이블에 데이터 출력하는 메소드
	public void displayMember() {
		
		model.setRowCount(0); //테이블에 출력된 데이터 reset 
		
		//실제 DB 에 저장된 데이터
		MemberDao dao=new MemberDao();
		List<MemberDto> list=dao.getList();
		
		for(MemberDto tmp:list) {
			//MemberDto 객체에 있는 회원 정보를 이용해서  Object 배열을 만든다 
			Object[] row= {tmp.getNum(), tmp.getName(), tmp.getAddr()};
			//row 를 추가한다.
			model.addRow(row);
		}
		
	}
	
	
	//main  메소드
	public static void main(String[] args) {
		MemberFrame f=new MemberFrame();
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setBounds(100, 100, 800, 500);
		f.setVisible(true);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		//눌러진 버튼의 action command 값을 읽어와서 
		String command=e.getActionCommand();
		//분기한다. 
		if(command.equals("save")) {
			//1. 입력한 이름과, 주소를 읽어온다.
			String name=inputName.getText();
			String addr=inputAddr.getText();
			//2. 읽어온 이름과 주소를 MemberDto 객체를 생성해서 담는다.
			MemberDto dto=new MemberDto();
			dto.setName(name);
			dto.setAddr(addr);
			//3. MemberDao 객체를 이용해서 DB 에 저장을 한다. 
			MemberDao dao=new MemberDao();
			dao.insert(dto);
			//4. refresh ! 
			displayMember();
		}else if(command.equals("delete")) {
			//1. 선택한 row 가 있는지 , 있다면 어떤 row 를 선택했는지 알아내기
			//int selectedIndex=table.getSelectedRow();
			int[] rows=table.getSelectedRows();
			if(rows.length == 0) {
				//선택된 row 가 없다고 알려준다.
				JOptionPane.showMessageDialog(this, "선택된 row 가 없습니다.");
				//프레임아 밑에 코드는 실행하지마!
				return; 
			}
			
			for(int tmp:rows) {
				//2.선택한 row 의 가장 첫번째 칼럼에 있는 숫자를 읽어내기
				int num=(int)model.getValueAt(tmp, 0);
				//3. MemberDao 객체를 이용해서 DB 에서 삭제
				MemberDao dao=new MemberDao();
				dao.delete(num);
			}
			
			//4. refresh
			displayMember();
		}
	}

	
	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		// TODO Auto-generated method stub
		System.out.println("property change!");
		System.out.println("property name:"+evt.getPropertyName());
		
		System.out.println("isEditing:"+table.isEditing());
		/*
		 *  property name 이 "tableCellEditor" 이고
		 *  table 이 수정중이 아닐때 
		 *  현재 포커스가 있는 곳의 정보를 모두 읽어와서 DB 에 수정반영하기 
		 */
		if(evt.getPropertyName().equals("tableCellEditor") && !table.isEditing()) {
			//현재 포커스가 있는 row 의 정보를 DB 에 수정 반영 한다. 
			//변화된 값을 읽어와서 DB 에 반영한다. 
			//수정된 칼럼에 있는 row  전체의 값을 읽어온다. 
			int selectedIndex=table.getSelectedRow();
			int num=(int)model.getValueAt(selectedIndex, 0);
			String name=(String)model.getValueAt(selectedIndex, 1);
			String addr=(String)model.getValueAt(selectedIndex, 2);
			//수정할 회원의 정보를 MemberDto 객체에 담고 
			MemberDto dto=new MemberDto(num, name, addr);
			//DB에 저장하기 
			new MemberDao().update(dto);
			//선택된 포커스 clear
			table.clearSelection();
		}
	
	}
}

 

 

 

 

수정하는 기능은 아직 못 넣어봤...은 너무 욕심이 과해

간신히 추가 기능이랑 삭제 기능 넣어봄.

package test.frame;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;

import test.dao.BtRDao;
import test.dto.BtRDto;

public class BtRFrame extends JFrame implements ActionListener{
	JTextField inputTitle, inputWriter;
	DefaultTableModel model;
	JTable table;
	
	public BtRFrame(String title) {
		super(title);
		
		setLayout(new BorderLayout());
		JLabel label2=new JLabel("책 제목");
		JLabel label3=new JLabel("저자");
		
		inputTitle = new JTextField(50);
		inputWriter = new JTextField(30);
		
		JButton addBtn=new JButton("추가");
		JButton deleteBtn=new JButton("삭제");
		
		JPanel panel=new JPanel();
		panel.add(label2);
		panel.add(inputTitle);
		panel.add(label3);
		panel.add(inputWriter);
		panel.add(addBtn);
		panel.add(deleteBtn);
		panel.setSize(1500,500);
		
		panel.setBackground(Color.orange);
		add(panel, BorderLayout.NORTH);
		addBtn.addActionListener(this);
		deleteBtn.addActionListener(this);
		addBtn.setActionCommand("add");
		deleteBtn.setActionCommand("delete");
		
		table =new JTable();
		String[] colNames= {"번호", "책 제목", "저자"};
		model=new DefaultTableModel();
		model.setColumnIdentifiers(colNames);
		model.setRowCount(0);
		
		table.setModel(model);
		JScrollPane scroll=new JScrollPane(table);
		add(scroll, BorderLayout.CENTER);

		printBtR();
		
		table.getTableHeader().setFont(new Font("Sans-serif",Font.BOLD, 18));
		table.setFont(new Font("Sans-serif", Font.PLAIN, 16));
		table.setRowHeight(25);
	}


	public static void main(String[] args) {
		BtRFrame f=new BtRFrame("읽을 책 목록");
		f.setDefaultCloseOperation(EXIT_ON_CLOSE);
		f.setBounds(20,20, 1500, 1000);
		f.setVisible(true);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		String command=e.getActionCommand();
		if(command.equals("add")) {
			String title=inputTitle.getText();
			String writer=inputWriter.getText();
			BtRDto dto=new BtRDto();
			dto.setTitle(title);
			dto.setWriter(writer);
			BtRDao dao=new BtRDao();
			dao.insert(dto);
		}else if(command.equals("delete")) {
			int selectedRow=table.getSelectedRow();
			if(selectedRow==-1) {
				JOptionPane.showMessageDialog(this, "삭제할 row를 선택하세요");
				return;
			}
			int num=(int)model.getValueAt(selectedRow, 0);
			new BtRDao().delete(num);
		}
		printBtR();
	}
	
	
	public void printBtR() {
		model.setRowCount(0);
		BtRDao dao= new BtRDao();
		List<BtRDto> list=dao.getList();
		for(BtRDto tmp:list) {
			Object[] rowData= {tmp.getNo(), tmp.getTitle(), tmp.getWriter()};
			model.addRow(rowData);
		}
		
	}
	
}

 

나만의 읽을 책 리스트를 만들었는데, 수정하는 기능도 넣으면 좋을 것 같긴하다. 어떻게 할지는 두고 봐야겠지만.

개선하고 싶은 부분

1. 수정하는 기능 추가하기

2. 번호 칼럼의 폭 줄이고 책 제목 폭 넓히기

3. 번호 칼럼, 제목 칼럼 우측 정렬

4. 패널 영역 크기 조절 시도 했는데 실패했다. 어떻게 해야 하는지 확인해보기

 

남은 시간은 수정하는 기능 추가하는 거 시도하다가 집에 가야겠다.