메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

내 맘대로 꾸미는 자바 스윙 컴포넌트

한빛미디어

|

2004-08-09

|

by HANBIT

27,028

저자: 김영익 / (주)콘델라


자바 언어를 공부하는 사람은 누구나 접하는 것이 AWT와 스윙(Swing) 컴포넌트이다. 대부분의 자바 서적에서 다루고 있으며, 자바 언어 자체가 처음 등장했을 때 브라우저 안에서 보여주는 역동적인 GUI를 보고서 감탄하곤 했었다. 그러나 자바에서 처음 지원했던 GUI 컴포넌트인 AWT로는 개발자들을 감동시키기에는 너무 역부족이었다. AWT에서 지원하는 컴포넌트로는 요즘의 현란한 윈도우 프로그램들을 따라 갈수가 없기에 스윙 컴포넌트가 추가되었으며, 요즘에는 스윙 컴포넌트로 제작된 멋진 GUI 프로그램들이 등장하곤 한다. 스윙 컴포넌트에서는 “Look & Feel” 이라는 것이 있는데 마치 윈도우의 테마를 변경하는 것처럼 다양한 컴포넌트의 속성을 한꺼번에 변경이 가능한 것이다. 이제부터 우리는 “Look & Feel” 처럼 거창하지는 않지만 버튼, 트리 등의 스윙 컴포넌트를 자신의 입맛에 맞도록 예쁘게 꾸며보도록 하자.


1.“Look & Feel” ?

혹시라도 “Look & Feel”이 무엇인지 모르는 분을 위해 JDK 설치 디렉토리 아래에서 볼 수 있는 SwingSet 예제를 잠깐 살펴보자.





위의 예제에서 여러 가지 컴포넌트들을 둘러보고 이제는 메뉴에서 “Look & Feel” 을 선택하여 “Motif Look & Feel” 을 선택해보자. 순식간에 아래 그림처럼 모든 컴포넌트들이 변해버린다.





기본적인 컴포넌트의 골격은 변경되지 않지만 색상이나 폰트들이 모두 변경되었다.
이런 기능을 위해서는 스윙 컴포넌트 모델을 이해하고 적절한 상위 클래스를 상속받아 구현하거나 각각의 컴포넌트들의 속성을 지정해야 한다. 만약 여러분에게 버튼의 폰트와 색상만 변경하라고 하면 어떻게 할 것인가? 이런 경우에는 당연히 “Look & Feel”을 사용할 필요가 없을 것이다. 호미로 충분할 것을 불도우저를 동원할 필요가 없듯이… 그런데 여기서 궁금한 것은 과연 이렇게 컴포넌트들의 속성과 기본 값을 어떻게 지정되어 있는지 궁금하지 않은가? 그 궁금증을 풀기 위해 아래 예제를 살펴보자. 소스 코드는 아주 간단하여 따로 설명이 필요 없다.


import javax.swing.*;
import java.util.*;
import java.io.*;

// http://www.devx.com/tips/Tip/13176

public class SwingProperties {

  public static void main(String[] args) {
    String lineSep = "\n";
    UIDefaults uid = UIManager.getDefaults();
    Enumeration uidKeys = uid.keys();
    BufferedWriter buff = null;
    FileWriter fr = null;

    try {
      // 프로퍼티를 읽어서 파일로 저장할 것이다
      fr = new java.io.FileWriter("swing_defaults.txt", true);
      buff = new java.io.BufferedWriter(fr);

      // 각각의 프로퍼티에 대해 값을 얻어온다
      while (uidKeys.hasMoreElements()) {
        Object aKey = uidKeys.nextElement();
        Object aValue = uid.get(aKey);
        String str = aKey + "\t = \t" + aValue + lineSep;
        buff.write(str);
      }
    } catch (IOException ioe) {
    } finally {
      try {
        buff.flush();
        buff.close();
        fr.close();
      } catch (Exception e) {
      }
    }

  }

}


위 예제는 소스 코드 안에 주석으로 되어 있는 링크의 예제를 살짝 변경한 것이다.
결과는 실행 후에 swing_defaults.txt 파일을 열어서 확인하자. 파일의 내용은 모든 스윙 컴포넌트의 속성에 대한 키와 값들이다. 다음 예제에서부터 이 값들의 일부를 변경하여 스윙 컴포넌트를 예쁘게 꾸며보도록 하자.


2. MyButton, MyLabel

우선 아래 그림은 예제를 실행 후의 화면이다. 상단에 버튼이 하나 있고 하단에는 라벨이 보인다. 눈썰미 있는 분들은 벌써 감이 오겠지만 굴림 폰트가 사용되고 이탤릭체에 사이즈도 훨씬 크다. 아래의 라벨의 텍스트는 두 줄로 되어 있으며 아래 줄은 언더라인 효과까지 보인다. 그리고 버튼의 툴팁은 바탕색이 노란색이다.





아래 소스 코드를 보면 어떻게 이런 컴포넌트가 만들어 지는지 쉽게 알 수 있다. 눈여겨 볼 것은 initSwingProperties 메소드이다. 이 메소드에서 UIManager에 폰트와 색상을 프로퍼티로 설정하는 것이다. 그리고 컴포넌트를 생성하면 설정된 프로퍼티에 의해 스윙 컴포넌트가 보여진다. 이 메소드를 호출하기 전에 컴포넌트를 생성하면 새로 지정한 프로퍼티의 효과가 없는 컴포넌트가 생성되므로 간단하게 사용 할 수 있다. 라벨에서 setText 메소드를 사용할때 파라미터는 HTML이 사용 가능하고 두 줄로 보이며 언더라인까지 표현이 된다.


import javax.swing.*;
import java.awt.*;

public class MyButton extends JFrame {

  Font gulimItalicFont = new Font("굴림", Font.ITALIC, 20);

  GridLayout gridLayout1 = new GridLayout();
  JButton myButton;
  JLabel myLabel;

  public MyButton() {
    initSwingProperties();
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    setSize(300,300);
    setVisible(true);
  }

  private void initSwingProperties() {
    UIDefaults defaults = UIManager.getDefaults();
    defaults.put("Button.font", gulimItalicFont);
    defaults.put("Label.font", gulimItalicFont);
    defaults.put("ToolTip.background", Color.yellow);
  }

  public static void main(String[] args) {
    MyButton myButton1 = new MyButton();
  }
  
  private void jbInit() throws Exception {
    myButton = new JButton();
    myLabel = new JLabel();
    this.getContentPane().setLayout(gridLayout1);
    gridLayout1.setColumns(1);
    gridLayout1.setRows(2);
    myButton.setToolTipText("My ToolTip");
    myButton.setText("My Button");
    myLabel.setHorizontalAlignment(SwingConstants.CENTER);
    myLabel.setText("My
Label");
    this.getContentPane().add(myButton, null);
    this.getContentPane().add(myLabel, null);
  }

}



3. MyFileChooser

이번에 보여줄 예제는 FileChooser 이다. 일단 프로퍼티를 지정하기 전과 후의 모습을 비교해서 보도록 하자. 실행을 하면 프레임에 Open 이라는 버튼이 있는데 버튼을 누르면 FileChooser 가 나타난다.





그림을 비교해보면 대부분의 폰트가 볼드가 아닌 플레인이며 툴팁의 내용도 한글이 아닌 영문으로 변경되었다. 어떻게 된 것인지 소스 코드를 살펴보자. 이 예제에서도 initSwingProperties 메소드만 중점적으로 보면 된다. 이 메소드 안에서 폰트를 변경하고 툴팁을 다시 설정하고 있는 것이다.


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MyFileChooser extends JFrame {

  Font gulimBoldFont = new Font("굴림", Font.PLAIN, 14);
  Font gulimItalicFont = new Font("굴림", Font.ITALIC, 18);
  Font batangFont = new Font("바탕", Font.PLAIN, 16);
  JPanel jPanel1 = new JPanel();
  JButton openButton = new JButton();

  public MyFileChooser() {
    initSwingProperties();
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    setSize(300,300);
    setVisible(true);
  }

  private void initSwingProperties() {
    UIDefaults defaults = UIManager.getDefaults();
    defaults.put("List.font", gulimBoldFont);
    defaults.put("Label.font", batangFont);
    defaults.put("ComboBox.font", batangFont);
    defaults.put("FileChooser.font", batangFont);
    defaults.put("FileChooser.openButtonToolTipText", "Open");
    defaults.put("FileChooser.saveButtonToolTipText", "Save");
    defaults.put("FileChooser.cancelButtonToolTipText", "Cancel");
    defaults.put("FileChooser.helpButtonToolTipText", "Help");
    defaults.put("FileChooser.updateButtonToolTipText", "Update");
  }

  private void jbInit() throws Exception {
    openButton.setText("Open");
    openButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        openButton_actionPerformed(e);
      }
    });
    this.getContentPane().add(jPanel1, BorderLayout.NORTH);
    jPanel1.add(openButton, null);
  }

  void openButton_actionPerformed(ActionEvent e) {
    JFileChooser chooser = new JFileChooser();
    int returnVal = chooser.showSaveDialog(this);
  }

  public static void main(String[] args) {
    MyFileChooser test = new MyFileChooser();
  }

}



4. MyScrollBar

웹 서핑을 하다 보면 특정 사이트에서 내용을 볼 때 스크롤바의 색상이 변경 되는 경험을 할 수 있다. 자바에서도 아래 그림처럼 할 수 있다 ^^.





아래 소스 코드를 보면 initSwingProperties 메소드에서 스크롤바의 막대 색상은 붉은 색으로, 가로 넓이는 기본값보다 더 넓게 지정하고 있다.


import javax.swing.*;
import java.awt.*;

public class MyScrollBar extends JFrame {
  JScrollPane jScrollPane1;
  JTextArea jTextArea1;

  public MyScrollBar() {
    initSwingProperties();
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void initSwingProperties() {
    UIDefaults defaults = UIManager.getDefaults();
    defaults.put("ScrollBar.thumb", Color.red);
    defaults.put("ScrollBar.width", new Integer("30"));
  }

  public static void main(String[] args) {
    MyScrollBar test = new MyScrollBar();
    test.setSize(100,100);
    test.setVisible(true);
  }
  private void jbInit() throws Exception {
    jScrollPane1 = new JScrollPane();
    jTextArea1 = new JTextArea();
    jScrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    jScrollPane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    this.setForeground(Color.red);
    this.getContentPane().add(jScrollPane1, BorderLayout.CENTER);
    jScrollPane1.getViewport().add(jTextArea1, null);
  }

}



5. MyTree

앞서 소개된 예제들에서는 프로퍼티를 지정하는 방식이었으나 이번에 보여줄 트리 예제는 조금 다른 방식을 사용한다. 트리에서 특정 노드만 다른 폰트를 사용하고 싶을 때 렌더러를 이용할 수 있는 방법을 보여주겠다.





위 그림에서 “node02”만 폰트 크기가 작고 이탤릭체로 되어 있다. 아래 소스 코드를 보면 렌더러에서 특정 노드인지 검사하여 새로운 폰트로 지정하면 위의 그림처럼 보여지게 된다.


import javax.swing.*;
import java.awt.*;
import javax.swing.tree.*;

public class MyTree extends JFrame {

  Font gulim_20 = new Font("굴림", Font.PLAIN, 20);
  Font gulim_italic_16 = new Font("굴림", Font.ITALIC, 16);

  JScrollPane scrollPane;
  JTree tree;

  public MyTree() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    MyTree test = new MyTree();
  }
  private void jbInit() throws Exception {
    DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("ROOT", true);
    DefaultTreeModel treeModel = new DefaultTreeModel(rootNode);
    DefaultMutableTreeNode node01 = new DefaultMutableTreeNode("node01");
    DefaultMutableTreeNode node02 = new DefaultMutableTreeNode("node02");
    DefaultMutableTreeNode node03 = new DefaultMutableTreeNode("node03");
    rootNode.add(node01);
    node01.add(node02);
    node02.add(node03);
    tree = new JTree(treeModel);
    tree.setCellRenderer(new MyTreeRenderer());
    JScrollPane scrollPane = new JScrollPane(tree);
    getContentPane().add(scrollPane,  BorderLayout.CENTER);
    scrollPane.getViewport().add(tree, null);
    setSize(300,300);
    setVisible(true);
  }

  class MyTreeRenderer extends DefaultTreeCellRenderer {

    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
      super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
      setFont(gulim_20);
      DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value;
      Object obj = treeNode.getUserObject();

      // 특정 노드만 다른 폰트를 사용하도록
      if (obj.toString().equals("node02")) {
        this.setFont(gulim_italic_16);
      }

      return MyTreeRenderer.this;
    }

  } // MyTreeRenderer

}



6. 마치면서

앞에서 소개된 예제들을 기반으로 여러분은 자신만의 컴포넌트를 꾸미거나 더 나아가서 새로운 “Look & Feel”을 만들 수 도 있을 것이다. 외국에는 부지런한 개발자들이 다양한 컴포넌트나 “Look & Feel”을 만들어서 공개하는 경우도 있다. 우리도 기본으로 제공되는 컴포넌트가 마음에 들지 않는다고 투정 부리지 말고 직접 예쁘게 꾸며보고 다른 개발자들과 함께 나누는 기쁨을 가져보자.
TAG :
댓글 입력
자료실

최근 본 상품0