[Java] GUI를 활용한 직원 관리 프로그램
해당 프로젝트 정보(Github) : 링크
목표
- Singleton 디자인 패턴을 활용한 안정적인 객체 생성
- Client와 Server 사이에서 IP/Port 연결을 통해 원활한 소켓 통신 구현
- 소켓 통신 시, 객체 단위 전달을 위한 직렬화(Serializable) 구현
- Client 생성 시 Thread를 활용한 구현
- 프로그램 시각화를 위한 GUI의 JFrame 활용
클래스 다이어그램
Employee
직원 정보 객채 : 번호, 이름, 직책, 거주지
정보 CRUD를 위한 getter와 setter 생성 및 서버 출력에 필요한 toString 메소드 오버라이드
소켓에서 객체 단위 전송을 위한 직렬화(Serializable) 적용
IEmpMgr
구현이 필요한 메소드들을 작성한 인터페이스
load : emp.dat에 저장되어 있는 정보 가져오기
save : emp.dat에 save하여 기존 정보 갱신
add : 직원 정보 추가
search : 직원 정보 검색
update : 직원 정보 수정
delete : 직원 정보 삭제
EmpMgrEmpl
인터페이스를 구현한 클래스
Singleton 디자인 패턴을 활용한 instance 메소드 구현
EmpClient
Thread를 이용한 클라이언트 구현
Ip와 port를 지정하고, Socket 라이브러리 활용
EmpServer
ServerSocket을 통한 서버 구현
지정된 포트로 직원 정보가 들어오면, console 창에 emp.dat에 저장되어있는 직원 정보 출력
EmpUI
GUI를 통한 프로그램 시각화
EmpMgrEmpl에 구현한 메소드를 활용해 JButton Event 처리
RecordNotFoundException, DuplicateException
CRUD 메소드 구현 시, 직원 정보를 찾지 못하거나 이미 저장된 정보일 때 발생시킬 error 구현
실행 화면
1. 서버 실행
2. UI 실행
3. 연결된 UI 모습
Add, Update, Delete, Search 등 메소드를 실행할 때, 성공과 실패 여부를 JLabel을 통해 보여주도록 구현
4. 서버 전송 시, EmpServer Console 창
emp.dat에 저장되어있는 정보가 콘솔 창에 출력됨
5. UI 종료 후 재시작
재시작 후 최근에 저장된 emp.dat에서 불러온 정보가 GUI에 출력
소스 코드
Employee.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | import java.io.Serializable; public class Employee implements Serializable{ private int empNo; private String name; private String position; private String dept; public Employee() { } public Employee(int empNo, String name, String position, String dept ) { super(); this.empNo = empNo; this.name = name; this.position = position; this.dept = dept; } public int getEmpNo() { return empNo; } public void setEmpNo(int empNo) { this.empNo = empNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDept() { return dept; } public void setDept(String dept) { this.dept = dept; } public String getPosition() { return position; } public void setPosition(String position) { this.position = position; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append(empNo); builder.append(" "); builder.append(name); builder.append(" "); builder.append(position); builder.append(" "); builder.append(dept); return builder.toString(); } } | cs |
IEmpMgr.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import java.util.List; public interface IEmpMgr { // filename에서 객체를 읽어들이는 메서드 public void load(String filename) ; // filename에 객체를 쓰는 메서드 public void save(String filename) ; // Employee를 저장하는 매서드 public void add(Employee b) throws DuplicateException; // 전체 직원정보를 리턴하는 메서드 public List<Employee> search(); // 번호를 이용하여 검색된 직원을 리턴하는 메서드 public Employee search(int num) throws RecordNotFoundException; // 번호를 찾아 직원정보를 수정하는 메서드 public void update(Employee b) throws RecordNotFoundException; // 번호를 찾아 직원 정보를 삭제하는 메서드 public void delete(int num) throws RecordNotFoundException; } | cs |
EmpMgrImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.ArrayList; import java.util.List; public class EmpMgrImpl implements IEmpMgr { /** 직원나 매니저의 정보를 저장하기 위한 리스트 */ private List<Employee> emps; private static EmpMgrImpl instance; private EmpMgrImpl() { emps = new ArrayList<Employee>(); load("emp.dat"); } public static EmpMgrImpl getInstance() { if(instance == null) instance = new EmpMgrImpl(); return instance; } /** 파일로 부터 자료 읽어서 메모리(ArrayList)에 저장하기*/ public void load(String filename) { File file=new File(filename); System.out.println(file); if (!file.exists()) return; emps.clear(); ObjectInputStream ois=null; Object ob=null; try{ ois=new ObjectInputStream(new FileInputStream(file)); while(true){//마지막 EOF Exception발생 ob=ois.readObject(); emps.add((Employee)ob); } }catch(EOFException ee){System.out.println("읽기 완료"); }catch(FileNotFoundException fe){ System.out.println("파일이 존재하지 않습니다"); }catch(IOException ioe){ System.out.println(ioe); }catch(ClassNotFoundException ce){ System.out.println("같은 클래스 타입이 아닙니다"); }finally{ if(ois !=null){ try{ ois.close(); }catch(IOException oe){System.out.println("파일을 닫는데 실패했습니다");} } } } @Override public void save(String filename) { File file = new File(filename); ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new FileOutputStream(file)); for(Employee e : emps) { oos.writeObject(e); oos.flush(); } } catch (FileNotFoundException e) { System.err.println(e); } catch (IOException e) { System.err.println(e); } finally { try { oos.close(); } catch (IOException e) { System.err.println(e); } } } @Override public void add(Employee b) throws DuplicateException { for (Employee e : emps) { if(e.getEmpNo() == b.getEmpNo()) { throw new DuplicateException(); } } emps.add(b); } @Override public List<Employee> search(){ return emps; } @Override public Employee search(int num) throws RecordNotFoundException { for (Employee e : emps) { if(e.getEmpNo() == num) { return e; } } throw new RecordNotFoundException(); } @Override public void update(Employee b) throws RecordNotFoundException { boolean chk = true; for (Employee e : emps) { if(e.getEmpNo() == b.getEmpNo() ) { e.setName(b.getName()); e.setPosition(b.getPosition()); e.setDept(b.getDept()); chk = false; break; } } if(chk) throw new RecordNotFoundException(); } @Override public void delete(int num) throws RecordNotFoundException { Employee e = search(num); emps.remove(e); } } | cs |
RecordNotFoundException.java
1 2 3 4 5 6 7 8 | class RecordNotFoundException extends Exception { @Override public String toString() { return super.toString() + ": 데이터가 없습니다."; } } | cs |
DuplicateException.java
1 2 3 4 5 6 7 8 | class DuplicateException extends Exception { @Override public String toString() { return super.toString() + ": 데이터가 중복되었습니다."; } } | cs |
EmpClient.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import java.io.IOException; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.List; class EmpClient extends Thread { private List<Employee> emps; private String ip = "localhost"; private int port = 6000; public EmpClient(List<Employee> emps) { this.emps = emps; } @Override public void run() { Socket s = null; ObjectOutputStream oos = null; try { s = new Socket(ip, port); oos = new ObjectOutputStream(s.getOutputStream()); for(Employee e : emps) { oos.writeObject(e); oos.flush(); } } catch (Exception e) { System.err.println(e); } finally { try { oos.close(); s.close(); } catch (IOException e) { System.err.println(e); } } } } | cs |
EmpServer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import com.emp.Employee; public class EmpServer { private int port = 6000; public void receive() { ServerSocket ss = null; try { ss = new ServerSocket(port); System.out.println("ServerSocket ok. port=" + port); } catch (Exception e) { System.err.println(e); } while(true) { Socket s = null; ObjectInputStream ois = null; try { System.out.println("server ready..."); s = ss.accept(); ois = new ObjectInputStream(s.getInputStream()); while(true) { Employee e = (Employee) ois.readObject(); if(e == null) break; System.out.println(e); } } catch (Exception e) { //System.err.println(e); } finally { try { System.out.println("receive ok"); ois.close(); s.close(); } catch (Exception e2) { System.err.println(e2); } } } } public static void main(String[] args) { new EmpServer().receive(); } } | cs |
EmpUI.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | import java.awt.BorderLayout; import java.awt.Color; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.List; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; public class EmpUI implements ActionListener{ private JFrame frame; private JList list; private JTextField txtEmpNo; private JTextField txtName; private JTextField txtDept; private JTextField txtPosition; private JLabel lblStatus; private JButton btnAdd; private JButton btnSearch; private JButton btnUpdate; private JButton btnDelete; private JButton btnSave; private JButton btnUpload; private JButton btnClear; EmpMgrImpl mgr = EmpMgrImpl.getInstance(); public EmpUI(){ frame = new JFrame("EmpManager Client"); lblStatus = new JLabel(" "); lblStatus.setBackground(Color.LIGHT_GRAY); lblStatus.setForeground(Color.BLUE); txtEmpNo = new JTextField(); txtName = new JTextField(); txtPosition = new JTextField(); txtDept = new JTextField(); btnAdd = new JButton("Add"); btnUpdate = new JButton("Update"); btnSearch = new JButton("Search"); btnClear= new JButton("Clear"); btnDelete = new JButton("Delete"); btnSave = new JButton("SaveToFile"); btnUpload = new JButton("SendToServer"); list = new JList(); JPanel inputs = new JPanel(); JPanel inputLables = new JPanel(); JPanel inputFields = new JPanel(); JPanel inputBtns = new JPanel(); inputLables.setLayout(new GridLayout(4,1)); JLabel lblEmpNo = new JLabel("EmpNo"); lblEmpNo.setHorizontalAlignment(SwingConstants.CENTER); JLabel lblName = new JLabel("Name"); lblName.setHorizontalAlignment(SwingConstants.CENTER); JLabel lblGrade = new JLabel("Position"); lblGrade.setHorizontalAlignment(SwingConstants.CENTER); JLabel lblDiv = new JLabel("Department"); lblDiv.setHorizontalAlignment(SwingConstants.CENTER); inputLables.add(lblEmpNo); inputLables.add(lblName); inputLables.add(lblGrade); inputLables.add(lblDiv); inputFields.setLayout(new GridLayout(4,1)); inputFields.add(txtEmpNo); inputFields.add(txtName); inputFields.add(txtPosition); inputFields.add(txtDept); inputBtns.setLayout(new GridLayout(1,4)); inputBtns.add(btnAdd); inputBtns.add(btnUpdate); inputBtns.add(btnDelete); inputBtns.add(btnSearch); inputBtns.add(btnClear); inputs.setLayout(new BorderLayout()); inputs.add(inputLables, BorderLayout.WEST); inputs.add(inputFields, BorderLayout.CENTER); inputs.add(inputBtns, BorderLayout.SOUTH); JPanel center = new JPanel(); center.setLayout(new BorderLayout()); center.add(list); center.add(lblStatus, BorderLayout.NORTH); JPanel pnlBtns = new JPanel(); pnlBtns.setLayout(new GridLayout(1,4)); pnlBtns.add(btnSave); pnlBtns.add(btnUpload); frame.add(inputs, BorderLayout.NORTH); frame.add(center); frame.add(pnlBtns, BorderLayout.SOUTH); frame.setSize(500, 400); frame.setVisible(true); showList(); } /** 이벤트 등록 */ public void addEvent(){ frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); btnAdd.addActionListener(this); btnClear.addActionListener(this); btnDelete.addActionListener(this); btnSave.addActionListener(this); btnSearch.addActionListener(this); btnUpdate.addActionListener(this); btnUpload.addActionListener(this); list.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent ee) { if(list.getSelectedValue()==null) return; Employee e=(Employee) list.getSelectedValue(); txtEmpNo.setText(e.getEmpNo()+""); txtName.setText(e.getName()); txtPosition.setText(e.getPosition()); txtDept.setText(e.getDept()); } }); } @Override public void actionPerformed(ActionEvent e) { if(e.getSource()==btnAdd){ addRecord(); }else if(e.getSource()==btnUpdate){ updateRecord(); }else if(e.getSource()==btnSearch){ searchRecord(); }else if(e.getSource()==btnClear){ clearField(); lblStatus.setText(" "); }else if(e.getSource()==btnDelete){ deleteRecord(); }else if(e.getSource()==btnSave){ saveRecord(); }else if(e.getSource()==btnUpload){ new EmpClient(mgr.search()).start(); } } private void addRecord() { String empNo=txtEmpNo.getText().trim(); String name=txtName.getText().trim(); String position=txtPosition.getText().trim(); String dept=txtDept.getText().trim(); if(empNo.equals("") ||name.equals("") ||position.equals("")||dept.equals("")){ lblStatus.setText("모든 항목를 입력해 주세요."); return; } try { mgr.add(new Employee(Integer.parseInt(empNo),name,position,dept)); lblStatus.setText("등록 성공"); showList(); clearField(); } catch (NumberFormatException e) { lblStatus.setText("EmpNo은 숫자로 입력해주세요"); return; } catch (DuplicateException e) { lblStatus.setText(e.toString()); } } private void updateRecord(){ String empNo=txtEmpNo.getText().trim(); String name=txtName.getText().trim(); String position=txtPosition.getText().trim(); String dept=txtDept.getText().trim(); if(empNo.equals("") ||name.equals("") ||position.equals("")||dept.equals("")){ lblStatus.setText("모든 항목를 입력해 주세요."); return; } try { Employee empl = new Employee(Integer.parseInt(empNo), name, position, dept); mgr.update(empl); lblStatus.setText("수정 성공"); showList(); clearField(); } catch (NumberFormatException e) { lblStatus.setText("EmpNo은 숫자로 입력해주세요"); return; } catch (RecordNotFoundException e) { lblStatus.setText(e.toString()); } } private void searchRecord(){ String empNo = txtEmpNo.getText().trim(); if(empNo.equals("")) { lblStatus.setText("직원 번호를 입력해 주세요."); return; } try { Employee e = mgr.search(Integer.parseInt(empNo)); mgr.search(e.getEmpNo()); lblStatus.setText("검색 성공"); showList(); txtEmpNo.setText(Integer.toString(e.getEmpNo()));; txtName.setText(e.getName());; txtPosition.setText(e.getPosition()); txtDept.setText(e.getDept()); } catch (NumberFormatException e) { lblStatus.setText("EmpNo은 숫자로 입력해주세요"); return; } catch (RecordNotFoundException e) { lblStatus.setText(e.toString()); } } private void deleteRecord(){ String empNo = txtEmpNo.getText().trim(); if(empNo.equals("")) { lblStatus.setText("직원 번호를 입력해 주세요."); return; } try { mgr.delete(Integer.parseInt(empNo)); lblStatus.setText("삭제 성공"); showList(); clearField(); } catch (NumberFormatException e) { lblStatus.setText("EmpNo은 숫자로 입력해주세요"); return; } catch (RecordNotFoundException e) { lblStatus.setText(e.toString()); } } private void saveRecord(){ try { mgr.save("emp.dat"); lblStatus.setText("저장 성공"); } catch (Exception e) { lblStatus.setText(e.toString()); } } /** AWT List 컴포넌트에 직원정보 표시 */ private void showList(){ List<Employee> ee=mgr.search(); list.removeAll(); list.setListData(ee.toArray()); } /** 직원정보를 입력하는 TextField의 내용 제거 */ private void clearField(){ txtEmpNo.setText(" "); txtName.setText(" "); txtPosition.setText(" "); txtDept.setText(" "); } public static void main(String[] args){ EmpUI ui = new EmpUI(); ui.addEvent(); } } | cs |
'Java' 카테고리의 다른 글
[Java] 직렬화(Serialization) (0) | 2021.07.04 |
---|---|
[Java] 컴파일 과정 (1) | 2019.06.10 |
[자바(java)/스프링(spring)] 면접 질문 모음 (1) | 2019.02.13 |
[Java] 필수 개념 정리 (1) | 2019.01.20 |
자바 - 데이터타입/기본문법 (0) | 2019.01.02 |