인터페이스 부분 셋팅 파일

Quiz.zip

프로젝트 진행에 관한 파일.

기본적인 인터페이스만 완료.

DB와 네트워크 부분 그리고 그 밖에 부분은 제외 시킨 파일.

by 만성피로 | 2008/11/16 20:32 | 정리할 자료들 | 트랙백 | 덧글(0)

DB 사용에 대한 고민.

현재 프로젝트 진행 정도는 DB와 네트워크 부분 수정 문제로 프로젝트가 잠시 중단 된 시점이다.

DB를 사용 하는 방법에는 2가지를 고려 중이다.

1. 클라이언트 쪽에서 DB 서버에 직접 접근을 한다.
2. 네트워크를 통해서 서버에 쿼리메시지를 보내고 서버는 받은 쿼리메시지를 이용해서 DB에 접근하는 방법이다.

그러나 DB에 접근 할 수 있는 계정을 호스트 마다 정할 수 있다는 점에서 약간 주춤 했던 것이 한가지 있다.
계정명@호스트명 이런식으로 정한다면 모든 호스트에 대한 설정이 문제가 됐었다.

이점에 대해서 검색을 해본 결과..

계정명@%

이렇게 하면 그 어떤 호스트에서도 접근이 가능하다. 그럼 1번의 방법을 이용한다면 클라이언트가 DB에 직접 접근이 가능하다.
이렇게 한다면 java.net 패키지 없이 서버 DB에 접근이 가능하다.

그러나 1번을 이용하지는 않으려고 생각중이다. 여러 클라이언트에서 DB에 접근을 시도 한다고 가정 했을 때 문제가 될 소지가 있다고 보기 때문이다.

2번의 방법을 이용한다면 서버쪽에 DB 쿼리 메시지를 처리해줄 프로그래밍만 해주면
클라이언트 <-네트워크이용-> 서버  <-DB이용-> MySQL
위와 같은 구조로 한다면 프로젝트의 질적인 부분에서도 더 좋다고 생각된다.

끝으로 현재 까지 진행 상황은
로그인, 계정 생성, 계정 삭제, 암호변경, 계정찾기 까지 모두 완료 된 상태이다.

by 만성피로 | 2008/11/16 20:08 | 정리할 자료들 | 트랙백 | 덧글(2)

윈도우 창 속에 윈도우 창 - JInternalFrame.

위에 보이는 이미지는 원도우 창 안에 윈도우 창이 존재하는 이미지 입니다. 보통 포토샵 프로그램에서 여러 이미지를 불러오게 되면 포토샵 프로그램 창 안에 여러가지 이미지들이 각각 따로 배치가 돼 있는 것을 볼 수 있습니다. 오늘은 바로 이와 같이 윈도우 창 안에 윈도우 창을 넣는 방법에 대해서 이야기 해 봅시다.

그럼 위에 이미지를 아주 단순하게 생각을 해 봅시다.

JFrame 안에 JFrame를 넣는다.
이 단순한 생각을 코딩한다면 JFrame.add(JFrame) 이런 방식을 사용한다는 의미 일 것입니다.
그러나 실제로 돌리면 안된다는 것을 알 수 있습니다. 물론 공부를 탄탄히 하셨다면 왜 인지도 알수 있겠지요.

그럼 어떻게 해야 할까요? 방법은 간단합니다 JInternalFrame 클래스를 이용하면 됩니다.
JInternalFrame 클래스에 대한 자세한 정보는 API를 참고하세요.

이용 방법은 간단합니다. add를 이용해서 넣어주면 됩니다.

그러나 여기서 주의해야 할 것이 한가지 있는데..

setSize, setLocation 등 일부 메소드가 먹히지 않는 경우가 발생할 수 있습니다.

그 이유는 바로 레이아웃 메니저에 대한 설정 문제 입니다. 이런 간단한 설명으로는 이해가 부족할 수 있으니 간단한 예제를 통해서 더 자세히 알아보도록 합시다.

import javax.swing.*;

public class Internaltest {

 public static void main(String[] args) {
  JFrame frm = new JFrame("외부 윈도우 창");
  
  JPanel jp = new JPanel();
  frm.setLayout(null);
  // 이 부분이 생각보다 중요할 수 있습니다. 레이아웃 메니저 때문에 원하는 데로 설정이 안될 수도 있습니다.
  // JPanel, JFrame는 기본적인 레이아웃이 다르게 설정 돼 있죠..

  JInternalFrame inter = new JInternalFrame("내부 윈도우 창",false,false,false,false);
    // JInternalFrame 클래스는 생성자가 많으니 API를 잘 참고해야 합니다.

  inter.setSize(200,300);
  inter.setLocation(100, 50);
  inter.setVisible(true);
  
  frm.add(inter);
  frm.setSize(500,500);
  
  frm.setVisible(true);
  
 }
}

간단한 예제이지만 실제로 해보지 않으면 도움이 되질 못합니다. 꼭 해보시길 바랍니다.

by 만성피로 | 2008/11/10 22:42 | 정리할 자료들 | 트랙백 | 덧글(1)

메뉴바 만들기.

이번 글에서는 메뉴바를 만들어 보도록 하겠습니다.
그리고 awt에 있는 Menu가 아닌 swing에 있는 JMenu를 예로 합니다.

위에 보이는 그림은 현재 프로젝트를 진행하고 있는 기본 인터페이스 입니다. 저것을 가지고 쉽게 그림으로 알아보도록 합시다.

메뉴를 위와 같이 구성 하려면 다음의 3가지 클래스를 이용해야 합니다.
JMenuBar 클래스
JMenu 클래스
JMenuItem 클래스

조금 귀찮죠 -_-? 그래도 오히려 이 때문에 더 쉽게 기억 될 수 있으니 철자만 잘 외우세요 -_-;


가장 먼저 위에 그림에서 활성화 된 부분에 해당하는 클래스는 JMenuBar 클래스 입니다.
모든 메뉴의 내용들은 최종적으로  JMenuBar 클래스에 들어가게 됩니다.

더 쉽게 말하자면 우리가 각종 JButton, JTextArea, JPanel은 모두 JFrame에 들어가는 것과 같다고 할 수 있습니다.

그럼 다음 그림을 보도록 합시다.
좀 전에 그림과 약간 비슷하지만 위에 활성화 된 영역은 JMenu 클래스 입니다.
파일에 해당하는 JMenu 객체
게임에 해당하는 JMenu 객체
도움말에 해당하는 JMenu 객체
이렇게 3개가 존재하게 됩니다.

이 3개의 객체들은 JMenuBar에 들어가게 되는 것이지요.
JMenuBar 객체.add(파일);
JMenuBar 객체.add(게임);
JMenuBar 객체.add(도움말);
이런 식입니다.

그럼 마지막으로
위에 보이는 활성화 된 영역은 JMenuItem 클래스 입니다.
형식은 List 클래스 활용과 비슷하기도 합니다. 허나 다른점은 각 메뉴별로 JMenuItem형 객체라는 점이지요
현재 보이는 그림을 예로 들면
로그인 부터 종료 까지 총 6개의 JMenuItem 객체가 JMenu형 객체(파일)에 속하는 것입니다.
JMenu 객체.add(로그인);
.....
JMenu 객체.add(종료);

이런식입니다. 아주 간단하고 쉽습니다.

이를 예제 소스의 일부를 보도록 합시다.

  file = new JMenu("파일");
  game = new JMenu("게임");
  help = new JMenu("도움말");
  
//파일 메뉴의 항목들
  file_login = new JMenuItem("로그인");
  file_idCreate = new JMenuItem("계정생성");
  file_idSearch = new JMenuItem("계정/암호 찾기");
  file_passChange = new JMenuItem("암호변경");
  file_logout = new JMenuItem("로그아웃");
  file_exit = new JMenuItem("종료");
  
//게임 메뉴의 항목들
  game_start = new JMenuItem("게임시작");
  game_rank = new JMenuItem("랭킹보드");
  
//도움말 메뉴의 항목들
  help_info = new JMenuItem("게임정보");
  help_update = new JMenuItem("업데이트");
  
//항목을 해당 목록에 넣기
  file.add(file_login);
  file.add(file_idCreate);
  file.add(file_idSearch);
  file.add(file_passChange);
  file.add(file_logout);
  file.add(file_exit);
  
  game.add(game_start);
  game.add(game_rank);
  
  help.add(help_info);
  help.add(help_update);

//메뉴바에 모두 배치  
  menubar = new JMenuBar();
  
  menubar.add(file);
  menubar.add(game);
  menubar.add(help);

전체적으로 봤을 때 awt를 배울 때와 같은 형식입니다. 쉽게 생각하도록 합시다.

그리고 각 메뉴를 클릭 했을 때 일어나야 할 이벤트들은 ActionListener을 써야 한다는 점을 생각해보도록 합시다.
왜? 라는 생각을 할 수도 있겠지만 ActionListener가 무엇을 하는 것인가? 라는 것을 생각해 보면 알 수 있습니다.

그리고 JFrame에 적용 시키는 방법은 약간 다릅니다.
add()를 활용하는 것이 아니라 setJMenuBar() 메소드를 이용해야 합니다.

JFrame형객체.setJMenuBar(JMenuBar형객체);

여기까지가 메뉴바에 대한 간단한 설명이었습니다. 더 자세한건 API를 참고하면 됩니다.

다음 글에는 JInternalFrame에 대해서 이야기를 해봅시다.

by 만성피로 | 2008/11/07 21:56 | 정리할 자료들 | 트랙백 | 덧글(1)

실습 과제 풀이.

우리가 흔히 프로그램을 설치 또는 특정 작업을 컴퓨터가 처리 할 때 몇 퍼센트 정도 진행이 됐는지 알 수 있도록 하기 위해서 위와 같이 JProgressBar(JProgressBar는 자바에서 불리우는 명칭이자 클래스 입니다.)를 이용합니다.

위에 보이는 그림은 참으로 단순하기 그지 없는 JProgressBar 실습예제입니다. 그러나..

실습 과정에서 약간의 문제가 발생하는 부분이 있어서 해설편을 이렇게 준비를 했습니다.

그럼 하나 하나 알아보도록 합시다.
일단 위에 보이는대로 인터페이스를 완성합니다.
그리고 각 버튼에 이벤트를 정해주고 실행을 합니다.

문제가 되는 부분은 여기 부터 입니다. 캡쳐가 없어서 보여드리지는 못하지만 다음의 문제가 발생하는 경우 잘 봐두셔야 합니다.
증가 버튼을 누르면 버튼이 눌린 상태로 다운 먹은 듯한 현상이 잠시 일어난 뒤에 바의 색이 전부 파랗게 차 있다.

이런 문제가 발생했다면 해결 방법은 다음과 같습니다.

이벤트 버튼에 직접 JProgressBar 객체에 상태를 변화시키는 코딩을 했기 때문에 발생하는 문제입니다.

왜? 그렇게 코딩을 하면 안되느냐?
이는 멀티쓰레딩과도 같은 효과를 바라는 것이기 때문에 문제가 되는 것입니다.

우리는 메인 메소드를 통해서 프로그램을 동작시킵니다.
그 말은 현재 프로그램은 메인메소드가 동작중이라는 말이 되지요.

그러나 이벤트리스너를 적용시켰다면 버튼을 눌렀을 때는 이벤트가 발생합니다.
이벤트는 하나의 메소드가 실행되는 것이지요..

그럼 당연히 메인메소드는 잠시 중단이 되고 이벤트 메소드가 실행됩니다.
그래서 화면이 멈춰 있는 듯한 현상이 일어나는 것입니다.

약간의 해설을 더 하자면 완성된 인터페이스가 보여지는 것은 메인메소드에서 실행되기 때문입니다.
이벤트리스너는 단순히 이벤트 메소드를 실행하는 것입니다.(이래도 어렵다면 그림을 그리세요)

이를 해결 하는 방법은 두가지 방법이 존재합니다.
1. 멀티쓰레드를 이용한다.
2. 이벤트가 메인메소드에서 실행돼야 한다.

이 두가지 방법을 보면 멀티쓰레드를 사용할 줄 안다면 1번이 더 쉽다고 느껴질 수 있습니다. 그러나 멀티쓰레드로 해결하지는 않겠습니다. 멀티 쓰레드로 한다면 약간의 문제의 소지가 더 있기 때문에 2번으로 해결하겠습니다.

메인메소드에서 이벤트가 실행돼야 한다.
어떻게 할까요? 이벤트 메소드를 메인 안에서 해결한다는 것은 메인 메소드 안에서 무명 클래스 또는 기타 여러가지 방법을 이용해야 하지 않을까 하는 생각이 들 수도 있습니다. 그렇다면 변수의 접근할 수 있는 권한 설정이 바껴야 한다는 점도 있을 수 있고 여러가지 귀찮은 상황이 일어날 수 있습니다.

그래서 아주 간단하게 해결 하도록 하겠습니다.

일단 버튼을 클릭해서 실행 했을 때 JProgressBar 객체의 상태 변화를 주지는 않겠습니다.
단순히
증가는 증가 스위치, 감소는 감소 스위치, 정지는 정지 스위치
이렇게 변수를 지정해서 사용하겠습니다.
그럼 버튼을 클릭하면 메인은 아주 찰나의 시간 동안 멈추고 이벤트를 처리하고 다시 메인으로 돌아옵니다.
그럼 메인에서 스위치에 따라 동작을 하도록 하면 됩니다.

메인에서 직접 짜도 되고 메소드를 메인에서 실행 하는 방법을 취하면 됩니다.
이는 아주 간단하게 이해 할 수 있도록 소스롤 보는쪽으로 합시다.
 public void progressBar() {
  try {
   while (true) { // 루프는 무한으로 돌아야 한다.
    while (state == PLUS) { // state 변수의 변화에 따라 루프문을 실행한다.
     Thread.sleep(50); //잠시 쉰다.
     jpb.setValue(index); // JProgressBar 객체에 값을 변화 시킨다.
     label.setText("현재상태 : " + index + "%");
     if (index < 100) {
      index++;
     }

    }
    while (state == MINUS) {
     Thread.sleep(50);
     jpb.setValue(index);
     label.setText("현재상태 : " + index + "%");
     if (index > 0) {
      index--;
     }
    }
    while (state == STOP) {
    }
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

PLUS, MINUS, STOP는 final 변수이고 state가 액션리스터 메소드에서 값을 변화합니다.
 private final int PLUS = 1;
 private final int STOP = 0;
 private final int MINUS = 2;
 private int state = 0;

그리고 메인메소드에서 이 루프문이 들어 있는 메소드를 실행하면 메인에서 동작하는 것이기에 다운 된 듯한 현상을 깔끔히 해결 할 수 있습니다.
 public static void main(String[] args){
  Exam1102 ex = new Exam1102();
  ex.progressBar();

 }

전체 소스는 아래 파일을 참고 하세요.
Exam1102.java 

그리고 아까 잠시 이야기 했던 멀티쓰레드를 이용하는 방법에 대해서 이야기 합시다.

이 문제가 발생할 수 있는 이유는 다음과 같습니다.
처음 이벤트를 실행 할 때는 전혀 문제가 되지 않습니다. 그러나 문제는 그 이후부터 발생합니다.
멀티쓰레드를 이용하기 위해서는 약간의 조건이 붙는데 한번 실행 된 메소드는 다시 실행이 불가능합니다.
다시 실행을 하려면 객체를 다시 만들어야 한다는 점이지요.
메소드의 재활용이 불가능하다.(?) 라고 할 수 있습니다.
그렇다면 매번 버튼이 눌러질 떄 마다 객체를 새로 생성해야 한다는 것이 문제가 되지요.
어떻게든 잘만 코딩을 한다면 이 문제점을 해결 할수도 있다고 보는데 일단은 효율적인 면에서 떨어진다고 봅니다.
너무 어려운 길을 돌아서 가는 방법이기 때문이지요.
자바를 이해하고 연구 분석을 하기에는 괜찮은 방법일지는 모르겠지만 얻는 것보다 손해 보는 것이 더 많다고 판단 되기 때문에 이 방법은 추천하지 않습니다.

그럼 이번 글은 여기서 마치도록 하겠습니다.

멀티쓰레드에 관한 정보는 아직 부족한 것이 많으니 보충 설명은 댓글을 달아주세요 ^^;

by 만성피로 | 2008/11/03 21:49 | 정리할 자료들 | 트랙백 | 덧글(1)

◀ 이전 페이지다음 페이지 ▶