TIL #8 - 게시판 프로그램
게시판 프로그램이다.
게시판이 여태까지 배운 것들의 총망라이므로 한 번 스스로 만들어보면 아주 큰 공부가 될 것 같다.
만들 클래스는 아래와 같다.
1) 구조체 클래스
- Board.java
- Member.java
- Reply.java
2) 각 구조체에 따른 메소드 클래스
- BoardUtil.java
- MemberUtil.java
- ReplyUtil.java
- MyArray.java
- MyScanner.java
3) BoardReplyWrapper.java : Board[] 와 Reply[]를 같이 묶은 클래스
4) 메인 메소드를 넣을 클래스
- BoardEx.java
(큰 기능이 있는 클래스는 아니지만 프로그램 실행을 하려면 메인 메소드가 필요하므로
메인 메소드를 따로 줄 클래스를 만든다.)
게시글 기능
1) 회원 관련 기능
- 로그인
- 회원가입
(단, 중복된 아이디 사용 불가능)
2) 게시판 관련 기능
- 글 목록 보기
- 새로 작성하기
- 글 수정
- 글 삭제
- 글 개별로 보기
(단, 글의 수정과 삭제의 경우 글쓴이와 사용자가 일치할 경우 가능)
3) 댓글 관련 기능
- 댓글 입력
- 댓글 수정
- 댓글 삭제
- 댓글 갯수 확인
(단, 사용자가 글쓴이와 다른 회원일 경우에 댓글 기능 이용 가능)
먼저 구조체를 만들어 본다.
Member.java
회원 정보에 관한 구조체이다.
package boardProject;
/*
* 회원정보
*/
public class Member {
// 회원번호, 유저네임, 비밀번호, 닉네임
public int id;
public String userName;
public String password;
public String nickName;
}
회원정보는 회원번호(1부터 시작하는 인덱스 번호), 유저네임(아이디), 비밀번호, 닉네임 으로 이루어진다.
Board.java
게시글 정보에 관한 구조체이다
package boardProject;
/*
* 게시글 구조체
* 글번호, 제목, 내용, 작성자 회원번호, 입력날짜
*/
public class Board {
public int id; // 글번호
public String title; // 글제목
public String content; // 글 내용
public int writerId; // 작성자 회원번호
public String writtenDate; // 입력날짜
}
1부터 시작하는 인덱스 번호인 글번호, 글제목, 글 내용, 작성자 회원번호, 입력날짜(현재 날짜 자동입력) 으로 이루어진다.
Reply.java
댓글 정보에 관한 구조체이다.
package boardProject;
/*
* 댓글 데이터 구조체
*/
public class Reply {
public int id; // 댓글 번호
public int boardId; // 글 번호
public int memberId; // 회원번호
public String content; // 댓글 내용
}
1부터 시작하는 인덱스 번호인 댓글번호, 해당 댓글이 입력될 글 번호, 회원번호, 댓글내용으로 이루어진다.
후에 Board[]와 Reply[]가 같이 쓰일 일이 있기 때문에 포장클래스인 BoardReplyWrapper.java 를 만든다.
package boardProject;
/*
* Board과 Reply 배열을 합침
*/
public class BoardReplyWrapper {
// 이 클래스는 말 그대로 포장 클래스
// 예시 : 이마트 샴푸 린스 같이 든 플라스틱 박스
Board[] boardArr;
Reply[] replyArr;
}
다음은 각 클래스에 대한 메소드를 만들어본다.
MyArray.java
배열을 다양하게 컨트롤하기 위한 메소드들이 있는 클래스이다.
우리가 다룰 배열은 구조체에 따라 각각 Board[], Member[], Reply[] 이다.
해당 배열에 대해 만들 메소드는
배열을 늘리는 expand()
배열에 요소를 추가하는 add()
배열에 인덱스를 찾아주는 indexOf()
배열 칸 하나를 제거해주는 remove()
이다.
메소드들은 리턴 값들만 해당 배열들로 잘 바꿔주면 되기 때문에 board에 대한 메소드만 다루도록 한다.
배열을 늘리는 expand()
private static Board[] expand(Board[] arr) {
Board[] temp = new Board[arr.length];
for (int i = 0; i < arr.length; i++) {
temp[i] = arr[i];
}
arr = new Board[temp.length + 1];
for (int i = 0; i < temp.length; i++) {
arr[i] = temp[i];
}
return arr;
}
expand()는 뒤에서 볼 add()에서만 사용할 것이기 때문에 접근제어자를 private으로 설정한다.
Board[] 배열을 return 해야하기 때문에 return 타입은 Board[] 이다.
(이를 Member[], Reply[]로 상황따라 바꾸면 되는 것이다)
배열을 늘리는 경우에는 배열의 요소, 인덱스값을 모두 복사를 해야하기 때문에
데이터의 손실을 방지하기 위해서 임시 저장소 temp를 만들어 먼저 늘리고자 하는 배열 arr의 정보를 temp에 넣는다.
arr의 길이를 먼저 넣고,
이후 temp 배열의 길이를 늘린 후
temp 배열의 길이만큼 for문을 돌리며 늘린 배열 temp의 값을 arr에 넣고 arr를 return 한다.
배열 요소를 추가하는 add()
public static Board[] add(Board[] arr, Board element) {
int index = arr.length;
arr = expand(arr);
arr[index] = element;
return arr;
}
add 메소드는 간단하다.
index 변수에 배열의 길이 값을 넣은 후
앞서 만든 expand 메소드로 배열을 늘린다.
배열의 길이는 배열의 크기-1 이기 때문에 바뀌기 전의 배열 길이가 늘린 배열의 크기가 된다.
그러므로 expand를 적용시키기 전의 배열 길이를 넣은 index번째 배열에 추가할 요소 element를 넣는다.
배열을 하나 제거해주는 remove()
public static Board[] remove(Board[] arr, Board element) {
int index = indexOf(arr, element);
if (index != -1) {
Board[] front = new Board[index];
for (int i = 0; i < front.length; i++) {
front[i] = arr[i];
}
Board[] back = new Board[arr.length - front.length - 1];
int backIndex = 0;
for (int i = index + 1; i < arr.length; i++) {
back[backIndex] = arr[i];
backIndex++;
}
arr = new Board[front.length + back.length];
for (int i = 0; i < front.length; i++) {
arr[i] = front[i];
}
backIndex = front.length;
for (int i = 0; i < back.length; i++) {
arr[backIndex] = back[i];
backIndex++;
}
}
return arr;
}
배열을 제거하는 것은 조금 복잡하다.
먼저 indexOf 메소드로 제거할 배열 인덱스를 찾아내 index 변수에 넣는다.
그런 후 index가 -1이 아닌 상태에서 (배열이 제대로 존재하면 : 인덱스가 -1인 배열은 존재하지 않기 때문)
front와 back으로 나눈다.
front와 back은 제거할 배열 index를 기준으로 앞, 뒤 인데
앞과 뒤를 따로 분리시킨 후 index를 제거하여 후에 합치는 식으로 배열을 제거한다.
먼저 front 배열을 만든다.
front 배열은 index 만큼의 크기를 가진다.
그리고 0부터 front.length 만큼 front[]에 arr값을 넣는다.
이로써 front배열에 대한 작업은 끝이다.
문제는 back 배열이다.
back배열의 크기는 전체 배열의 길이 arr.length - front.length -1 이다.
왜냐하면 front 배열을 크기를 index로 했기 때문에 front.length에는 index도 포함되어 있다.
그렇기 때문에 index를 제외시키기 위해서 -1을 해준다.
그럼 애초에 front배열을 만들 때 index-1을 해주면 되지 않냐고 할 수 있지만
index-1이면 자칫 index가 -1와 같이 음수가 될 수도 있기 때문에 index에 직접적으로 -1을 해주지 않는다.
그런 후 backIndex를 0으로 초기화 시킨다.
backIndex는 Index+1부터 시작되기 때문에 0으로 시작하지 않는 상태이다.
하지만 우리는 0에서부터 값을 넣어야한다.
그런 후 for문을 돌리는데 i값을 index +1부터 시작해 arr.length 만큼 진행한다.
우리는 back을 위한 위치를 따로 만들어서 0에서 1씩 증가시키며 위치를 직접 지정해줘야한다.
그렇기 때문에 backIndex를 0으로 초기화시키는 것이다.
backIndex를 0으로 초기화시키지 않았을 때는 후에 앞 뒤 배열을 합쳐서 배열 요소를 넣을 때 문제가 생긴다.
예시를 보자.
새로운 for문을 만든다.
for(int i = 0; i < arr.length; i++)
이 for문 안에서 arr[i] 번째에 차례대로 front와 back 배열값들을 넣는다.
arr[i] = front[i]는 문제가 없지만
arr[i] = back[i]에서 문제가 생긴다.
만약, front의 길이가 3이고 back의 길이가 2라면 i는 총 5번 반복된다.
그럼 for문을 통해서 차례대로 i가 0일 때 부터 값을 넣는 상황을 생각해보자.
i가 0일때부터 쭉쭉 ++i되어서 점차 나아가다가 i가 3일때 문제가 발생한다.
front길이가 3이면 인덱스는 0부터 2까지 존재하기 때문이다.
그렇다면 if문을 써서 front의 길이까지만 갈 수 있도록 조건을 건다.
하지만, arr[i] = back[i]에서 다시 문제가 생긴다.
역시 3일 때 문제가 생긴다.
문제는 back에는 index 3이 없다는 것이다.
back은 길이가 2이기 때문에 0에서 1까지만 있어서 index 3이 들어갈 자리가 없다.
그렇기 때문에 backIndex를 통해서 back의 인덱스를 우리가 직접 컨트롤 해야한다는 것이다.
front와 back의 배열을 다 만들었다면
arr의 배열 값을 각 배열에 복사해 넣는다.
front는 그대로 진행하면 되고
back의 경우에는 backIndex를 0으로 초기화 시켰기 때문에 i가 0부터 시작하게 된다.
하지만 이미 front가 0부터의 값들을 차지하고 있기 때문에 거기에 back 배열의 요소들이 들어가면 front의 요소들이 지워지게 된다.
그렇기 때문에 이번엔 backIndex를 0이 아닌 다른 것으로 초기화 해야한다.
바로 front.length 이다.
배열의 마지막 index는 배열의 크기 -1 이기 때문에 front의 마지막 index는 front.length-1 이기 때문이다.
front의 요소들은 사실 상 front.length-1에서 끝나게 되기 때문에
처음으로 back배열에 요소를 집어넣을 위치는 front.length-1의 다음 값인 front.length가 된다.
이로써 배열 컨트롤에 대한 메소드는 끝이다.
다음은 직접적으로 각 구조체에 대한 메소드들이다.
먼저 Board에 대한 메소드의 모임 BoardUtil.java이다.
BoardUtil.java
이곳에서는 게시글에 대한 메소드들이 모여있다.
글 번호, 제목, 작성자, 작성일, 댓글수를 한 줄에 보여주는 list()
public static void list(BoardReplyWrapper wrapper, Member[] memberArr) {
for (int i = wrapper.boardArr.length - 1; i >= 0; i--) {
Board b = wrapper.boardArr[i];
// 댓글 갯수 세기
int count = ReplyUtil.countReply(b.id, wrapper.replyArr);
String message = b.id + " " + b.title + " ";
if(count != 0) {
message += "[" + count + "]";
}
message += MemberUtil.showNickName(memberArr, b.writerId) + " " + b.writtenDate;
System.out.println(message);
}
}
우리가 게시판에서 글을 쓰면 최신글이 가장 위로 올라오는 것을 볼 수 있다.
가장 오래된 것일 수록 리스트의 제일 밑에 있다.
그렇기 때문에 가장 나중에 쓰인 것이 배열의 0 인덱스에 가까워야하기 때문에 배열을 거꾸로 나열하는 for문을 만든다.
게시글을 쓰는 write()
public static Board[] write(Board[] boardArr, Scanner scan, Member member) {
Board b = new Board();
b.id = 1;
if (boardArr.length != 0) {
b.id = boardArr[boardArr.length - 1].id + 1;
}
System.out.print("제목 : ");
b.title = scan.nextLine();
System.out.print("글 내용 : ");
b.content = scan.nextLine();
b.writerId = member.id;
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy년 MM월 dd일 hh시 mm분 ss초");
b.writtenDate = sdf.format(c.getTime());
boardArr = MyArray.add(boardArr, b);
return boardArr;
}
boardArr는 게시글이 얼마나 쓰일 지 모르기 때문에, 즉 유동적인 길이를 가졌기 떄문에
boardArr의 길이가 0이 아니면, 가장 마지막 요소를 찾아서 그 요소 번호 id 번호를 가지고 올 수 있다.
배열의 가장 마지막 요소의 index는 length-1이다.
그럼 해당 위치에 있는 board 구조체의 id+1 한 값이 우리가 입력할 id가 된다.
(이는 사용자가 보는 화면에서는 인덱스가 0부터 시작하지 않게 하는 작업이기도 하다)
사용자 id와 Board의 id (글쓴이의 id) 가 일치하는지 보는 selectOne()
private static Board selectOne(Board[] boardArr, int id) {
for (int i = 0; i < boardArr.length; i++) {
if (boardArr[i].id == id) {
return boardArr[i];
}
}
return null;
}
밑의 showOne을 위해 만든 메소드이다.
글을 하나 골라서 개별 보기를 수행하는 showOne()
if문 별로 잘라서 보도록 한다.
list(wrapper, memberArr);
System.out.print("개별보기할 글 번호를 입력해주세요 : ");
int id = MyScanner.nextInt(scan);
Board b = selectOne(wrapper.boardArr, id);
먼저 글의 리스트를 보여주고 개별 보기를 할 글 번호를 입력받는다.
if (b == null) {
System.out.println("존재하지 않는 글 번호입니다. ");
} else {
System.out.println("제목 : " + b.title);
System.out.println("작성자 : " + MemberUtil.showNickName(memberArr, b.writerId));
System.out.println("작성일 : " + b.writtenDate);
System.out.println("글 내용 : " + b.content);
System.out.println("======================================================");
ReplyUtil.list(wrapper.replyArr, b.id, memberArr);
// b.id가 boardId
그런 후 board가 null이면 글이 없다는 것이므로 경고창을 띄운다.
이후 null이 아닌 경우에 글 내용을 출력한다.
(ReplyUtil은 댓글 관리 메소드로 뒤에서 다룬다)
그런 후 사용자가 원하는 글을 골라 보여주고 사용자에게 글에 대한 수정, 삭제 여부를 묻는다.
하지만 글의 수정과 삭제는 글을 쓴 회원에게만 가능하게 해야한다.
if (member.id == b.writerId) {
System.out.println("1. 수정 2. 삭제 3. 뒤로");
int userChoice = MyScanner.nextInt(scan);
if (userChoice == 1) {
// 수정하는 메소드 호출
System.out.println("==== 글 수정 ====");
System.out.println("제목 : ");
b.title = scan.nextLine();
System.out.println("글 내용 : ");
b.content = scan.nextLine();
int index = MyArray.indexOf(wrapper.boardArr, b);
wrapper.boardArr[index] = b; // index 번호 업데이트
System.out.println("수정 완료");
그렇기 때문에 member의 id와 writeId가 동일한 경우에만 글 수정을 수행한다.
글의 수정은 그냥 다시 제목과 글 내용을 입력받은 후 그대로 배열에 덮어버리면 수정이 완료된다.
아래는 2와 3을 눌러 삭제와 뒤로 의 경우이다.
} else if (userChoice == 2) {
// 삭제하는 메소드 호출
// MyArray를 이용해서 boardArr에서 board 삭제
wrapper.boardArr = MyArray.remove(wrapper.boardArr, b);
System.out.println("삭제 완료");
list(wrapper, memberArr); // 삭제후 글 목록 다시 보여줌
} else if (userChoice == 3) {
// 글 목록보기로 돌아간다.
list(wrapper, memberArr);
}
삭제의 경우엔 remove 메소드를 호출해 수행하고 뒤로의 경우엔 list 메소드를 호출한다..
만약 member의 id와 writeId가 다른 경우에는 어떻게 할까?
댓글 기능을 보여준다 .
} else {
// 멤버아이디와 글쓴이 아이디가 다르면 댓글달기
System.out.println("1. 댓글 달기 2. 댓글 수정 3. 댓글 삭제 4. 뒤로");
System.out.print("> ");
int userChoice = MyScanner.nextInt(scan);
아래의 댓글 관련 코드들은 전부 ReplyUtil에서 설명하도록 한다.
1. 댓글 달기 코드이다.
if (userChoice == 1) {
// 댓글달기
Reply r = new Reply();
r.memberId = member.id;
r.boardId = b.id;
System.out.println("댓글 내용을 입력해주세요 ");
System.out.print("> ");
r.content = scan.nextLine();
wrapper.replyArr = ReplyUtil.insert(wrapper.replyArr, r);
// 댓글입력 끝
// 댓글의 id를 선택하고
// 해당 댓글을 쓴 사람이 로그인 했는지 체크하고
// 둘다 가능한거면 삭제
// 아닐 시에는 경고 메세지 출력
showOne(wrapper, scan, member, memberArr);
// 댓글 보여주기
2. 댓글 수정 코드이다.
} else if (userChoice == 2) {
// 댓글 수정
System.out.println("수정할 댓글의 번호를 입력해주세요 ");
Reply r = new Reply();
r.id = MyScanner.nextInt(scan);
int index = MyArray.indexOf(wrapper.replyArr, r);
if(index != -1) {
// 해당 댓글을 쓴 사람과 로그인한 유저가 동일인물인지 확인
r = wrapper.replyArr[index]; // index가져온다
if(r.memberId == member.id) {
// 동일인물이므로 수정 시작
System.out.println("댓글 내용 : ");
r.content = scan.nextLine();
wrapper.replyArr[index] = r; // 덮는다.
}else {
// 다른 사람이 쓴 댓글이니 경고 메세지 출력
System.out.println("권한이 없습니다. ");
}
}else {
System.out.println("존재하지 않는 번호입니다. ");
}
3. 댓글 삭제 코드이다.
} else if (userChoice == 3) {
// 댓글 삭제
System.out.print("삭제할 댓글의 번호를 입력해주세요 : ");
Reply r = new Reply();
r.id = MyScanner.nextInt(scan);
if (MyArray.indexOf(wrapper.replyArr, r) != -1) {
r = wrapper.replyArr[MyArray.indexOf(wrapper.replyArr, r)];
// 해당 위치에 r초기화
if (r.memberId == member.id) {
// 마지막으로 한번 더 물어보고 사용자가 Y라고 입력하면 삭제
System.out.println("정말 삭제 하시겠습니까? 1. Y(네) 2. N(아니오)");
String agree = scan.nextLine();
if (agree.equalsIgnoreCase("y")) {
// IgnoreCase : 대소문자 무시
// 댓글 삭제
wrapper.replyArr = ReplyUtil.delete(wrapper.replyArr, r);
System.out.println("댓글이 삭제되었습니다 ");
}
} else {
// r.memberId != member.id 이면 댓글 작성자가 아니다
System.out.println("권한이 없습니다. ");
}
마지막으로 없는 댓글인 경우와 뒤로 가는 경우이다.
} else {
// -1 : 없는 댓글
System.out.println(" 없는 댓글 번호 입니다. ");
// 글 보여주기
showOne(wrapper, scan, member, memberArr);
}
} else if (userChoice == 4) {
// 뒤로
list(wrapper, memberArr);
}
}
}
return wrapper;
}
바로 댓글 관련 메소드를 보자
ReplyUtil.java
list()
해당 게시글의 댓글을 보여주는 메소드이다.
public static void list(Reply[] arr, int boardId, Member[] memberArr) {
// 댓글 배열과 우리가 어떤 글을 보는지 (boardId)
for(Reply r : arr) {
if(r.boardId == boardId) {
System.out.println(r.id +" "+ r.content +" "+ MemberUtil.showNickName(memberArr, r.memberId));
}
}
}
reply가 가진 boardId와 특정 게시글의 boardId가 같은 경우에 Reply 배열을 나열한다.
insert()
댓글을 추가한다.
public static Reply[] insert(Reply[] arr, Reply r) {
// 인덱스 정해주기
r.id = arr.length > 0 ? arr[arr.length-1].id + 1 : 1;
// if(arr.length > 0) {
// r.id = arr[arr.length-1].id + 1;
// } 위의 삼항연산자로...
arr = MyArray.add(arr, r);
return arr;
}
만약 배열의 길이가 0보다 크다면 reply의 id에 index가 주어진다.
delete()
댓글을 삭제한다.
public static Reply[] delete(Reply[] arr, Reply r) {
arr = MyArray.remove(arr, r);
// 댓글을 쓴 사람만 댓글을 제거하도록
return arr;
}
countReply()
댓글을 카운트해 갯수를 보여준다
public static int countReply(int boardId, Reply[] replyArr) {
int count = 0;
for(Reply r : replyArr) {
if(r.boardId == boardId) {
count++;
}
}
return count;
}
다음은 회원에 관한 메소드들이다.
MemberUtil.java
showNickName()
닉네임을 보여주는 메소드이다.
public static String showNickName(Member[] memberArr, int id) {
for (int i = 0; i < memberArr.length; i++) {
if (memberArr[i].id == id) {
return memberArr[i].nickName;
}
}
return null;
}
logIn()
로그인 기능이다.
private static Member logIn(Member[] memberArr, Member logInTry) {
// 누가 파라미터에 메소드를 부르니 그냥 이름이다 이름
Member m = null;
// 먼저 index가 존재하는지 찾는다.
int index = MyArray.indexOf(memberArr, logInTry.userName);
if (index != -1) { // 일치하는 id를 가진 member를 찾으면
if (logInTry.password.equals(memberArr[index].password)) {
m = memberArr[index];
}
}
return m;
}
logInPrint()
사용자에게 직접 보여지는 로그인 기능이다.
public static Member logInPrint(Member[] arr, Scanner scan) {
// 체크해서 맞는게 나올 때 까지
Member logIn = new Member();
System.out.print("ID를 입력해 주세요 : ");
logIn.userName = scan.nextLine();
System.out.print("비밀 번호를 입력해주세요 ");
logIn.password = scan.nextLine();
logIn = MemberUtil.logIn(arr, logIn);
// 얘가 null이 되면 다시 아이디와 비번 입력을 받는다.
while (logIn == null) {
System.out.println("잘못 입력하셨습니다. ");
logIn = new Member(); // 로그인 초기화
System.out.print("ID를 입력해 주세요 : ");
logIn.userName = scan.nextLine();
System.out.print("비밀 번호를 입력해주세요 ");
logIn.password = scan.nextLine();
logIn = MemberUtil.logIn(arr, logIn); // 틀리면 다시 입력받기
}
// 일치하는 애를 찾아서 while문을 빠져나왔다!
return logIn;
}
index()
로그인과 회원가입을 기능이다.
public static Member[] index(Scanner scan, Member[] memberArr, BoardReplyWrapper wrapper) {
while (true) {
System.out.println("게시판");
System.out.println("1. 로그인 2. 회원가입 3. 종료 ");
System.out.print("> ");
int choice = MyScanner.nextInt(scan);
if (choice == 1) {
// 로그인
Member logInUser = logInPrint(memberArr, scan); // 로그인
showMenu(scan, memberArr, wrapper, logInUser);
// 이 배열들은 메인메소드에서 만들어서 우리한테 보내주기로 한 애들
break;
} else if (choice == 2) {
// 회원가입
memberArr = register(scan, memberArr);
} else if (choice == 3) {
System.out.println("종료 ");
break;
}
}
return memberArr;
}
register()
회원가입 메소드이다
private static Member[] register(Scanner scan, Member[] arr) {
Member m = new Member();
System.out.print("사용할 ID를 적어주세요 : ");
m.userName = scan.nextLine();
// 유효성 검사
// 해당 userName이 존재하는지부터 체크
// indexOf의 결과값이 -1이 아니면
// 계속 돌아가게 만듦
while (MyArray.indexOf(arr, m.userName) != -1) {
System.out.println("이미 존재하는 아이디 입니다. ");
System.out.print("사용할 ID를 적어주세요 : ");
m.userName = scan.nextLine();
}
System.out.println("사용할 비밀 번호를 입력해주세요 ");
m.password = scan.nextLine();
System.out.println("사용할 닉네임을 적어주세요 ");
m.nickName = scan.nextLine();
m.id = 1;
// id값은 BoardUtil.write() 메소드가 알아서 해주는 부분
if (arr.length != 0) {
m.id = arr[arr.length - 1].id + 1; // 배열이 존재하면.. id값 이렇게 준다.
}
arr = MyArray.add(arr, m);
// 결과값을 다시 arr에 넣어야한다.
return arr;
}
showMenu()
메뉴를 보여주는 메소드이다.
private static void showMenu(Scanner scan, Member[] memberArr, BoardReplyWrapper wrapper, Member member) {
// 파라미터 설명
// scanner : 입력에 필요
// Member[] memberArr : 회원 모아놓은 배열
// Board[] boardArr : 게시글 모아놓은 배열
// Reply[] replyArr : 댓글 모아놓은 배열
// Member[] member : 로그인한 유저
// BoardReplyWrapper wrapper : Board[] Reply[] 묶어놓은 포장 클래스
while (true) {
System.out.println("게시판");
System.out.println("1. 글 목록 보기 2. 새로 작성하기 3. 로그아웃 4. 종료 ");
System.out.print(">");
int userChoice = MyScanner.nextInt(scan);
if (userChoice == 1) {
// 글 목록 보기
BoardUtil.list(wrapper, memberArr);
if (wrapper.boardArr.length > 0) {
System.out.println("1. 글 개별 보기 2. 뒤로가기 ");
System.out.print(">>");
userChoice = MyScanner.nextInt(scan);
if (userChoice == 1) {
// 글 개별 보기
wrapper = BoardUtil.showOne(wrapper, scan, member, memberArr);
}
}
} else if (userChoice == 2) {
// 게시물 작성
// 작성한 것은 boardArr에 다시 넣어준다..
wrapper.boardArr = BoardUtil.write(wrapper.boardArr, scan, member);
} else if (userChoice == 3) {
// 로그아웃
// 로그아웃 된 상태에서 회원가입도 가능하게
member = null;
while (member == null) {
System.out.println("1. 회원가입 2. 로그인 3. 종료 ");
userChoice = MyScanner.nextInt(scan);
if (userChoice == 1) {
// 회원가입
memberArr = register(scan, memberArr);
} else if (userChoice == 2) {
// 로그인
member = logInPrint(memberArr, scan);
} else if (userChoice == 3) {
// 종료
// break를 두 번하는 방법
break;
}
}
}
// 여기서 userChoice가 얼마인지 출력해보면
// 우리가 마지막으로 선택한 값들이 남아있다.
// 그런데 만약 userChoice가 3이면?
// >> 사용자가 종료를 골랐다는 것
if (userChoice == 3) {
// 종료
System.out.println("로그아웃 후 종료되었습니다. ");
break;
}
}
}