Swing GUI를 만들다 보면 윈도우를 그래픽툴처럼 디자인하고 싶다는 생각이 든다.

 

물론 이런것을 즐기는 사람도 있을것이다. 그런데 끓임없는 코드의 작성과 수정을 하다 보면 현타가 올 수도 있다. 윈도우는 윈도우니까... 복잡한 레이아웃을 짤때 더 그럴수도 있다.

 

이럴때 이클립스의 WindowBuilder를 사용하면 더 편하게 만들 수 있다. 비주얼 베이직의 그것들 처럼 마우스의 클릭과 드래그로 창을 만들 수 있다. 대부분의 그래픽툴처럼 관리가 편하게 되어 있다.

 

WindowBuilder - 비주얼베이직 같다.

WindowBuilder는 두방향 GUI 디자이너를 지향하는데 소스코드도 직접 수정할 수 있다. 아래쪽 탭에 Source 와 Designer 가 있다. Source code를 수정하면 Designer에 반영되고 Designer를 수정하면 Source code에 즉시 반영이 된다.

 

*WindowBuilder 다운로드 링크

https://www.eclipse.org/windowbuilder/download.php

 

Installing WindowBuilder Pro | The Eclipse Foundation

The Eclipse Foundation - home to a global community, the Eclipse IDE, Jakarta EE and over 375 open source projects, including runtimes, tools and frameworks.

www.eclipse.org

설치방법은 아래 업데이트 사이트 링크를 클릭하여 나오는 주소창을 복사하여 메뉴의 help >> install new software 를 클릭 >> Work with 에 붙여넣고 Add 한다.

 

주소창: https://download.eclipse.org/windowbuilder/lastgoodbuild/

 

WindowBuilder 를 체크하여 설치하면 된다.

 

WindowBuilder를 실해하는 방법은

 

메뉴의 new >> other >> WindowBuilder >> Swing Designer >> JFrame 순으로 클릭한다.

 

 

아래 이미지와 코드를 비교해보면 어떻게 동작하는지 대략 알 수 있다.

 

GUI 디자이너

 

실제 실행화면 (Win10)

 

아래는 위의 결과물이 나오기까지의 코드블록이다. 물론 다른 코드로도 동일한 디자인을 만들수 있다. 디자이너를 통해 나온 코드를 빼서 다시 최적화를 해도 좋고 아니면 그대로 디자이너를 사용해도 된다. 디자이너가 작성하는 코드를 보면서 공부도 된다. 이들은 어떻게 자동으로 코드를 생성했을까라는 의문을 가지고 보면 좋다.

 

여기서는 JPanel에 JTextField와 JButton 을 붙였다. Swing Actions를 사용하면 버튼을 클릭했을시의 Action 을 지정해줄수 있다. SwingAction 이란 클래스가 생성되어 이벤트를 관리해준다. SwingAction 클래스에 오버라이드된 ActionPerformed 메서드 내용을 작성해주면 된다.

package com.kay.builder.test;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;

public class Test extends JFrame {

	private JPanel contentPane;
	private JTextField textField;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Test frame = new Test();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public Test() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 455, 400);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		GridBagLayout gbl_contentPane = new GridBagLayout();
		gbl_contentPane.columnWidths = new int[]{106, 106, 106, 106, 0};
		gbl_contentPane.rowHeights = new int[]{88, 88, 88, 88, 0};
		gbl_contentPane.columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		gbl_contentPane.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		contentPane.setLayout(gbl_contentPane);
		
		textField = new JTextField();
		GridBagConstraints gbc_textField = new GridBagConstraints();
		gbc_textField.gridwidth = 4;
		gbc_textField.fill = GridBagConstraints.BOTH;
		gbc_textField.insets = new Insets(0, 0, 5, 5);
		gbc_textField.gridx = 0;
		gbc_textField.gridy = 0;
		contentPane.add(textField, gbc_textField);
		textField.setColumns(10);
		
		JButton btnNewButton_2 = new JButton("New button");
		GridBagConstraints gbc_btnNewButton_2 = new GridBagConstraints();
		gbc_btnNewButton_2.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton_2.insets = new Insets(0, 0, 5, 5);
		gbc_btnNewButton_2.gridx = 0;
		gbc_btnNewButton_2.gridy = 1;
		contentPane.add(btnNewButton_2, gbc_btnNewButton_2);
		
		JButton btnNewButton_1 = new JButton("New button");
		GridBagConstraints gbc_btnNewButton_1 = new GridBagConstraints();
		gbc_btnNewButton_1.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton_1.insets = new Insets(0, 0, 5, 5);
		gbc_btnNewButton_1.gridx = 1;
		gbc_btnNewButton_1.gridy = 1;
		contentPane.add(btnNewButton_1, gbc_btnNewButton_1);
		
		JButton btnNewButton_4 = new JButton("New button");
		GridBagConstraints gbc_btnNewButton_4 = new GridBagConstraints();
		gbc_btnNewButton_4.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton_4.insets = new Insets(0, 0, 5, 5);
		gbc_btnNewButton_4.gridx = 2;
		gbc_btnNewButton_4.gridy = 1;
		contentPane.add(btnNewButton_4, gbc_btnNewButton_4);
		
		JButton btnNewButton_3 = new JButton("New button");
		GridBagConstraints gbc_btnNewButton_3 = new GridBagConstraints();
		gbc_btnNewButton_3.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton_3.insets = new Insets(0, 0, 5, 0);
		gbc_btnNewButton_3.gridx = 3;
		gbc_btnNewButton_3.gridy = 1;
		contentPane.add(btnNewButton_3, gbc_btnNewButton_3);
		
		JButton btnNewButton_6 = new JButton("New button");
		GridBagConstraints gbc_btnNewButton_6 = new GridBagConstraints();
		gbc_btnNewButton_6.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton_6.insets = new Insets(0, 0, 5, 5);
		gbc_btnNewButton_6.gridx = 0;
		gbc_btnNewButton_6.gridy = 2;
		contentPane.add(btnNewButton_6, gbc_btnNewButton_6);
		
		JButton btnNewButton_7 = new JButton("New button");
		GridBagConstraints gbc_btnNewButton_7 = new GridBagConstraints();
		gbc_btnNewButton_7.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton_7.insets = new Insets(0, 0, 5, 5);
		gbc_btnNewButton_7.gridx = 1;
		gbc_btnNewButton_7.gridy = 2;
		contentPane.add(btnNewButton_7, gbc_btnNewButton_7);
		
		JButton btnNewButton_8 = new JButton("New button");
		GridBagConstraints gbc_btnNewButton_8 = new GridBagConstraints();
		gbc_btnNewButton_8.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton_8.insets = new Insets(0, 0, 5, 5);
		gbc_btnNewButton_8.gridx = 2;
		gbc_btnNewButton_8.gridy = 2;
		contentPane.add(btnNewButton_8, gbc_btnNewButton_8);
		
		JButton btnNewButton_5 = new JButton("New button");
		GridBagConstraints gbc_btnNewButton_5 = new GridBagConstraints();
		gbc_btnNewButton_5.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton_5.insets = new Insets(0, 0, 5, 0);
		gbc_btnNewButton_5.gridx = 3;
		gbc_btnNewButton_5.gridy = 2;
		contentPane.add(btnNewButton_5, gbc_btnNewButton_5);
		
		JButton btnNewButton_10 = new JButton("New button");
		GridBagConstraints gbc_btnNewButton_10 = new GridBagConstraints();
		gbc_btnNewButton_10.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton_10.insets = new Insets(0, 0, 0, 5);
		gbc_btnNewButton_10.gridx = 0;
		gbc_btnNewButton_10.gridy = 3;
		contentPane.add(btnNewButton_10, gbc_btnNewButton_10);
		
		JButton btnNewButton_11 = new JButton("New button");
		GridBagConstraints gbc_btnNewButton_11 = new GridBagConstraints();
		gbc_btnNewButton_11.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton_11.insets = new Insets(0, 0, 0, 5);
		gbc_btnNewButton_11.gridx = 1;
		gbc_btnNewButton_11.gridy = 3;
		contentPane.add(btnNewButton_11, gbc_btnNewButton_11);
		
		JButton btnNewButton = new JButton("New button");
		GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
		gbc_btnNewButton.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton.insets = new Insets(0, 0, 0, 5);
		gbc_btnNewButton.gridx = 2;
		gbc_btnNewButton.gridy = 3;
		contentPane.add(btnNewButton, gbc_btnNewButton);
		
		JButton btnNewButton_9 = new JButton("New button");
		GridBagConstraints gbc_btnNewButton_9 = new GridBagConstraints();
		gbc_btnNewButton_9.fill = GridBagConstraints.BOTH;
		gbc_btnNewButton_9.gridx = 3;
		gbc_btnNewButton_9.gridy = 3;
		contentPane.add(btnNewButton_9, gbc_btnNewButton_9);
	}

}

스윙 디자이너라는 이름에 충실하도록 디자인을 쉽게 해준다. 꽤 오래전부터 무료로 배포하고 있으니까 GUI프로그래밍을 할 일이 있으면 설치해두자. . 2005년 쯤인가 대학에서 이클립스로 강의를 진행했던 기억이 난다. 그 당시엔 최신의 개발툴이었는데... 최근의 강의들을 보면 아직도 자바 강의는 이클립스로 진행하는 곳이 많은 것 같다. 최근 국내의 많은 개발자들이 IntelliJ로 갈아타고 있다고 한다. 아무래도 시대가 원하는 IDE로 바뀌기 마련이다. IDE도 오래되면 기능이 무거워질 수 밖에 없다. 기능들이 하나 둘씩 추가되다 보면 그 기능을 쉽게 삭제하거나 바꿀 수 없다. 원래 그 기능을 사용하는 사용자들이 곤란해지기 때문이다.

 

전세계적으로 아직까지 이클립스는 IDE시장에서 MS VS에 이어 2위니까 그래도 이클립스의 업데이트는 계속 해줄 것 같다.

 

https://pypl.github.io/IDE.html

 

TOP IDE Top Integrated Development Environment index

TOP IDE Top Integrated Development Environment

pypl.github.io

 

공유하기

facebook twitter kakaoTalk kakaostory naver band