java awt 에서 그림을 그릴 때 Container 와 Canvas 의 차이점.

SIGMA8634 chipset 기반에서 시스템 전반에 관여하는 SETUP 프로그래밍을 하고 있다.

havi ui API를 이용하지 않고 java awt api 만을 이용하여 개발 중이다. jvm 호환성만 의존한 상태로 다양한 플랫폼을 지원하기 위해서이다.

SETUP UI 를 개발하면서 가장 큰 애로사항 또는 고려할 점은,

1. 사용자 액션-리모콘 입력-에 따라 즉시 화면이 출력되어야 하므로 빠른 반응을 위해서 SETUP UI 는 미리 메모리에 객체 생성/초기화 되어 있어야 한다.(객체, 리소스(이미지, 사운드 등))

2. STB 과 같은 제한된 자원의 임베디드 환경이라는 점.

3. 메뉴 간 이동(전환) 빠르기가 적절해야 한다.

4. UI 가 편리해야 한다.

..정도로 생각할 수 있겠다.

이 중에서 구현하는 데 있어 깊은(?) 내공을 가지지 않고서는 힘든 부분이 있는데-다른 부분도 마찬가지지만..ㅡ,.ㅡa- , 3번을 고심해 볼 필요가 있다.

예로, A 메뉴가 있고, A 메뉴 내 B 서브 메뉴가 있는 등,

– A
—– B
———– E
———– F
———– G
—– C
—– D

위와 같이 가정하면,

A 메뉴 내에는 B, C, D 메뉴가,
B 메뉴 내에는 E, F, G 메뉴가 구성되어 있다는 것을 알 수 있다.

즉, A 메뉴에서 B 메뉴를 선택하면, 화면이 바뀌면서 전체 화면이 B 메뉴가 주관이 된다.

이때, 전체 A 메뉴에서 B 메뉴로 바뀔 때,

여럿 graphics api 를 이용하여 실시간으로 그림을 그릴 것인지, 미리 화면을 그려놓았다가 화면 전환을 할 것인지는 개발자 몫이다.

하드웨어 성능이 뒷받침이 된다면야 실시간도 무리가 아니지만 임베디드라는 환경에서, 보통은 화면 깜빡임이 나타나는데-큰 화면을 부분적으로 그리더라도, 빠른 PC에서 조차도 나타난다.- 이를 방지하고자 더블버퍼링 기술을 쓰기도 한다.

그래서, 고심 끝에 각 메뉴별 장면을 미리 그려놓았다가 메뉴 전환시 메뉴별 장면을 바꿔치는 방법을 선택했다.-자원 문제에 대해서 다음에 다룬다.-

이를 쉽게 응용할 수 있는 방법으로, awt CardLayout 있었다.

CardLayout 은 장면 전환이 쉽게 되도록 지원하는 배치 관리자 중 하나인데, 카드를 여러 개 포개어 놓고, 필요한 카드만 보는 레이아웃이다.

처음 개발 중에는 저 레이아웃을 이용해 각 장면 단위로 어떤 컴포넌트를 이용할까 고민하다가 고른 것이 Canvas 였다.

java에서 그림 그리기 딱인 컴포넌트가 Canvas 이니까 말이다.

그래서 각 장면을 Canvas를 상속받아 Scene 이란 컴포넌트를 만들게 되었고, 아래와 같이 각 장면 컴포넌트는 CardLayout 에 이용해 출력했다.

//장면 생성
//MainMenu와 SystemMenu는 Scene을 상속
MainMenu mainMenu = new MainMenu();
SystemMenu systemMenu = new SystemMenu();
.
.
//장면을 출력할 container
Frame frame = new Frame(“Setup”);
Window window = new Window(frame);
//레이아웃매니저
CardLayout cardLayout = new CardLayout();
window.setLayout(cardLayout);
//장면을 등록
window.add(“MainMenu”, mainMenu);
window.add(“SystemMenu”, systemMenu);
.
.
//원하는 장면 출력
cardLayout.show(window, “MainMenu”);
.
.
cardLayout.show(window, “SystemMenu”);
.
.

위와 같은 형태로 코딩했다. 그리고 테스트를 수행…

그런데 생각지 못한 결과가 나왔다.

장면 전환시 깜빡임이 발생했다. 미리 장면을 다 그려놓고 장면을 바꿔치기 한 것 뿐인데 화면 깜빡임이 발생한 것이다.

시간 차를 주고 디버깅을 해보니, 분명 장면을 그리는 중에 나타나는 현상을 아닌 것 같았는데 한참이나 고심을 했다.

그런데 아주 쉽게 풀리는 열쇠를 발견 했으니, 장면이 상속받은 개체에 문제가 있었다.

쉽게 그림그리는 장면 단위만 생각해서 Canvas 개체를 가져다 쓴 것인데, 이게 jvm 내에서 Canvas를 교체할 경우-장면전환- 화면을 다시 지우는 현상이 있었다.

Canvas에서 Container 로 변경하니 깜빡임이 없어졌다.

//변경 전
public abstract class Scene extends Canvas
//변경 후
public abstract class Scene extends Container

Container 를 상속받느냐 Canvas를 상속받느냐에 따른 화면 처리 차이가 궁금해진다.

둘다 Component에서 시작한 것들인데 CardLayout에서 화면 출력시 처리가 다른 모양이다.

언제 찾아보기나 할까나~ ^^;;

Leave a Comment