IBM Korea Skip to main content
       IBM 홈    |  제품 & 서비스  |  고객지원 & 다운로드  |  회원가입  

Magic with Merlin: 오디오 스윙(Swing)
목 차:
소리(Auditory)의 기초
예제
참고자료
필자소개
기사에 대한 평가
관련 dW 링크:
Build a better GUI
Tutorial: JMF basics
Enterprise Media Beans (from alphaWorks)
Subscribe to the developerWorks newsletter
US 원문 읽기
Also in the Java zone:
Tutorials
Tools and products
Code and components
Articles
사용자 인터페이스 향상을 위한 소리 신호 구현하기

John Zukowski
President, JZ Ventures, Inc.
2002년 7월

Column iconSwing 아키텍쳐는 개발자들이 원시 UI를 모방하는 자바 애플리케이션용 유저 인터페이스를 만드는 수단을 제공했다. Java 2 Platform, Standard Edition은 이 아이디어를 적용하여 UI 작동과 피드백 사운드를 조합하는 메커니즘으로 개념을 발전시켰다.

J2SE version 1.4에는 새롭고 재미있는 Swing 기능이 있어 눈길을 끈다. Swing 제어는 특정 이벤트에 대한 응답으로 소리 피드백을 제공할 수 있다. 하지만 이 기능은 디폴트 상태에서는 사용할 수 없다. 추가된 기능 덕택에 Swing 제어가 시스템의 원시 운영 체제를 잘 모방할 수 있도록 한다.

소리(Auditory)의 기초
Swing은 Pluggable Look-and-Feel (PLAF) 아키텍쳐와 함께 작동한다. 다양한 컴포넌트의 색깔과 폰트를 설정하기위해 코딩을 할 필요가 없다. 대신 컴포넌트는 Interface (UI) Manager로 부터 이 설정들을 요청한다. 개발자들은 UI Manager에게 사용자가 보기 원하는 인터페이스가 무엇인지를 명령할 수 있다; 옵션으로는 Windows, Motif, Metal styles 등이 있다. UI Manager는 각 컴포넌트에게 이들을 어떻게 디스플레이 해야하는지를 명령한다. 버튼 같은 컴포넌트의 경우 전면 색상은 Button.foreground 속성을 설정하여 제어된다:

UIManager.put("Button.foreground", Color.red);

Button.foreground는 사용자 인터페이스 속성 이름이고 Color.red는 특정 설정이다. 설정을 변경한 후에 모든 새로운 버튼은 붉은 색이 된다. (이전에 만들어진 버튼을 변경하는 방법도 있다.)

J2SE 1.4에서 소리 피드백을 비슷한 형태로 실행할 수 있다. UI 속성 이름과 알맞은 설정을 알고있으면 된다. 여기에서 속성은 AuditoryCues.playList이고 설정은 소리 신호에 대한 이름들의 String 어레이 이다. UI Manager는 이러한 이름들을 특정 액션이 발생할 때 작동하는 소리 파일로 매핑한다.

다음은 시스템이 제공하는 룩앤필(look-and-feel)의 사운드 리스트이다. 각각 이름들은 자가 설명적(self-explanatory)이다.

  • CheckBoxMenuItem.commandSound
  • InternalFrame.closeSound
  • InternalFrame.maximizeSound
  • InternalFrame.minimizeSound
  • InternalFrame.restoreDownSound
  • InternalFrame.restoreUpSound
  • MenuItem.commandSound
  • OptionPane.errorSound
  • OptionPane.informationSound
  • OptionPane.questionSound
  • OptionPane.warningSound
  • PopupMenu.popupSound
  • RadioButtonMenuItem.commandSound

AuditoryCues.playList 속성에 제공된 이름들의 String 어레이는 이벤트 이름들의 모음일 뿐이다. 이러한 이름들을 룩앤필이 지정한 사운드로 매핑하는 것은 UI Manager가 할 일이다.

이러한 이름들에서 지원하기 원하는 실제 이벤트 이름의 어레이를 수동으로 조작할 수 있지만 불필요하다. 다행히도 일반적인 사용 그룹을 위한 두 개의 시스템 정의 설정이 있다.

설정은 AuditoryCues.allAuditoryCues 검색 키(look-up key)를 제공하는 데, 이를 사용하여 UI Manager에서 나오는 모든 사운드에 대한 적절한 어레이를 찾을 수 있다. 일단 어레이를 찾으면 UI Manager에 있는 AuditoryCues.playList 키를 사용하여 이를 저장할 수 있다:


  UIManager.put("AuditoryCues.playList",
    UIManager.get("AuditoryCues.allAuditoryCues"));

사용할 수 있는 두 개의 다른 검색 키 값이 있다: AuditoryCues.noAuditoryCues(소리없음)과 AuditoryCues.defaultCueList는 네 개의 OptionPane 설정을 위한 사운드 신호를 작동하고 Metal look-and-feel에 한정되어있다.

AuditoryCues.playList 설정을 변경하면 새로운 오디오 신호를 사용할 수 있다. 특별한 작동이 발생하면 UI Manager는 그 작동과 관계있는 키의 플레이리스트를 검사한다. UI Manager는 로딩하여 실행할 사운드 파일을 찾기위해 그 키를 사용한다. 신호 어레이에 키가 없다면 어떤 소리도 실행되지 않는다.

특정 사운드를 원하지 않으면 신호 이름을 다른 파일로 매핑하여 대체할 수 있다. 예를들어 아래 코드에서 시스템에서 제공하는 에러 사운드 파일로 매핑된 question sound를 보게된다:


  UIManager.put("OptionPane.questionSound", "sounds/OptionPaneError.wav");

이것이 Swing 프로그램에서 사전정의된 액션과 관계 있는 소리 신호를 작동하는 방법이 전부이다.

예제
Listing 1의 프로그램은 원하는 세 개의 신호 설정을 선택할 수 있는 세 개의 라디오 버튼을 나타낸다. 그림 1에서 간단한 사용자 인터페이스를 볼 수 있다.

그림 1. 예제 애플리케이션 인터페이스
Example application interface

팝업 윈도우를 디스플레이하는 두 개의 버튼이 있다. 팝업이 디스플레이 될 때 소리 신호를 발생시킨다.

Listing 1. 소리 예제

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

public class Audio extends JFrame {
  
  public Audio() {
    super("Auditory Popups");
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    UIManager.put("AuditoryCues.playList",
      UIManager.get("AuditoryCues.defaultCueList"));
    UIManager.put("OptionPane.questionSound", 
      "sounds/OptionPaneError.wav");

    JPanel contentPane = (JPanel)this.getContentPane();
    JPanel center = new JPanel();
    ButtonGroup buttonGroup = new ButtonGroup();

    JRadioButton defaultAudio = new JRadioButton("Default", true);
    center.add(defaultAudio);
    buttonGroup.add(defaultAudio);
    defaultAudio.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        UIManager.put("AuditoryCues.playList",
          UIManager.get("AuditoryCues.defaultCueList"));
      }
    });

    JRadioButton offAudio = new JRadioButton("Off", false);
    center.add(offAudio);
    buttonGroup.add(offAudio);
    offAudio.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        UIManager.put("AuditoryCues.playList",
          UIManager.get("AuditoryCues.noAuditoryCues"));
      }
    });

    JRadioButton onAudio = new JRadioButton("On", false);
    center.add(onAudio);
    buttonGroup.add(onAudio);
    onAudio.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        UIManager.put("AuditoryCues.playList",
          UIManager.get("AuditoryCues.allAuditoryCues"));
      }
    });

    contentPane.add(center,  BorderLayout.CENTER);

    JButton confirmButton = new JButton("Confirmation Dialog");
    contentPane.add(confirmButton, BorderLayout.SOUTH);
    confirmButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        int result = JOptionPane.showConfirmDialog(Audio.this, 
          "Confirm?");
        if (result == JOptionPane.YES_OPTION) {
          JOptionPane.showMessageDialog(Audio.this, "Confirmed");
        } else {
          JOptionPane.showMessageDialog(Audio.this, "Rejected");
        }
      }
    });

    JButton messageButton = new JButton("Message Dialog");
    contentPane.add(messageButton, BorderLayout.NORTH);
    messageButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JOptionPane.showMessageDialog(Audio.this, "The Message");
      }
    });
    this.pack();
    show();
  }
  public static void main(String args[]) {
    new Audio();
  }
}

참고자료

필자소개
John ZukowskiJohn Zukowski는 JZ Ventures, Inc. 에서 전략적 자바 컨설팅을 수행하고 있으며 jGuru 커뮤니티에서 운영하는 Java FAQs의 구루(guru)로 활동하고 있다. 저서로는 Mastering Java 2, J2SE 1.4Learn Java with JBuilder 6 등이 있다.
이 기사에 대하여 어떻게 생각하십니까?

정말 좋다 (5) 좋다 (4) 그저그렇다 (3) 수정보완이 필요하다(2) 형편없다 (1)

  회사소개  |  개인정보 보호정책  |  법률  |  문의