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

한빛출판네트워크

IT/모바일

자바 스윙: 메뉴와 툴바 - 제 1편

한빛미디어

|

2003-03-12

|

by HANBIT

18,056

저자: Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole, 역 한빛리포터 이상화

본 기사는 『Java Swing, 2nd Edition』에서 메뉴와 툴바에 대한 내용을 다룬 챕터를 요약한 기사이다. 이 내용을 통해 스윙 메뉴에 대한 설명을 시작하겠다.

본 기사에서는 스윙 메뉴와 툴바에 관해 논의하고 있다. 툴바에 비해 메뉴가 더욱 풍부한 기능과 유연성을 가지고 있다. 따라서 본 기사에서는 메뉴에 더 많은 지면을 할애 하였다. 특히 메뉴와 툴바는 새로운 애플리케이션을 배울 때 훌륭한 시작점이 되어줄 수 있으며, 특히 스윙은 메뉴 레이아웃 배치에 있어서 풍부한 기능을 제공하고 있다.

툴바는 버튼, 콤보 박스, 재이동이 가능한 패널에 포함되어있는 다른 요소들을 그룹화 할 수 있다. 이와 같은 특수한 작업뿐만 아니라 기타 다양한 일반 작업도 가능하다. 스윙 툴바에는 어떤 컴포넌트도 추가할 수 있을 뿐만 아니라 스윙 콤포넌트가 아닌 것도 추가 가능하다. 덧붙여 스윙은 프레임으로부터 툴바를 드래그하여 편리하게 작은 창으로 분리되게 한다.


Java Swing, 2nd Edition

참고 도서

Java Swing, 2nd Edition
David Wood, Marc Loy, James Elliott, Brian Cole, Robert Eckstein


스윙 메뉴 소개

스윙 메뉴 컴포넌트는 Jcomponent의 서브 클래스이다. 따라서 메뉴 컴포넌트는 스윙 컴포넌트의 모든 장점을 가지고 있고 레이아웃 메니저와 컨테이너라는 관점을 가지고 메뉴 컴포넌트에 접근할 수 있다.

스윙 메뉴 시스템의 특징 중에서 주목 할만한 것들은 아래과 같다.
  • 아이콘이 메뉴 아이템으로 사용되거나 대체될 수 있다
  • 라디오 버튼도 메뉴 아이템이 될 수 있다
  • 키보드 단축키가 메뉴아이템에 할당되거나 메뉴 아이템 문자 옆에 표시된다
  • 대부분의 표준 스윙 컴포넌트는 메뉴 아이템으로 사용될 수 있다
스윙은 메뉴 분리자, 체크박스 메뉴 아이템, 팜 업 메뉴, 서브메뉴를 제공한다. 또한 스윙메뉴는 키보드 단축키를 지원하며 밑줄이 있는 단축키를(역주 : 예를 들어 파일(F)/FILE) 지원한다. 게다가 스윙은 프레임 상단의 프레임 삽입위치에 따라 자동적으로 변경되는 메뉴바를 붙일 수 있다. 매킨도시에서 이러한 작동을 하려면 애플리케이션에서 설정이 되어 있어야 한다. 아래 [그림 14-1]은 스윙에서 다양한 요소를 갖고 있는 메뉴 시스템을 정의하고 있다.


[그림 14-1] 스윙 메뉴 시스템의 요소들

모든 플랫폼이 밑줄이 있는 단축키를 지원하는 것은 아니다. 매킨토시는 이러한 단축키를 지원하지 않으며 설사 실제 메뉴에서 이러한 밑줄이 보인다 하더라도 동작하지는 않는다. 만약 이러한 밑줄이 있는 단축키를 사용하려면 단축키를 지원하는 플랫폼에서만 사용될 수 있도록 코드를 그룹화 하여 별개의 메소드를 고려하는 것이 좋다.

모든 플랫폼이 단축키(†역자 주: Ctrl-C와 같은 기능)를 지원하지만 이러한 기능을 사용하기 위한 방법은 각기 다르다. Toolkit 메소드와 getMenuShortcutKeyMask를 이용하는 것이 좋은 방법이다.

메뉴 계층

스윙 메뉴의 클래스 다이어그램은 아래 [그림 14-2]와 같다.


[그림 14-2] 스윙 메뉴 다이어그램

AbstractButton을 보고 의외라고 생각할 수도 있지만 메뉴와 메뉴 아이템은 스윙 버튼과 많은 공통점을 가지고 있다. 예를 들어 메뉴아이템은 마우스가 메뉴 위에 있을 때 반전될 수 있으며 사용자가 선택하여 클릭할 수도 있다. 또한 버튼처럼 비활성화 되거나 없어지기도 하며 이벤트 처리하는 명령을 메뉴에 할당할 수도 있다. JCheckBoxMenuItemJradioButtonMenuItem는 두 개의 상태 사이에서 토글되어 질 수 있다. 스윙 메뉴 컴포넌트가 스윙 버튼의 많은 기능들을 공유하고 있기 때문에 AbstractButton에서 상속을 받는 것이 효율적이다.

또한 JmenuJmenuItem으로부터 상속 받는 것도 의아하게 생각할 수 있겠지만 이것은 Jmenu가 메뉴의 타이틀을 제공하는 암시적인 메뉴를 포함하고 있기 때문이다. 이후 이런 메뉴의 일부분은 타이틀 버튼(†역자 주: 메뉴를 형성하는 큰 범주, 파일(F) 편집(E)…)이라 불리게 되는데 이것을 마우스로 드래그 하거나 누르게 되면 이에 대응하는 메뉴가 나타난다. 여기에서 주의할 점은 이 메뉴가 메뉴바에 고정되지 않는다는 것이다. 서브메뉴처럼 작동하는 곳에 삽입할 수도 있다. 이것은 계층 구조에서 보듯이(†역자 주: JmenuJmenuItem을 상속 받는 것) 타이틀 버튼이 메뉴 아이템처럼 작동해야 하는 것을 의미한다. 좀더 자세한 작동방법은 이후 Jmenu 클래스를 얘기할 때 논의하겠다.

거의 모든 메뉴 클래스가 상속 받고 있는 MenuElement 인터페이스는 키보드/마우스 이벤트와 같은 사용자 입력이 발생했을 때 스윙 메뉴 컴포넌트가 어떠한 반응을 보여야 하는 표준적인 메소드에 대한 윤곽을 그려준다. 스윙 메뉴 클래스는 전형적으로 키보드/마우스 이벤트를 처리해서 컴포넌트 대리자에게 통지해준다. 이때 컴포넌트 대리자는 컴포넌트가 필요에따라 재작성된다고 하더라도 처리가 된다. 메소드들은 MenuSelectionManager와 동시에 작동하게 되며 MenuElement 인터페이스를 자주 상속 받지 않아도 작동 방법을 이해할 수 있을 것이다. 어떻게 상속하는지는 다음 장에서 보여주겠다.

좀더 자세히

기본적인 스윙 메뉴를 소개하기 위해 간단한 프로그램을 살펴보자.
// IntroExample.java
//

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

public class IntroExample extends JMenuBar {

   String[ ] fileItems = new String[ ] { "New", "Open", "Save", "Exit" };
   String[ ] editItems = new String[ ] { "Undo", "Cut", "Copy", "Paste" };
   char[ ] fileShortcuts = { "N","O","S","X" };
   char[ ] editShortcuts = { "Z","X","C","V" };

   public IntroExample(  ) {

      JMenu fileMenu = new JMenu("File");
      JMenu editMenu = new JMenu("Edit");
      JMenu otherMenu = new JMenu("Other");
      JMenu subMenu = new JMenu("SubMenu");
      JMenu subMenu2 = new JMenu("SubMenu2");

      // 밑줄 단축키가 있는 파일 메뉴 생성
	
      ActionListener printListener = new ActionListener(  ) {
         public void actionPerformed(ActionEvent event) {
            System.out.println("Menu item [" + event.getActionCommand(  ) +
                               "] was pressed.");
         }
      };
      for (int i=0; i < fileItems.length; i++) {
         JMenuItem item = new JMenuItem(fileItems[i], fileShortcuts[i]);
         item.addActionListener(printListener);
         fileMenu.add(item);
      }

      // 일반 단축키가 있는 파일 메뉴 생성
      for (int i=0; i < editItems.length; i++) {
         JMenuItem item = new JMenuItem(editItems[i]);
         item.setAccelerator(KeyStroke.getKeyStroke(editShortcuts[i],
              Toolkit.getDefaultToolkit(  ).getMenuShortcutKeyMask(  ), false));
         item.addActionListener(printListener);
         editMenu.add(item);
      }

      // Insert a separator in the Edit menu in Position 1 after "Undo".
      editMenu.insertSeparator(1);

      // 다른 메뉴의 서브 클래스 생성
      JMenuItem item;
      subMenu2.add(item = new JMenuItem("Extra 2"));
      item.addActionListener(printListener);
      subMenu.add(item = new JMenuItem("Extra 1"));
      item.addActionListener(printListener);
      subMenu.add(subMenu2);

      // 메뉴 자신을 생성
      otherMenu.add(subMenu);
      otherMenu.add(item = new JCheckBoxMenuItem("Check Me"));
      item.addActionListener(printListener);
      otherMenu.addSeparator(  );
      ButtonGroup buttonGroup = new ButtonGroup(  );
      otherMenu.add(item = new JRadioButtonMenuItem("Radio 1"));
      item.addActionListener(printListener);
      buttonGroup.add(item);
      otherMenu.add(item = new JRadioButtonMenuItem("Radio 2"));
      item.addActionListener(printListener);
      buttonGroup.add(item);
      otherMenu.addSeparator(  );
      otherMenu.add(item = new JMenuItem("Potted Plant", 
                           new ImageIcon("image.gif")));
      item.addActionListener(printListener);

      // 마지막으로 메뉴바에 모든 메뉴 삽입
      add(fileMenu);
      add(editMenu);
      add(otherMenu);
   }

   public static void main(String s[ ]) {
      JFrame frame = new JFrame("Simple Menu Example");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setJMenuBar(new IntroExample(  ));
      frame.pack(  );
      frame.setVisible(true);
   }
}
이 예제는 세 개의 단순한 메뉴를 포함하고 있는 메뉴바를 생성하며 File 메뉴는 밑줄이 있는 단축키로 만들고 Edit 메뉴는 일반 단축키를 포함시킨다. [그림 14-3]은 프로그램이 가지고 있는 모든 메뉴를 보여주고 있으며 서로 다른 플랫폼에서 Edit 메뉴의 단축키가 어떻게 나타나는지 보여주고 있다.


[그림 14-3] 스윙 메뉴 효과 예제

세 번째 메뉴에서 GIF 이미지를 가지고 마지막 아이템을 만들어 보았다. 덧붙여 Other 메뉴에 포함되어 있는 첫번째 메뉴 아이템(SubMenu)은 실제로 서브 메뉴를 가지고 있는 서브 메뉴이다. 이것은 메뉴의 재귀적인 성격을 나타낸다. 실제로 메뉴를 선택하면 도스 콘솔 창에 메뉴 선택에 대한 간단한 텍스트가 출력된다.
Menu item [New] was pressed.
Menu item [Radio 1] was pressed.
본 기사에서 보여준 클래스와 메소드를 일일이 이해하지 못했다고 자책할 필요는 없다. 단지 각 메뉴에 대해서 짧게 설명했을 뿐이다.

다음 기사에서는 메뉴바 선택 모델을 살펴볼 것이다.
TAG :
댓글 입력
자료실

최근 본 상품0