미완성본 전화번호부 프로그램에서 검색, 도움말만 제외한 모든 기능 구현
[ 작업일지 ]
1. 코드가 길어지고 복잡해 짐에 따라 코드 정리를 실행했음(종류별, 작업별로)
2. 설계 문제가 발생하여 설계 수정(공통 데이터 관리 클래스를 따로 작성함)
3. 처음 설계에 문제가 많아서 기능 추가에 어려움이 있었음(세분화 시켜 문제해결)
[ 내 용 ]
1. PhoneData 클래스 : 전화번호부에 대한 기초적인 데이터 수집에 틀 제공
2. CommonData 클래스 : 파일경로 및 파일로 부터 읽어 들인 텍스트 내용 저장 클래스
3. MainScreen 클래스 : 메인 화면 구성 및 이벤트 소스 작성
4. FileListener 클래스 : 메뉴창의 파일 항목에 대한 이벤트 처리 작성
5. EditListener 클래스 : 메뉴창의 편집 항목에 대한 이벤트 처리 작성
[ 자료구조 ]
저장되는 파일의 자료 구조는 문자열로 처리 했으며 단위 구분은 "^"문자를 중간에 삽입하여 처리하였으며, 단락 구분은 줄 바꿈으로 처리 하였습니다. 파일의 내용을 읽어서 처리 할 경우에는 한 문장씩 데이터를 읽어 들여 파싱("^")을 통해 처리하였습니다.
[ 소스 코드 ]
1. PhoneData 클래스
/**
* subject : 전화번호부 관리 프로그램(전화번호 데이터 클래스)
* 작성일 : 2009.01.31 ~ 2009.02.01
* 기본적인 전화번호부 데이터 관리 클래스
*/
import java.io.*;
public class PhoneData {
private String index;
private String name;
private String phone_num;
private String address;
/* 데이터 속성 setting and getting 메소드 구현 */
public String getIndex() { return index; }
public void setIndex(String index) { this.index = index; }
public void setName(String n) { name = n; }
public String getName(){ return name; }
public void setPhone_num(String t){ phone_num = t; }
public String getPhone_num() { return phone_num; }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
/** @ 여기로 전달되는 PhoneData 클래스는 trim()이 완료된 상태로 전달되야함 */
public void writeData(PhoneData data, CommonData com){
try {
CommonData comm = com;
BufferedWriter out = new BufferedWriter(new FileWriter(comm.FILEPATH, true));
String str = index+"^"+"^"+name+"^"+phone_num+"^"+address+"\n";
out.write(str);
out.close(); // 파일 close() 메소드를 사용안하여 파일에 입력이 안되었었음.
}catch(Exception e){
e.printStackTrace();
}
}
}
2. CommonData 클래스
* subject : 전화번호부 관리 프로그램(공통 데이터 클래스)
* 작성일 : 2009.02.01 ~ 2009.02.01
* 파일 경로, 파일로 부터 읽은 텍스트 자료를 통합하여 관리
*/
package co.kim;
public class CommonData {
public static String TEXT;
private static CommonData instance;
private CommonData(){
FILEPATH = null;
TEXT = null;
}
public static CommonData getInstance(){
if ( instance == null ){ return instance = new CommonData(); }
return instance;
}
}
3. MainScreen 클래스
/**
* subject : 전화번호부 관리 프로그램(Main화면 클래스)
* 작 성 일 : 2009.01.31 ~ 2009.02.01
* 이벤트 소스와 프레임의 구성만 담당하는 Main 화면 구성 클래스
* 이벤트 수행은 메뉴항목에 따라 구현하는 클래스는 개별적으로 구현
*/
package co.kim;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MainScreen extends Frame {
CommonData com = CommonData.getInstance();
Frame parent; /* 이벤트 리스너에게 전달하기 위한 프레임 변수 */
/* 메뉴바를 구성하는 변수 */
MenuBar menubar;
Menu file, edit, help;
MenuItem file_new, file_open, file_save, file_save_as, file_exit;
MenuItem edit_input;
/* 검색 패널를 구성하는 변수 */
Panel top_panel;
JButton whole_b, con_b; // 전체 검색버튼, 조건 검색 버튼
JLabel label_n;
JTextField name_text;
/* 테이블을 구성하는 변수 */
JTable table;
String colnames[]={ "이름","전화번호", "주소"};
/* 테스트용 TextArea(로직 구성이 끝나면 테이블로 대체) */
TextArea text_a = new TextArea();
/**
* 메소드 : 생성자
*/
public MainScreen() {
parent = new Frame("전화번호부");
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent evt){
dispose();
System.exit(0);
}
});
/* @ 프레임의 사이즈, 레이아웃 */
setBounds(10,10,500,300);
setLayout(new BorderLayout());
menubar = new MenuBar(); // 메뉴바 생성
setMenuBar(menubar); // Frame에 메뉴바를 추가
/* @ file 메뉴에 대한 정의 */
file = new Menu("파일");
file_new = new MenuItem("새 전화번호부");
file_open = new MenuItem("파일 열기");
file_save = new MenuItem("저장");
file_save_as = new MenuItem("다른이름으로 저장");
file_exit = new MenuItem("종료");
file_new.addActionListener(new FileListener(parent, text_a, com));
MenuShortcut N = new MenuShortcut(KeyEvent.VK_N, false);
file_new.setShortcut(N);
file_open.addActionListener(new FileListener(parent, text_a, com));
MenuShortcut O = new MenuShortcut(KeyEvent.VK_O);
file_open.setShortcut(O);
file_save.addActionListener(new FileListener(parent, text_a, com));
MenuShortcut S = new MenuShortcut(KeyEvent.VK_S);
file_save.setShortcut(S);
file_save_as.addActionListener(new FileListener(parent, text_a, com));
file_exit.addActionListener(new FileListener(parent, text_a, com));
MenuShortcut X = new MenuShortcut(KeyEvent.VK_X);
file_exit.setShortcut(X);
file.add(file_new);
file.addSeparator();
file.add(file_open);
file.add(file_save);
file.add(file_save_as);
file.addSeparator();
file.add(file_exit);
menubar.add(file);
/* @ edit 메뉴에 대한 정의 */
edit = new Menu("편집");
edit_input = new MenuItem("자료입력");
edit_input.addActionListener(new EditListener(parent, text_a, com));
edit.add(edit_input);
menubar.add(edit);
/* @ help 메뉴에 대한 정의 */
help = new Menu("도움말");
menubar.add(help);
/* @ Top 검색 패널 구성 */
top_panel = new Panel();
top_panel.setLayout(new FlowLayout());
whole_b = new JButton("전체검색");
con_b = new JButton("이름 검색");
label_n = new JLabel(" 이 름 ");
name_text = new JTextField(12);
top_panel.add(whole_b);
top_panel.add(label_n);
top_panel.add(name_text);
top_panel.add(con_b);
top_panel.setBackground(Color.gray);
add("North",top_panel);
/* @ 테스트용 TextArea 구성*/
add(text_a);
setVisible(true);
}
public static void main(String[] args) {
new MainScreen();
}
}
4. FileListener 클래스
* subject : 전화번호부 관리 프로그램(파일 입출력 클래스)
* 작성일 : 2009.01.31 ~ 2009.02.01
* 전화번호부의 파일메뉴에 대한 이벤트를 수행하는 메소드들을 구현함
*/
package co.kim;
import java.awt.FileDialog;
import java.awt.event.*;
import java.io.*;
import java.util.StringTokenizer;
import java.util.Vector;
import java.awt.*;
public class FileListener implements ActionListener {
Frame parent;
TextArea text_a;
CommonData com;
int count;
/** @ 생성자 */
public FileListener(Frame f, TextArea t, CommonData com){
parent = f;
text_a = t;
this.com = com;
}
/** @ 파일 열기에 대해 구현 */
public void openFile(){
FileDialog file = new FileDialog(parent, "파일열기", FileDialog.LOAD);
file.show();
String path = file.getDirectory();
String fileName = file.getFile();
com.FILEPATH = path+fileName;
/* 파일이 존재하지 않는 경우 처리 방법 */
if( file.getFile() == null ){
System.out.println("clean");
System.out.println("not find the File");
}
refresh();
}
/** @ 파일의 내용을 읽어 메인 TextArea에 내용을 표시 */
public void refresh(){
try {
BufferedReader in = new BufferedReader(new FileReader(com.FILEPATH));
String text;
while(in.ready()) {
text = in.readLine();
com.TEXT += text; // 전체 텍스트를 얻기 위한 방법
StringTokenizer st = new StringTokenizer(text, "^");
while(st.hasMoreTokens()){ text_a.append(st.nextToken()+" "); }
text_a.append("\n");
}
in.close(); // 입력 스트림을 꼭 닫아야 함
}catch (Exception e){ e.printStackTrace(); }
}
/** @ 일반 저장에 대한 처리*/
public void saveFile() {
try {
BufferedWriter out = new BufferedWriter(new FileWriter(com.FILEPATH, true));
out.write(com.TEXT);
out.close(); // 파일 close() 메소드를 사용안하여 파일에 입력이 안되었었음.
}catch(Exception e){
e.printStackTrace();
}
}
/** @ 파일저장(다른 이름으로)에 대한 처리 */
public void saveAsFile() {
FileDialog file = new FileDialog(parent, "저장하기", FileDialog.SAVE);
file.show();
String path = file.getDirectory();
String fileName = file.getFile();
try {
BufferedWriter out = new BufferedWriter(new FileWriter(path + fileName));
out.write(com.TEXT, 0, com.TEXT.length());
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void actionPerformed(ActionEvent evt) {
// TODO Auto-generated method stub
String cmd = evt.getActionCommand();
if( cmd.equals("파일 열기") ){
openFile();
}else if( cmd.equals("저장")){
saveFile();
}else if( cmd.equals("다른이름으로 저장")){
saveAsFile();
}else if (cmd.equals("종료")){
parent.dispose();
System.exit(0);
}
}
}
5. EditListener 클래스
/**
* subject : 전화번호부 관리 프로그램(데이터 편집 클래스)
* 작성일 : 2009.01.31 ~ 2009.02.01
* 전화번호부의 편집 메뉴에 대한 이벤트를 수행하는 메소드들을 구현함
*/
package co.kim;
import java.awt.Button;
import java.awt.Dialog;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.TextField;
import java.awt.Event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.*;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.StringTokenizer;
import javax.swing.BoxLayout;
public class EditListener implements ActionListener {
Frame parent;
TextArea text_a;
CommonData com;
Dialog dialog;
Panel panel_1, panel_add, panel_b, panel_l;
PhoneData data;
TextField index_num, name_field, tel_field, address;
Label label;
/** @ 생성자(메인화면 프레임, 데이터표시 영역, 일반 데이터) */
public EditListener(Frame f, TextArea t, CommonData com) {
parent = f;
text_a = t;
this.com = com;
}
/** @ 다이어로그 창 구성 */
public void inputDialog() {
dialog = new Dialog(parent, "자료를 입력하세요");
dialog.show();
dialog.setBounds(10,10,260,180);
dialog.setLayout(new FlowLayout());
dialog.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent evt){
dialog.dispose();
dialog.setVisible(false);
}
});
/* 패널 구성 */
panel_1 = new Panel();
panel_1.setLayout(new GridLayout(3,2,4,2));
panel_add = new Panel();
panel_add.setLayout(new GridLayout(1,2,4,2));
panel_b = new Panel();
panel_b.setLayout(new GridLayout(1,2,4,2));
panel_l = new Panel();
Button enter, done;
/* 자료입력 컴포넌트 구성 */
panel_1.add(new Label("순 번"));
index_num = new TextField(12);
panel_1.add(index_num);
panel_1.add(new Label("이 름"));
name_field = new TextField(12);
panel_1.add(name_field);
panel_1.add(new Label("전화번호"));
tel_field = new TextField(12);
panel_1.add(tel_field);
panel_add.add(new Label("주 소"));
address = new TextField(12);
panel_add.add(address);
label = new Label("데이터를 입력하세요");
panel_l.add(label);
/* 메뉴 편집 -> 자료 입력 Dialog창에 입력 버튼 클릭시 처리 (내부 클래스로 구현)*/
enter = new Button("입력");
enter.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt) {
// TODO Auto-generated method stub
int result = addData();
}
});
enter.setActionCommand("add");
panel_b.add(enter);
/* 메뉴 편집 -> 자료입력 Dialog에서 완료 버튼이 클릭시 처리 */
done = new Button("완료");
done.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt) {
// TODO Auto-generated method stub
dialog.dispose();
}
});
panel_b.add(done);
/* 다이어로그에 패널 추가 */
dialog.add(panel_1);
dialog.add(panel_add);
dialog.add(panel_l);
dialog.add(panel_b);
}
/**
* 새로운 데이터를 입력받아 PhoneData 객체속성에 설정한 후 PhoneData 클래스의 writeData()메소드 실행
* 순번, 이름, 전화번호, 주소를 입력받아서 처리(미 입력 데이터가 있을 시 처리 보류와 함께 메세지 출력)
* [주 의] 파일을 열은 상태에서만 입력이 가능함
*/
public int addData(){
data = new PhoneData();
int result = 0; // 정상 처리시 값
String index = null;
String name = null;
String tel = null;
String addr = null;
String result_st = "";
try {
index = index_num.getText();
name = name_field.getText();
tel = tel_field.getText();
addr = address.getText();
if( index == null || index.equals("")){
result_st ="순번을 입력하세요";
result = -1;
}else if( name == null ){
result_st ="이름을 입력하세요";
result = -1;
}else if( tel == null ){
result_st ="전화번호를 입력하세요";
result = -1;
}else if( addr == null ){
result_st ="주소를 입력하세요";
result = -1;
}
if ( result == 0 ){
data.setIndex(index.trim());
data.setName(name.trim());
data.setPhone_num(tel.trim());
data.setAddress(addr);
data.writeData(data, com);
refresh();
}else {
label.setText(result_st);
return result;
}
}catch(Exception e){
e.printStackTrace();
}
return result;
}
/** @ 화면 갱신을 위한 방법 구현 */
public void refresh(){
String text;
text_a.setText(""); // TextArea 화면 초기화
try {
BufferedReader in = new BufferedReader(new FileReader(com.FILEPATH));
while(in.ready()) {
text = in.readLine();
StringTokenizer st = new StringTokenizer(text, "^");
while(st.hasMoreTokens()){
text_a.append(st.nextToken()+" ");
}
text_a.append("\n");
}
in.close(); // 입력 스트림을 꼭 닫아야 함
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void actionPerformed(ActionEvent evt) {
// TODO Auto-generated method stub
String com = evt.getActionCommand();
inputDialog();
}
}
[ 결 과 ]
<전체 화면>
< 메뉴 화면 >
< 데이터 입력창 화면 >
'자바(Java) > JAVA 2SE' 카테고리의 다른 글
Telnet 프로그램 (0) | 2009.02.03 |
---|---|
java.util.Timer - 쓰레드 타이머 (0) | 2009.02.01 |
메모장 프로그램 (0) | 2009.01.27 |
java.net.InetAddress - IP주소 (0) | 2009.01.23 |
java.lang.reflect 패키지 - 클래스와 객체의 정보 취득 (0) | 2009.01.22 |