JAVA Day-14,15(AMS만들기)

AMS 만들기

우리는 Airplain Manager System(비행관리시스템)을 만들어 보면서 비행계획을 추가해보고 또 추가된 비행계획을 검색, 수정, 삭제를 할 것이다. 또한 목록 전체보기도 만들어 초기 비행관리시스템의 형태를 만들어 볼 것이다.

밑 그림그려보기

우리는 코드를 작성 전에는 무엇을 만들지 밑그림을 작성해보아야 코드를 작성하면서 목표를 이룰 수 있다.
우리가 만들고자 하는 것은 비행계획 추가하기, 검색, 수정, 삭제, 목록보기와 같이 5개의 옵션을 만들고 이 5가지의 옵션을 자세히 살표보면 다음과 같다.
1. 추가하기
추가하기를 누르면 문자열로 차례로 항공사, 항공기번호, 승객수, 출발지, 도착지를 작성하도록 한다. 작성이 끝나면 메뉴로 돌아간다.
2. 검색하기
항공기번호 또는 항공사, 각각의 추가한 옵션별로 검색이 되도록 한다.
3. 수정하기
항공기번호는 고유의 번호이니 항공기번호를 가지고 수정할 수 있도록한다. 수정은 출발지, 목적지 2개만 수정하게 하며 이는 현실에서 항공사, 항공기번호, 승객수는 항공기의 고유 특징으로 변경할 수 없다는 것을 반영한 것이다.
4. 삭제하기
마찬가지로 삭제하기는 항공기번호로 이루어지게 한다. 삭제하기를 누르면 삭제할 항공기번호를 누르고 삭제된 자리는 다음 항공기 배열이 덮어씌우는 방식으로 한다.
5. 목록보기
목록보기를 누르면 모든 비행계획을 볼 수 있도록 한다.
또한 상단에는 항공기, 항공기번호와 같이 비행 정보를 표기해준다.

생각해보기

먼저 초기화면에 추가하기~목록보기라는 옵션을 보여줘야 함으로 joption.Option을 사용하여 각 선택 옵션을 직관적으로 보여주게 할 것이다. 또한 옵션을 선택하면 각 옵션버튼은 정수인 0~옵션수 만큼을 리턴하니 이 숫자를 담아낼 공간을 만들고 이 숫자를 각각 switch문에 담아 각 옵션 버튼별 기능을 구현하면 될 것이다.
또한 이 기능들은 메소드를 따로 담고있는 클래스로 만들 것이다.
ams 패키지 안에 2개의 클래스로 만들어 하나는 메소드를 모아두는 필드, 하나는 기능을 실행하는 메인메소드부분으로 만들 것이다.
비행계획은 누적되어 입력 받아야되니 2차원 배열을 사용하는 것이 적합하겠다. 배열의 길이는 넉넉하게 [100][5]로 설정하면 부족하지는 않겠다.
우리는 입력을 하면 콤마로 구분되기에 split을 사용해야 할 것이다.
검색결과는 따로 저장공간을 만들어 보여주는 것이 좋겠다.
이제 코드를 작성해보록 하자

코드 작성하기

클래스는 2개의 클래스를 만들고 하나는 AmsMain, 다른 하나는 AmsField를 만들어 저장한다.
1. 우리가 원하는 옵션을 띄울때 필요한 것은 JOptionPane.showOptionDialog이다. 각 요소별로 들어가는 것은 링크 참고 JOptionPane 사용방법 보러가기
우리는 초기화면에서 움직이는 이미지를 보여주고 싶기때문에 비행기그림을 원하는 경로에 다운받아 저장하였다. 먼저 Image를 사용하기 위해 ImageIcon img = new ImageIcon()으로 초기화 하였고 괄호안에는 "경로/main.gif"를 적어두었다. 이제 이미지는 img로 사용 할 수 있다.
또한 옵션은 5개로 5개의 1차원배열로 만들어 사용하였다.
JOption은 숫자를 리텅함으로 그 숫자를 담기위해 저장공간을 만들었다.
옵션을 선택할 때마다 종료되므로 while로 감싸 반복시켰고 x버튼을 누르면 꺼지도록 if문을 만들고 switch문으로 숫자를 입력 받아 작동 할 수 있게 세팅하였다.

public static void main(String[] args) {
	ImageIcon img = new ImageIcon("src/img/main.gif");
	String [ ] mainMenu = {"추가하기", "검색하기", "수정하기", "삭제하기","목록보기"};
	int choice = 0;
		
	while(true) {
		choice = JOptionPane.showOptionDialog(null, "", "MyAMS", JOptionPane.DEFAULT_OPTION, 
			JOptionPane.PLAIN_MESSAGE, img, mainMenu, null);
		if(choice == -1) break;
		switch(choice) {
			case 0 : 
				break;
			case 1 :
				break;
			case 2 : 
				break;
			case 3 : 
				break;
			case 4 : 
				break;
			}
		}
      }
  1. Field 클래스로 들어가서 필요한 메소드를 만드는데 뼈대만 만들어보자 우리는 메소드를 활용할때 각 기능요소를 미리 생각해두었다.
    추가하기 ~ 목록보기까지 말이다. 그럼 void 타입으로 오류가 나지 않도록 하여 메소드를 미리 만들어보자
public class AmsField {
	//추가하기
	void insert() { }
	//검색하기
	void search() { }
	//수정하기
	void update() { }
	//삭제하기
	void delete() { }
	//목록보기
	void show() { }
  }
  1. Main클래스에서 case 0 에 Joption.input을 사용하여 비행계획을 입력하는 것을 작성한다. insertMsg를 별도로 만들어서 작성하면 된다.
    또한 이 값은 콤마로 구분되게 만들고 split을 하여 배열로 들어가게 한다. 들어가는 배열은 1차원 배열로 새로히 선언한다. 배열명은 arPlain이 좋겠다.
    다시 Field클래스로 돌아와 이번에는 1차원 배열을 축척하여 2차원배열에 저장하도록하자. 그러기 위해서는 2차원 배열을 선언하고 insert의 매개변수를 arPlain을 받아 arrPlain에 저장하면 되는데 cnt로 한번 접근하여 0에 최초 값을 담고 그다음 값을 담기위해 cnt ++ 증가를 한다. 이때 cnt도 별도로 선언한다. 작성이 완료되면 다시 main클래스로 돌아와 Field클래스의 메소드를 사용하기위해 클래스 초기화하고 메소드 사용을 넣으면 되는데 이때 매개변수를 우리가 넣은 arPlain으로 하면 되겠다.
main클래스 
AmsField af = new AmsField();
String insertMsg = "정보를 그대로 입력하세요[,콤마도 포함]\n 항공사, 항공기번호, 승객수, 출발지, 목적지";
String [] arPlain = new String [5];
		
while(true) {
	switch(choice) {
		case 0 : 
		arPlain = JOptionPane.showInputDialog(insertMsg).split(",");
				af.insert(arPlain);
				break;
Field 클래스
String [][] arrPlain = new String[100][5];
int cnt;
	
	//추가하기
	void insert(String[] arPlain) {
	arrPlain[cnt] = arPlain;
	cnt ++;
	}
  1. 추가하기를 만들어 보았으니 잘 나오는지 확인하기 위해서 목록보기를 만들어보자. 목록보기는 클릭이 이루어지면 result값이 나오면 되는데 그러기 위해서는 result값이라는 저장공간을 만들어주고 arrPlain을 result에 담아내기만 하면 끝이다.
    result에 arrPlain을 담아내기 위해서는 arrPlain을 i와 j만큼 반복시켜야되는데 이때 i는 위에서 추가하기 할때마다 증가된 만큼이니 cnt를 반복시키면 되고 j는 배열에 한번 접근하여 5번 반복되게 하면 된다.
    또한 result에는 마지막 콤마가 붙여지지 않게 하기위해서 삼항 연산자를 사용하여 콤마를 제외하게 하고 마지막 show메소드가 result를 return하도록 하여 결과를 내보내게 한다.
    또한 result의 첫번째 값으로는 이 후 값들이 어떤 값들인지 보여주기 위해서 메뉴이름을 적는다.
String result = "";

String show() {
	result = "항공사, 항공기번호, 승객수, 출발지, 목적지\n";
	for (int i = 0; i < cnt; i++) {
		for (int j = 0; j < arrPlain[0].length; j++) {
			result += j == arrPlain[0].length-1 ?  arrPlain[i][j]  : arrPlain[i][j]+",";
			}
		}
	if(cnt == 0 ) result = "목록없음";
	return result;
}
  1. main클래스에 돌아가서 case4에는 메시지로 출력하면 되는데 show메소드가 result를 return하니 그대로 메시지 출력에 걸면되겠다.
case 4 : 
JOptionPane.showMessageDialog(null, af.show());
break;
  1. 먼저 검색은 외부에서 값을 가져와 가져온 값과 우리가 입력한 값을 비교하여 목록으로 만드는 작업이 필요하다.
    field클래스로 돌아오자
    equals로 arrPain[i][1]과 비교하고 이 값이 참이 될때마다 result에 누적함수로 i를 누적시키고 또한 searchCnt가 증가되게 만들어 배열 길이로 사용한다.
    arIndex라는 배열을 새로 만들고 arIndex의 길이는 cnt가 증가한 만큼이 되고 이 길이만큼 for반복을 만들어 콤마기준은 split하여 arIndex[i]에 저장한다.
String search(String keyword) {
	String result = "";
	int searchCnt = 0;
	int [] arIndex;
	for (int i = 0; i < cnt; i++) {
		if(keyword.equals(arrPlain[i][1])) {
			searchCnt ++;
			result += ""+i+",";
		}
	}
	arIndex = new int[searchCnt];
	for (int i = 0; i < arIndex.length; i++) {
		arIndex[i] = Integer.parseInt(result.split(",")[i]);
	}
	
  1. 그리고 이 값을 목록에 리턴시켜야 되는데 우리는 배열을 새로 만들고 이 배열의 값에 따라 목록이 추가되는 모습을 그렸다.
    따라서 show메소드를 오버로딩하여 show가 배열을 매개변수로 받도록 하자 다른 점은 show의 i반복은 cnt가 아닌 arIndex의 길이만큼 반복시킨다는 것과 우리가 저장한 arIndex의 i들을 목록에 띄우기 위해서 arrPlain[arIndex[i]][j]를 작성한다.
String show(int [] arIndex) {
	String result = "항공사, 항공기번호, 승객수, 출발지, 목적지\n";
		for (int i = 0; i < arIndex.length; i++) {
			for (int j = 0; j < arrPlain[0].length; j++) {
				result += j == arrPlain[0].length-1 ?  arrPlain[arIndex[i]][j]  : arrPlain[arIndex[i]][j]+",";
				}
			result += "\n";
			}
	if(cnt == 0 ) result = "목록없음";
	return result;
}
  1. main 클래스로 돌아와서 keyword를 초기화하고 input을 사용하여 keyword를 받고 메시지로 search메소드를 사용하면 되겠다.
case 1 :
keyword = JOptionPane.showInputDialog("검색하실 항공기번호를 입력하세요");
JOptionPane.showMessageDialog(null, af.search(keyword));
break;
  1. 삭제하기를 먼저 작성해보자
    삭제하기는 실제 배열에서 우리가 그 배열을 제거할때는 앞 혹은 뒤의 값을 덮어씌우는 방식으로 작성한다. (알고리즘 특성) 이 방식을 활용하여 삭제하기를 만들어 보자. 먼저 삭제할 값을 찾아야되는데 이때 검색하기와 동일하게 외부 매개변수를 받고 equals를 사용하면 되겠다.
    이 값이 참이면 덮어씌우면 되겠다.
void delete(String keyword{
if(keyword.equals(arrPlain[i][1])) {
	arrPlain[i]=arrPlain[i+1];
}
}
  1. 이렇게 하면 i번째가 어딘지 모르니 추가하기 하여 생성된 배열만큼 반복시키자.
for (int i = 0; i < cnt; i++) {
if(keyword.equals(arrPlain[i][1])) {
	arrPlain[i]=arrPlain[i+1];
	}
}
  1. 이제 생성된 비행계획만큼 찾는 코드가 완성되었다. 그러나 우리가 i행을 i+1로 덮어씌우게 되면 기존 i+1에 기존 값이 남아있어 공간이 낭비되고 똑같은 값이 보이는 오류가 나온다. 따라서 cnt--; 하여 공간을 줄여줄 필요가 있겠다.
void delete(String keyword{
for (int i = 0; i < cnt; i++) {
if(keyword.equals(arrPlain[i][1])) {
	arrPlain[i]=arrPlain[i+1];
    	cnt--;
		}
	}
}
  1. 이제 값을 삭제하는 코드는 완성되었지만 삭제할 비행계획이 없다면 비행계획이 없다고 메시지를 보여줘야 한다. main메소드에서 메시지를 띄워야 하는데 if조건문을 사용하기 위해서도 플래그를 사용하는 것이 좋겠다.
boolean delete(String keyword) {
boolean deleteCheck = false;
for (int i = 0; i < cnt; i++) {
if(keyword.equals(arrPlain[i][1])) {
	deleteCheck = true;
	arrPlain[i]=arrPlain[i+1];
    	cnt--;
		}
	}
	return deleteCheck;
}
  1. deleteCheck를 만들어 return 시켜 불리언 타입으로 만들었으니 main 메소드에서 사용해보자. (case:3)
    먼저 외부 변수를 받는 keyword가 필요하겠다.
keyword = JOptionPane.showInputDialog("삭제하실 항공기번호를 입력하세요");
  1. 외부변수를 받고 이값이 참인지 거짓인지 알 수 있으니 if조건문에 넣자
keyword = JOptionPane.showInputDialog("삭제하실 항공기번호를 입력하세요");
if(af.delete(keyword)){
}
  1. 참 일때 show메소드를 통해 다시 목록을 보여주면 되고 거짓 즉, 삭제할 목록이 없을때 삭제할 목록이 없다고 표시해주자
keyword = JOptionPane.showInputDialog("삭제하실 항공기번호를 입력하세요");
if(af.delete(keyword)){
	JOptionPane.showMessageDialog(null, af.show());
}else{
	JOptionPane.showMessageDialog(null, "삭제하실 목록이 없습니다.");
}
  1. 수정하기는 먼저 수정하고자 하는 행을 찾고 다음 수정하고 싶은 열에 접근하여 수정하면 되겠다. 수정하고자 하는 행에 접근하기 위해서는 검색메소드를 활용하자 검색메소드에 검색된 i를 가져오면 되겠다.
arrPlain[검색된 i][수정할 열] = 새로운 값;
  1. 검색된 i를 가져오기 위해서 먼저 main 메소드를 입력하자
    keyword를 동일하게 입력받고 이 keyword를 search메소드로 넘겨주자 그러면 search메소드에서 값을 찾게 될 것이고 이 찾을 값을 담아낼 변수를 만들자. 넘겨준 search메소드에서 값을 못찾으면 실패 메세지를 띄우자.
main
keyword = JOptionPane.showInputDialog("수정하실 항공기번호를 입력하세요");
	if(af.search(keyword).equals("목록없음")) {
	JOptionPane.showMessageDialog(null, "수정하실 비행계획이 없습니다.");
	}else {
					
}
Field
int btnIndex = 0;
search 메서드에 추가 
for (int i = 0; i < cnt; i++) {
	if(keyword.equals(arrPlain[i][1])) {
		**btnIndex = i;**
		searchCnt ++;
		result += ""+i+",";
  1. btnIndex에 검색된 i를 담아냈으니 이것을 가져오자
void update() {
	arrPlain[btnIndex][수정하고자 하는 열] = 새로운 값;
}
  1. update에 수정하고자 하는 열과 새로운 값을 위해 main메소드를 작성하자 index는 목적지, 출발지 중 선택하기로 만들자
    newValue는 input으로 가져 오면 되겠다. 또한 입력값이 없을때 continue하고 update에 변수를 넣어주자
String [] update = {"출발지 수정", "목적지 수정"}; 
String newValue = "";
..생략..
else {
	index = JOptionPane.showOptionDialog(null, "", "수정하기", JOptionPane.DEFAULT_OPTION, 
						JOptionPane.PLAIN_MESSAGE, img, update, null);
	newValue = JOptionPane.showInputDialog("수정하시는 값을 입력하세요");
	if(newValue.length() <= 0) continue;
			af.update(index, newValue);
			JOptionPane.showMessageDialog(null, "수정완료");
	}
  1. 이제 외부 변수를 가져왔으니 Field에 넣어보자
void update(int index, String newValue) {
	arrPlain[btnIndex][index+3] = newValue;
}
  1. 지금까지 작성한 코드는 다음과 같다.
field
package ams;

public class AmsField {
	String [][] arrPlain = new String[100][5];
	int cnt;
	String result = "";
	int btnIndex;
	//추가하기
	void insert(String[] arPlain) {
	arrPlain[cnt] = arPlain;
	cnt ++;
	}
	
	//검색하기
	String search(String keyword) {
		String result = "";
		int searchCnt = 0;
		int [] arIndex;
		for (int i = 0; i < cnt; i++) {
			if(keyword.equals(arrPlain[i][1])) {
				btnIndex = i;
				searchCnt ++;
				result += ""+i+",";
			}
		}
		arIndex = new int[searchCnt];
		for (int i = 0; i < arIndex.length; i++) {
			arIndex[i] = Integer.parseInt(result.split(",")[i]);
		}
		return show(arIndex);
	}
	
	
	//수정하기
	void update(int index, String newValue) {
		arrPlain[btnIndex][index+3] = newValue;
	}
	
	//삭제하기
	boolean delete(String keyword) {
		boolean deleteCheck = false;
		for (int i = 0; i < cnt; i++) {
			if(keyword.equals(arrPlain[i][1])) {
				deleteCheck = true;
				arrPlain[i]=arrPlain[i+1];
				cnt--;
			}
		}
		return deleteCheck;
	}
	
	//목록보기
	String show() {
		String result = "항공사, 항공기번호, 승객수, 출발지, 목적지\n";
		
			for (int i = 0; i < cnt; i++) {
				for (int j = 0; j < arrPlain[0].length; j++) {
					result += j == arrPlain[0].length-1 ?  arrPlain[i][j]  : arrPlain[i][j]+",";
				}
				result += "\n";
		}
		if(cnt == 0 ) result = "목록없음";	
		return result;
	}
	
	String show(int [] arIndex) {
		String result = "항공사, 항공기번호, 승객수, 출발지, 목적지\n";
			for (int i = 0; i < arIndex.length; i++) {
				for (int j = 0; j < arrPlain[0].length; j++) {
					result += j == arrPlain[0].length-1 ?  arrPlain[arIndex[i]][j]  : arrPlain[arIndex[i]][j]+",";
				}
				result += "\n";
			}
		if(cnt == 0 ) result = "목록없음";
		return result;
	}


}

main
package ams;


import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

public class AmsMain {
	public static void main(String[] args) {
		AmsField af = new AmsField();
		ImageIcon img = new ImageIcon("src/img/main.gif");
		String [ ] mainMenu = {"추가하기", "검색하기", "수정하기", "삭제하기","목록보기"};
		int choice = 0;
		String insertMsg = "정보를 그대로 입력하세요[,콤마도 포함]\n 항공사, 항공기번호, 승객수, 출발지, 목적지";
		String [] arPlain = new String [5];
		String keyword = "";
		int index = 0;
		String [] update = {"출발지 수정", "목적지 수정"}; 
		//String updateMsg = "수정을 원하시는 것을 선택하세요.";
		String newValue = "";
		
		while(true) {
			choice = JOptionPane.showOptionDialog(null, "", "MyAMS", JOptionPane.DEFAULT_OPTION, 
								JOptionPane.PLAIN_MESSAGE, img, mainMenu, null);
			if(choice == -1) break;
			switch(choice) {
			case 0 : 
				arPlain = JOptionPane.showInputDialog(insertMsg).split(",");
				af.insert(arPlain);
				break;
			case 1 :
				keyword = JOptionPane.showInputDialog("검색하실 항공기번호를 입력하세요");
				JOptionPane.showMessageDialog(null, af.search(keyword));
				break;
			case 2 : 
				keyword = JOptionPane.showInputDialog("수정하실 항공기번호를 입력하세요");
				if(af.search(keyword).equals("목록없음")) {
					JOptionPane.showMessageDialog(null, "수정하실 비행계획이 없습니다.");
				}else {
					index = JOptionPane.showOptionDialog(null, "", "수정하기", JOptionPane.DEFAULT_OPTION, 
								JOptionPane.PLAIN_MESSAGE, img, update, null);
					newValue = JOptionPane.showInputDialog("수정하시는 값을 입력하세요");
					if(newValue.length() <= 0) continue;
					af.update(index, newValue);
					JOptionPane.showMessageDialog(null, "수정완료");
					}
				break;
			case 3 : 
				keyword = JOptionPane.showInputDialog("삭제하실 항공기번호를 입력하세요");
				if(af.delete(keyword)) {
					JOptionPane.showMessageDialog(null, af.show());
				}else {
					JOptionPane.showMessageDialog(null, "삭제하실 목록이 없습니다.");
				}
				break;
			case 4 : 
				JOptionPane.showMessageDialog(null, af.show());
				break;
			}
			
		}
	}
}

좋은 웹페이지 즐겨찾기