Swing Designer 로 그리드백 레이아웃을 만들어 본다.
그리드 레이아웃은 단순하기 때문에 쉽게 작성할 수 있는데 디자인이 아쉽다. 그리드백 레이아웃은 그보다 정교하게 레이아웃을 짤 수 있다. 그런데 그만큼 내용이 복잡해진다. 그렇다면 방법은 Swing Designer 를 사용하여 그래픽을 보면서 디자인 하는 것이다.
이클립스에 설치하는 방법은 아래 포스트를 참조하면 된다.
Swing Designer 로 클래스를 작성한다. 방법은 new >> other >> WindowBuilder >> Swing Designer >> JFrame 으로 open 한다.
처음에 JFrame 과 그 아래에 JPanel이 하나 생성되어있다.
GridBagLayout 을 클릭하고 커서가 + 표시로 바뀌면 contentPane 을 클릭한다. 그러면 레이아웃이 GridBagLayout 으로 바뀐다. 여기까지 swing designer가 자동으로 생성한 코드는 아래와 같다. 아래 Design 탭과 Source 탭을 오가면서 확인할 수 있다.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.GridBagLayout;
public class GridBag1 extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GridBag1 frame = new GridBag1();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public GridBag1() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[]{0};
gbl_contentPane.rowHeights = new int[]{0};
gbl_contentPane.columnWeights = new double[]{Double.MIN_VALUE};
gbl_contentPane.rowWeights = new double[]{Double.MIN_VALUE};
contentPane.setLayout(gbl_contentPane);
}
}
여기서부터는 디자인의 영역이다. 비주얼베이식 처럼 컴포넌트를 클릭하고 패널에 추가하는 방식으로 진행한다.
컴포넌트를 추가할 때 마다 스윙디자이너가 코드를 더해준다. 사실 보이는 것이 그대로 반영이 안되는 경우도 있다. 인터넷의 문서를 많이 찾아봤지만 스윙디자이너와 그리드백 레이아웃에 대하여 추천하는 사람은 없었다. 인텔리제이를 사용하라는 의견이 많았다.
- 결론부터 이야기하면 GridBagLayout을 사용하는 것을 추천하지 않는다. 웹문서를 찾아봤으나 부정적인 평가가 많았다. 자바의 정석 2판까지는 AWT를 다루면서 Layout에 대한 내용이 있었는데 거기서도 GridBagLayout 은 뺀 것을 보니, 저자도 필수로 배워야할 사항은 아닌 것이라 생각하신것 아닌가 의문이 든다.
아래 웹문서에 보면 그리드백 레이아웃은 너무 많은 매개변수를 복잡하게 얽히게 만들어서 실패작이라고 불평하는 프로그래머들의 이야기가 들어있다. 잘쓰면 정교하게 만들 수 있는 도구지만 11개나 되는 값들이 각각의 컴포넌트에 작용하는 방식으로는 일하기가 쉽지 않다고 말한다. 그리드백레이아웃이 아니라 그리드버그레이아웃이라고 말한다 ㅋㅋ
* 그리드백레이아웃을 사용하면 안되는 이유 (Abandon hope, all ye who use GridBagLayout)
이게 조금 나온지 시간이 지난 프레임웤이다 보니까 지금 봤을 땐 별로라고 느낄 수가 있다고 본다. 최근의 UI UX발달은 비단 웹을 소비하는 유저(네티즌) 뿐 아니라 그 웹의 UI UX를 개발하는 개발자들의 환경도 좋아야 한다. 그럴려면 개발 인터페이스가 좋아야 한다. 인텔리제이가 최신 개발자들에게 각광받고 있는 이유가 아닐까 싶다. 정보의 최종소비자인 누리꾼들은 인텔리제이가 뭔지도 모른다. 알 필요 자체가 없다. 하지만 인텔리제이를 사용하는 개발자들은 뭔가 더 다른 것을 느낀다. IDE를 가지고 평가하긴 뭐 하지만 그 사람의 취향이나 라이프 스타일을 말해주는 차이도 존재하지 않을까 싶다.
최근의 개발 환경은 직관적이고 친화적으로 계속 변하고 있다. 하드웨어가 충분히 발전해서 예전에는 생각하지 못했던 무거운 개발환경을 충분히 감당해 내고 있다. 좀 상상같지만 나중에는 키보드를 칠 필요도 없을 거라 생각한다. 뇌파를 읽어서 프로그래밍을 완성할 수 있다고 본다.
*Brain Reading 뇌파 읽는 기술 링크
이런 시대에 어떤 기술이 과거의 유물인지 아닌지 판가름하는 것은 필요한 것으로 보인다. 레이아웃 매니저의 가성비나 효율을 잘 따져 볼 필요가 있다.
그래도 한번쯤 보고 지나가야 한다고 생각해서 그리드백레이아웃에 대한 웹문서를 남겨둔다. 사실 글쓴이도 아직 그리드백레이아웃의 11개의 모든 요소들을 다 파악하지 못했다. 크게 알아야할 이유를 못 느껴서이다. 간단한 프로젝트를 위해서는 너무 복잡한 레이아웃보다 차라리 Absolute Layout (절대 좌표 레이아웃) 으로 만드는게 차라리 나을 것이라 본다.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class SwingEX13 extends JFrame{
JPanel contentPane;
JTextField tf1;
SwingEX13(){
contentPane = new JPanel();
GridBagLayout gbl_contentPane = new GridBagLayout();
setContentPane(contentPane);
contentPane.setLayout(gbl_contentPane);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc_tf2 = new GridBagConstraints();
JButton bt1 = new JButton("NORTH STAR");
gbc_tf2.gridx = 0;
gbc_tf2.gridy = 0;
gbc_tf2.gridwidth = 1;
gbc_tf2.gridheight = 1;
gbc_tf2.fill = GridBagConstraints.BOTH;
contentPane.add(bt1,gbc_tf2);
GridBagConstraints gbc_tf3 = new GridBagConstraints();
JButton bt2 = new JButton("SOUTH WEST");
gbc_tf3.gridx = 0;
gbc_tf3.gridy = 2;
gbc_tf3.gridwidth = 1;
gbc_tf3.gridheight = 1;
gbc_tf3.fill = GridBagConstraints.BOTH;
contentPane.add(bt2,gbc_tf3);
GridBagConstraints gbc_tf4 = new GridBagConstraints();
JButton bt3 = new JButton("EAST AIR");
gbc_tf4.gridx = 2;
gbc_tf4.gridy = 0;
gbc_tf4.gridwidth = 1;
gbc_tf4.gridheight = 1;
gbc_tf4.fill = GridBagConstraints.BOTH;
contentPane.add(bt3,gbc_tf4);
GridBagConstraints gbc_tf5 = new GridBagConstraints();
JButton bt4 = new JButton("WEST LIFE");
gbc_tf5.gridx = 1;
gbc_tf5.gridy = 2;
gbc_tf5.gridwidth = 1;
gbc_tf5.gridheight = 1;
gbc_tf5.fill = GridBagConstraints.BOTH;
contentPane.add(bt4,gbc_tf5);
GridBagConstraints gbc_tf6 = new GridBagConstraints();
JButton bt5 = new JButton("CENTRAL TIGER");
gbc_tf6.gridx = 0;
gbc_tf6.gridy = 3;
gbc_tf6.gridwidth = 2;
gbc_tf6.gridheight = 1;
gbc_tf6.fill = GridBagConstraints.BOTH;
contentPane.add(bt5,gbc_tf6);
GridBagConstraints gbc_tf7 = new GridBagConstraints();
JTextField jf1 = new JTextField("NEO AGE");
gbc_tf7.gridx = 0;
gbc_tf7.gridy = 1;
gbc_tf7.gridwidth = 2;
gbc_tf7.gridheight = 1;
gbc_tf7.fill = GridBagConstraints.BOTH;
contentPane.add(jf1,gbc_tf7);
setBounds(1400, 300, 450, 300);
setTitle("Swing GridBag Layout");
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new SwingEX13();
}
}
딱히 설명할 것은 없는 코드이다. 그리드백레이아웃의 컴포넌트들은 서로 상대적으로 변화하기 때문에 하나의 컴포넌트를 제외하거나 좌표를 바꾸면 다른 컴포넌트들이 연동해서 바뀌는 방식이다. 따라서 기준점을 잡기가 어렵다. 기준점을 잡으려면 columnWidths 나 rowHeights 들을 가지고 만들어야 하는데 갭(틈새) 등에 대한 설정까지 해야하기 때문에 상대적으로 복잡하다. HTML/CSS에 익숙한 사람들이라면(프론트엔드 디자이너) 쓸만할 것이라고 한다.
아 그렇구나라는 생각이 들었다. 프론트엔드 개발자들은 항상 이런 복잡한 레이아웃을 다뤄야 하니까... 로직을 짜는 백엔드와 프론트엔드의 차이가 그런 부분이 있었다. 디자인학과를 나왔던 안나왔던 공간감각이 있어야 한다. 알고리즘과는 조금 다른 이야기 같다.