[Swing] GridBagLayout 에 대한 정리 1

4. 컴포넌트를 여백의 어디에 위치시킬 것인가?


컴포넌트의 크기가 할당받은 공간(컴포넌트 자체의 크기 + 남는 공간의 크기)보다 작을 경우에 컴포넌트를 할당받은 공간의 어디에 표시할 것인지를 나타낸다.

anchor가 유효하려면 다음의 조건이 충족되어야 한다.

컴포넌트가 남는 공간을 확보했다.
컴포넌트가 남는 공간을 다 채우지 않았다.

즉, weight 값이 0보다 커서 남는 공간을 확보한 상태에서 fill = GridBagConstraint.NONE이거나 부분적으로 채우는 HORIZONTAL, VERTICAL일때만 의미가 있다.

상식적으로 weight 가 0이거나, 또는 0 보다 커서 여백을 확보했지만 fill = GridBagConstraint.BOTH로 다 채웠다면 anchor를 적용할 여지가 없어진다.

anchor는 9개의 값을 갖는다.

[그림1]http://java.sun.com/docs/books/tutorial/uiswing/layout/gridbag.html

How to use GridBagLayout 강좌의 페이지를 캡쳐한 것인데, 상하좌우, 좌상단, 좌하단, 우상단, 우하단, 가운데, 이렇게 9개의 값을 설정할 수 있다.(기본값은 CENTER)

[그림1]에 나온 값은 Orientation에 상대적인 값인데 Orientatiion이란 "컴포넌트를 배치하는 방향" 정도를 의미한다. 우리에게 익숙한 왼쪽에서 오른쪽으로 배치하는 경우와 반대로 오른쪽에서 왼쪽으로 배치한느 경우, FIRST_LINE_START 가 가리키는 위치도 달라지게 된다.

이와 다르게 Orientation과 상관없이 지정할 때에는 아래의 값을 사용한다.

[그림2] 이것은 절대 위치를 의미함.

사실 컴포넌트를 오른쪽에서 왼쪽으로 쓸 일이 거의 없다보니 대부분의 경우 위와같이 동서남북의 형태로 사용하게 되는 듯 하다.

5. 여백 주기

열심히 레이아웃을 잡아놓고 나면 아래와 같은 갑갑한(?) 모습이 나오게 된다.

[그림3]다닥다닥 붙어서 보기 안좋다.

label과 textfield가 붙어있어서 보기에 심히 좋지가 않은데, 이와같이 레이아웃이 어느정도 잡힌 후에 inset 과 ipadx, ipady 로 컴포넌트간의 간격을 조정할 수 있다.

insets은 "컴포넌트에게 할당된 공간"과 컴포넌트 사이에 삽입하는 공백이고 ipadx, ipady는 컴포넌트 안에 삽입하는 공백이다.

ipadx와 ipady 는 컴포넌트간의 높이나 너비가 맞지 않을때 패딩을 삽입해서 보기 좋게 만든다. 아래와 같은 그림을 보면 text field와 button의 높이가 서로 다른 것을 알 수 있다.

[그림4]높이가

text field에 ipady = 7 정도를 설정해서 높이를 똑같이 맞춰주면 깔끔해보인다.

[그림5] ipady

하지만 label이 양 옆으로 꽉 붙어서 답답한 느낌이 드니 label 에 inset을 지정해서 다음과 같이 바꾸면 한결 보기가 좋다.(마찬가지로 button에도 추가하면 좋다)

6. 설정 순서 정리

GridBagConstraints 값을 설정할 때 다음과 같이 하면 문제를 최소화할 수 있다.

* gridx, gridy 로 위치를 잡는다.
* gridwidth, gridheight 로 셀 구간을 할당한다.

이렇게 위치를 잡아놓은 다음에 남는 공간을 할당한다.

공간을 할당한 후에 각 셀이 어느 정도의 공간을 확보했는지 대강 짐작할 수 있도록 다음과 같이 anchor를 WEST로 지정한다.

GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.WEST;

기본값이 CENTER인 경우에는 인접한 셀 사이의 여백이 모호해서 눈으로 짐작하기가 힘들다.(제대로 벌어진건지 아니면 쪼그라 든 상태인지 확인이 안된다.)

* weightx 를 분할 지정한 후 확인.
* weighty 를 분할 지정한 후 확인.

여백 지정이 제대로 되었다면 각각의 셀에 "fill" 값을 적용해서 벌려준다.

화면이 제대로 나온 것을 확인한 후 insets과 ipadx, ipady 를 지정해서 마무리 한다.

7. 정리하면....

GridBagLayout은 강력하지만, API가 난해해서 사용하기가 쉽지 않다.

무엇보다도 서로 다른 맥락에서 사용되어야할 설정값들의 타입이 모두 int 형으로 되어 있어서 GridBagLayout에 익숙치 않은 사용자들은 설정값을 엉뚱하게 할당해서 에러가 속출하는 요인이 된다.(보통 아래와 같은 식이다.)
위와같이 assigning 해서는 안되는데도 모두 int 타입이다보니 자칫 잘못했다가는 뒤죽박죽이 되어버려서 한 번 꼬이면 바로 잡느라고 시간을 엄청 잡아먹는다.

게다가 자바 튜토리얼 문서를 보면, 한 번 생성한 GridBagConstraints 를 계속해서 재사용하는 예를 보여주는데, 선행하는 컴포넌트에 적용된 설정값이 그 다음 이어지는 컴포넌트에 영향을 미쳐서(즉, 제대로 초기화가 안되어서) 엉뚱한 화면이 튀어나올때가 많다.(아마도 가장 많은 에러가 여기서 발생하지 않을까 싶다.)

또한 GridBagLayout 자체가 "각각의 컴포넌트 단위"로 레이아웃을 지정하다보니 원시적인 수타 코딩을 하면 코드가 엄청나게 길어지고, 만에 하나 중간에 다른 컴포넌트를 끼워넣는다든가 하면 이제 죽는 일만 남게 된다.

이런 문제점때문에 GridBagConstraints.REMAINDER, RELATIVE같은 설정값을 마련해두었지만 위치의 절대 지정과 상대 지정이 또 뒤석이면서 문제를 악화시킬 때도 많다. 사용자들이 "매우 잘 이해하고 있어야 한다"는 전제 조건이 걸림돌이 된 대표적인 사례가 바로 GridBagLayout이 아닐까 싶다.

이렇다보니 요즘 IDE에서는 레이아웃을 잡아주는 플러그인을 따로 제공한다. 대부분의 경우 GridBagLayout을 수타 코딩하는 사람은 별로 없다. 플러그인으로 레이아웃만 잡아놓고 여기에 리스너를 붙이는 일을 따로 손보는 식이다.

하지만 ui 를 잡아주는 Tool을 쓰더라도, 기본적인 이해가 뒷받침 되지 않으면 여전히 화면이 원하는대로 나오지는 않는다. Tool을 쓰는 이유가 번거로운 반복 작업에 들어갈 시간을 줄이는 데 있으니 Tool을 잘 쓰려면 이론이 뒷받침 되어야 할 듯 싶다.





'Dev > Java' 카테고리의 다른 글

GridBagLayout Utility Class  (0) 2010.05.06
[Swing] GridBagLayout에 대한 정리 2  (3) 2010.05.06
[Swing] GridBagLayout 에 대한 정리 1  (3) 2010.05.06
TDD 로 iBATIS 3 예제 구현  (0) 2010.05.05
Posted by yeori

댓글을 달아 주세요

  1. silver-lining
    2010.07.01 20:18

    좋은 글 잘보았습니다.
    저도 현재 swing 으로 프로젝트를 진행중입니다.
    yeori 님 처럼 Util 클래스를 간단히 만들어 사용중인데
    gc.fill = GridBagConstraints.BOTH;
    gc.weightx = weightx;
    gc.weighty = weighty;
    gc.gridx = xpos;
    gc.gridy = ypos;
    gc.gridwidth = width;
    gc.gridheight = height;
    gc.insets = new Insets(top, left, bottom, right);

    fill 을 기본적으로 BOTH 로 잡고 weightx와 weighty, gridx,y, gridwidth, height, insets
    으로 레이아웃을 잡습니다.
    적당한 x, y좌표와 x y의 길이 그리고 여백이 남았을 시 주는 gridwidth height 등을 주면
    제가 원하는 화면으로 나옵니다. 허나 텍스트 필드의 경우 Document 로 해당 텍스트의 리미트 lenghth 를
    주지 않는다면 텍스트필드의 길이가 레이아웃을 벗어난 크기로 길어져 버립니다.
    그래서 해결을 setPreparedSize(new Dimension()) 으로 처리하는데 어떤점이 원인일지
    아실것 같아서 간단히 적어봅니다. 지금까지 이렇게 상세한 내용은 보지 못하였는데 전체적으로
    다 체감되지 않아서 인지 실제 코딩으로 직접 적용해보지 않는이상은 저는 잘 모르겠더라구요.. 음

    • 2010.07.02 09:46 신고

      안녕하세요 ^^ 오랫만에 블로그 들어와서 봤더니 댓글이 있네요 ^^

      말씀하신 현상이 정확히 어떤 상황에서 나타나는지는 잘 모르겠습니다. gridlayout의 경우에는 코드 자체를 보지 않는 한 무엇이 잘못이다라고 딱 꼬집어서 말하기가 어렵거든요.

      일단 문제가 생기면 한 줄 한 줄 입력하면서 문제 지점을 찾는 수밖에는 없어보입니다.

      그럼 수고하세요 ^^

  2. 20191202
    2019.12.02 21:59

    과제하는데 많은 도움이 되었습니다. 감사합니다.

나의이름 패스워드

홈페이지 비밀글