[Java GUI] 연락처 관리 프로그램 (ver2.0)

HSRyuuu dev blog·2023년 3월 30일
0
post-thumbnail

연락처 관리 프로그램 (ver2.0)

지난 ver.1.0은 객체지향 설계, 클래스이용, 자료구조 이용 등을 고려하지 않고, 구현에만 집중했다고 했었다.

이후, 객체지향 프로그래밍을 좀 더 공부하며 이전보다 조금더 복잡도를 줄여서 리팩토링 할 수 있을까 고민해보았다.

이전에는 배열과 String을 통해서 데이터를 관리하고, GUI 클래스 내에 static 변수로 모든 데이터를 관리했었다.

ver.2.0에서는 Map 자료구조를 이용하였고,  Person 클래스를 이용하여 관리하는것으로 변경해 보았다.

아직 많이 부족한것 같고, 딱 봐도 좀 지저분한  부분이 있는것 같지만, 자료구조를 응용하여 처음으로 프로그램에 적용해 보았고, 변경하면서 조금 더 정확히 이해하게된 측면이 있는 것 같다.

< 변경점 >

  1. 데이터 관리
  • ver.1.0) 이름, 나이, 생일, 학번, 전화번호를 각각을 tab( \t ) 로 구분하여 문자열로 저장
  • ver.2.0) Map<String, Person> 으로 관리 / Map의 key는 Person.getName()으로 사용
  1. 데이터베이스 - 이전과 동일하게 TextFile을 이용
  • ver.1.0) 모든 정보를 TextFile에서 가져오고, 변경하며 관리
  • ver.2.0) 모든 정보를 Map으로 관리, TextFile은 저장소의 역할만 한다.

1. GUI 클래스

package addressManagement;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.regex.Pattern;

public class AddressGUI extends JFrame {
    String fname = "data/juso.txt";
    static JTable table;
    static String[] colNames = {"이름","나이","생일","학번","전화번호"};
    static String[][] data = new String[50][5];
    static JTextField nameSpace,studentNumSpace,ageSpace,birthDaySpace,phoneSpace;

    public AddressGUI() throws IOException {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//종료버튼
        setTitle("연락처 관리");// 제목 설정
        setResizable(false);
        this.setLayout(null);
        PersonList firstList = new PersonList();
        PersonList mainList = new PersonList();
        mainList.setMainMap(firstList.getTextFile());
        data = mainList.getDataArray();

//panel1----------------------------------------------------------------------
        JPanel panel1 = new JPanel();
        panel1.setLayout(new FlowLayout());

//연락처 출력 버튼
        JButton printBtn = new JButton("연락처 출력");
        printBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                    tableRefresh(mainList);
            }
        });
        panel1.add(printBtn);

//나가기 버튼
        JButton exitBtn = new JButton(" 나가기 ");
        exitBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                System.exit(0);
            }
        });
        panel1.add(exitBtn);

//연락처 삭제 버튼, label
        JLabel deleteAddress = new JLabel("          삭제할 연락처(이름) : ");
        panel1.add(deleteAddress);

        JTextField delName = new JTextField(5);
        panel1.add(delName);

        JButton delete = new JButton("연락처 삭제");
        delete.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                int result = mainList.containsKeyCheck(delName.getText());
                if(result==0) {
                    mainList.deletePerson(delName.getText());
                }else if(result==1) {
                    JOptionPane error = new JOptionPane();
                    error.showMessageDialog(null, "삭제 란이 빈칸입니다.");
                }else if(result==2){
                    JOptionPane error = new JOptionPane();
                    error.showMessageDialog(null, "존재하지 않는 이름입니다.");
                }
                tableRefresh(mainList);
                try {
                    mainList.setTextFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
        panel1.add(delete);

//panel 위치 설정
        panel1.setBounds(10,10,850,40);// (x축, y축, 폭, 높이)
				this.add(panel1);//setBounds로 정한 위치에 panel1 추가
//panel2 : 입력창 ---------------------------------------------------------------------------------------------------------
        JPanel panel2 = new JPanel();
        panel2.setLayout(new FlowLayout());

        JLabel nameTxt,studentNumTxt,ageTxt,birthTxt,phoneTxt;

//label, TextField 배치
        nameTxt = new JLabel(" 이름");panel2.add(nameTxt);
        nameSpace =  new JTextField(5);panel2.add(nameSpace);
        ageTxt= new JLabel("   나이");panel2.add(ageTxt);
        ageSpace = new JTextField(3);panel2.add(ageSpace);
        birthTxt= new JLabel("   생일");panel2.add(birthTxt);
        birthDaySpace =  new JTextField(10);panel2.add(birthDaySpace);
        studentNumTxt= new JLabel("   학번");panel2.add(studentNumTxt);
        studentNumSpace = new JTextField(8);panel2.add(studentNumSpace);
        phoneTxt = new JLabel("  전화번호");panel2.add(phoneTxt);
        phoneSpace =  new JTextField(12);panel2.add(phoneSpace);

//연락처 등록 버튼
        JButton regist = new JButton("연락처 등록");
        regist.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                String errorMsg = judgeExp(getTexts());
                if(errorMsg==""){
                    mainList.addPerson(makePerson());
                }else{
                    JOptionPane error = new JOptionPane();//에러메시지 출력해주는 클래스
                    error.showMessageDialog(null, errorMsg);
                }
                tableRefresh(mainList);
                try {
                    mainList.setTextFile();
                    setTextDefault();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        panel2.add(regist);
//panel2 위치 설정
        panel2.setBounds(10,50,850,50);
        this.add(panel2);

//panel3 : 테이블---------------------------------------------------------------------------------------------------
        JPanel panel3 = new JPanel();
//연락처를 출력할 table 설정
        String[][] data = new String[50][5];
        String[] colNames = {"이름","나이","생일","학번","전화번호"};

        table = new JTable(data,colNames);
        JScrollPane sp = new JScrollPane(table);//scrollPane 에 테이블 위치시킴
        table.setFillsViewportHeight(true);// scrollPane 안에 테이블을 꽉 차서 보이게 함
        Dimension d = table.getPreferredSize();// d에서 설정한 사이즈를 넘어갈 시 스크롤바가 생성되도록 설정
        d.width = 700;
        d.height = 120;
        sp.setPreferredSize(d);//스크롤바 생성
        panel3.add(sp);

        panel3.setBounds(0,100,850,200);
        this.add(panel3);

        setSize(850,280);// 윈도우 크기설정
        setVisible(true);// 윈도우가 화면에 보임
    }

    static void tableRefresh(PersonList mainList){
        data = mainList.getDataArray();
        DefaultTableModel model = new DefaultTableModel(data,colNames);
        table.setModel(model);
    }

    static Person makePerson(){
            Person person = new Person(nameSpace.getText(), ageSpace.getText(), birthDaySpace.getText(), studentNumSpace.getText(), phoneSpace.getText());
            return person;
    }
    static String[] getTexts(){
        String[] infos = {nameSpace.getText(),ageSpace.getText(),birthDaySpace.getText(),studentNumSpace.getText(),phoneSpace.getText()};
    return infos;
    }
    static void setTextDefault(){
        nameSpace.setText("");
        ageSpace.setText("");
        birthDaySpace.setText("");
        studentNumSpace.setText("");
        phoneSpace.setText("");
    }

    static String judgeExp(String[] infos) {
        String msg1 = "", msg2 = "", msg3 = "", msg4 = "", msg5 = "", msg6 = "";//에러뜨면 에러메시지에 추가할 문자열
        String error = "";//위의 문자열중에 해당하는것만 error에 추가해줄
        String wstr = "";
        int ageCheck = 0;
        String nameExp = "^[가-힣]*$|^[a-zA-Z]*$";//이름 pattern (형식) 포맷
        String phoneExp = "(02|010)-\\d{3,4}-\\d{4}";//폰번호 포맷
        String birthDayExp = "\\d{4}\\d{2}\\d{2}";//생일 포맷// infos[0] = nameif (!Pattern.matches(nameExp, infos[0])) {//패턴이 맞는지 확인하는 메소드
            msg1 = "이름에는 한글 또는 영어만 입력 가능합니다.\n";
        }
//infos[1] = ageif(infos[1].isEmpty()){
            msg2 ="";
        }
        else if(Integer.parseInt(infos[1]) > 200) {
            msg2 = "나이는 200살을 넘을 수 없습니다.\n";
        }
//infos[2] = birthDayif (!Pattern.matches(birthDayExp, infos[2])) {
            msg3 = "생일은 (ex.19980101)형식으로 입력해주세요.\n";
        }
//infos[3] = studentNum  / infos[4] = phoneNumif (!Pattern.matches(phoneExp, infos[4])) {
            msg5 = "전화번호는 (ex.010-1234-5678)형식으로 입력해주세요\n";
        }
        if (infos[0].trim().isEmpty() || (ageCheck == 1) || infos[1].trim().isEmpty() || infos[2].trim().isEmpty() || infos[3].trim().isEmpty() || infos[4].trim().isEmpty()) {
            msg6 = "\n!!!!!!!빈칸이 있습니다.!!!!!!!\n";
        }//공백이 하나라도 있으면 맨 아래에 빈칸있다고 알려줌if ((msg1 != "") || (msg2 != "") || (msg3 != "") || (msg4 != "") || (msg5 != "") || (msg6 != "")) {
            error = msg1 + msg2 + msg3 + msg4 + msg5 + msg6;//에러 뜬 부분은 위에서 msg1~6에 저장했음. error 변수에 다 합쳐줌return error;
        }
        else return "";
    }
}

2. Person 클래스

package addressManagement;

import java.util.regex.Pattern;

public class Person {
    private String name;
    private String age;
    private String birthDay;
    private String studentNum;
    private String phoneNum;

    public Person(String name, String age, String birthDay, String studentNum, String phoneNum) {
        this.name = name;
        this.age = age;
        this.birthDay = birthDay;
        this.studentNum = studentNum;
        this.phoneNum = phoneNum;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(String birthDay) {
        this.birthDay = birthDay;
    }

    public String getStudentNum() {
        return studentNum;
    }

    public void setStudentNum(String studentNum) {
        this.studentNum = studentNum;
    }

    public String getPhoneNum() {
        return phoneNum;
    }

    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }
}

3. PersonList 클래스

package addressManagement;

import java.io.*;
import java.util.Hashtable;
import java.util.Map;
import java.util.regex.Pattern;

public class PersonList {
    Map<String, Person> mainMap = new Hashtable<>();
    static String fname = "C:\\dev_java_spring\\MyProject\\data\\juso.txt";
    public void addPerson(Person person){
        mainMap.put(person.getName(), person);
    }
    public void deletePerson(String s){
        mainMap.remove(s);
    }

    public void setMainMap(Map<String, Person> mainMap) {
        this.mainMap = mainMap;
    }
    public int containsKeyCheck(String delete){
//키가 있으면 0, 빈칸이면 1, 키가없으면 2if(mainMap.containsKey(delete)){
            return 0;
        }else if(delete.trim().isEmpty()){
            return 1;
        }else return 2;

    }
    public void setTextFile() throws IOException {
        String data[][] = this.getDataArray();
        try(FileOutputStream fos = new FileOutputStream(fname,false)){
        }catch(IOException e){
            e.printStackTrace();
        }
        BufferedWriter bw = new BufferedWriter(new FileWriter(fname));
        for(int i=0;i<mainMap.size();i++){
            String s = data[i][0]+"\t"+data[i][1]+"\t"+data[i][2]+"\t"+data[i][3]+"\t"+data[i][4];
            bw.write(s);
            bw.newLine();
        }
        bw.close();
    }

    public Map<String, Person> getTextFile() throws IOException{
        Map<String, Person> map = new Hashtable<>();
        BufferedReader br = new BufferedReader((new FileReader(fname)));
        for(int i=0;;i++){
            if(!br.ready())break;
            else{
                String str = br.readLine();
                String[] personal = new String[5];
                personal = str.split("\t");
                Person person = new Person(personal[0],personal[1],personal[2],personal[3],personal[4]);
                map.put(personal[0],person);
            }
        }
        br.close();
        return map;
    }

    public String[][] getDataArray(){
        String data[][] = new String[50][5];
        int first = 0;
        for(String s : mainMap.keySet()){
            Person man = mainMap.get(s);
            for(int i=0;i<5;i++){
                data[first][0] = man.getName();
                data[first][1] = man.getAge();
                data[first][2] = man.getBirthDay();
                data[first][3] = man.getStudentNum();
                data[first][4] = man.getPhoneNum();
            }
            first++;
        }
        return data;
    }
}

4. Test 클래스

package addressManagement;
import java.io.IOException;
public class Test {
    public static void main(String[] args) throws IOException {
            new AddressGUI();

    }
}
profile
Exciting dev life / 댓글, 피드백, 질문 환영합니다 !!!

0개의 댓글