그래픽 사용자 인터페이스와 사건처리
그래픽 사용자 인터페이스 그래픽 사용자 인터페이스(GUI)는 사람과 컴퓨터간의 상호작용을 위한 사람-컴퓨터 인터페이스(HCI)중의 하나이다 GUI는 사용자가 컴퓨터 화면 상에 있는 객체들과 상호작용을 하는 인터페이스이다 오늘날 사실상 거의 모든 컴퓨터 플랫폼에서 GUI가 사용되고 있다
GUI 프로그래밍 GUI 프로그램은 실행시키면 메뉴가 있는 창이 뜨고 창에는 아이콘, 단추, 제어 요소 등이 있다 입력은 마우스나 키보드를 통해 하고 출력은 화면을 통해 본다 이러한 프로그램을 작성하는 것이 GUI 프로그래밍이다 자바에서 GUI 프로그래밍을 지원하기 위해 모든 플랫폼에서 공통적으로 제공하는 최소한의 기능만을 지원하는 GUI 도구 모음을 제공한다
자바의 GUI 지원 도구 모음 GUI 응용을 지원하기 위한 클래스들은 주로 java.awt 패키지와 javax.swing 패키지에 있다 java.awt 패키지는 추상 윈도우 도구 모음(AWT)을 포함하는 최초의 자바 GUI 패키지이다 스윙 패키지는 AWT의 컴포넌트들보다 더 융통성이 있는 컴포넌트들을 포함한다 GUI 프로그램을 작성하기 위해서는 AWT 패키지와 스윙 패키지 둘 다 필요로 한다
스윙 스윙은 플랫폼 고유의 컴포넌트와 연계되지 않은 경량급의 빠른 컴포넌트들로 구성된 GUI 도구 모음이다 모든 새로운 스윙 컴포넌트들과 클래스들은 javax.swing 패키지에 정의되어 있다 스윙을 프로그램에서 사용하기 위해서는 다음과 같은 import 문을 사용해야 한다: import javax.swing.*;
스윙의 기본 구성 요소 컴포넌트: 정보를 화면에 보여 주거나 사용자가 프로그램과 어떤 방식으로 상호작용하게 하는 화면상의 요소이다 예: 단추, 레이블, 텍스트 필드 컨테이너: 다른 컴포넌트들을 포함하는 특별한 유형의 컴포넌트이다 예: 프레임, 패널 화면 구성 관리자: 컨테이너 내에서 컴포넌트의 위치를 결정한다
컨테이너 다른 컴포넌트들을 포함하고 조직하는 특별한 유형의 컴포넌트이다 컨테이너는 중량급 혹은 경량급으로 분류될 수 있다 중량급 컨테이너는 운영체제에 의해 관리된다 예: 프레임 반면에 경량급 컨테이너는 자바 프로그램에 의해 관리된다 예: 패널
프레임 프레임은 GUI 기반 자바 응용을 보여주기 위해 사용되는 컨테이너이다 프레임은 제목 막대를 가진 별도의 창으로 보여 진다. 화면상에서 위치를 바꿀 수 있고 크기를 조절할 수 있다
패널 패널은 보여 지기 위해서 또 다른 컨테이너에 더해 져야 한다 패널의 주요 역활은 GUI 안에 있는 다른 컴포넌트들을 구성하는 것을 돕는 것이다 패널에 컴포넌트들을 추가하기 위해 우리는 add() 메소드를 사용한다
예제 프로그램 1: 프레임 만들기 import java.awt.*; import javax.swing.*; public class JFrameDemo { public static void main(String[] args) { JFrame frame = new JFrame("JFrame Demo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 패널을 만든다 JPanel panel = new JPanel(); panel.setBackground(Color.green); panel.setPreferredSize(new Dimension(200, 100)); // 프레임을 보여 준다 frame.getContentPane().add(panel); frame.pack(); frame.setVisible(true); } }
예제 프로그램 1: 실행 결과
컴포넌트 스윙 컴포넌트들은 AWT 컴포넌트들의 기능을 향상한 것이거나 새로이 추가된 것이다 스윙 컴포넌트들은 그래픽스를 지원한다 모든 스윙 컴포넌트는 paintComponent 메소드를 가진다 예: 레이블, 단추, 텍스트 필드, 체크박스
사건 사건은 우리가 관심을 가질지 모르는 어떤 일의 발생을 나타내는 객체이다 예를 들면, 다음이 일어날 때 프로그램이 어떤 일을 수행해야 하는 경우: 1. 마우스를 움직인다 2. 단추가 눌러진다 3. 키보드의 키를 누른다 4. 마우스를 클릭한다
사건 사건은 컴포넌트에서 사용자나 시스템에 의하여 발생하는 일이다 자바는 사건을 나타내는 많은 사건 클래스를 제공한다 사건 소스(Event Source)는 사건이 발생되는 진원지이다. 사건 소스는 보통 컴포넌트이다. 사건 리스너는 사건이 일어나기를 기다리다가 사건이 발생하면 대응하는 객체이다 사건 리스너는 대응하는 컴포넌트와의 밀접한 관계 때문에 자주 내부 클래스로 정의된다 사건 처리를 위해서는 사건이 발생되는 컴포넌트에서 사건 리스너를 등록해야 한다
사건 처리 방법 사건 처리기의 역할을 담당하는 사건에 대한 처리 메소드를 갖는 사건 리스너(Event Listener)를 제공한다 이 사건 리스너는 각각의 사건 처리를 위한 메소드를 갖는 인터페이스 유형이다 사건이 발생되는 사건 소스에 사건 리스너를 등록해야 한다 예: Button button = new JButton("Test"); button.addActionListener(new ButtonHandler()); 사건 처리를 위임받은 사건 리스너에서 사건을 처리한다
사건이 발생할 때 컴포넌트는 리스너의 적절한 메소드를 호출한다 사건과 리스너 사건 컴포넌트 컴포넌트 객체는 사건을 발생시킬 수 있다 사건 리스너 대응하는 리스너 객체는 사건을 처리한다 사건이 발생할 때 컴포넌트는 리스너의 적절한 메소드를 호출한다 이 때 사건을 기술하는 객체를 넘겨 준다
사건 처리 구조 loop 사용자 사건을 얻는다 사용자 사건을 처리한다 사건에 반응하여 일을 처리한다 endloop
대화식 GUI 프로그램 작성 대화식 GUI 프로그램을 작성하기 위해서 최소한 세 가지 종류의 객체들이 필요하다: 컴포넌트들 컴포넌트들 사건들 사건 리스너들
GUI 프로그램 작성 필요한 컴포넌트들과 객체를 만들고 초기화 한다 특정 사건들이 발생할 때 일어나는 것을 정의하는 리스너 클래스들을 구현한다 관심 있는 사건들을 발생시키는 컴포넌트들과 사건 리스너들 사이의 관계를 설정한다
레이블 레이블(label)은 한 줄의 텍스트를 보여주는 GUI 컴포넌트이다 레이블은 JLabel 클래스에 의해 정의된다 레이블은 이미지를 보여 줄 수 있다
예제 프로그램 2: 레이블 실행 결과 import java.awt.*; import javax.swing.*; public class Caesar { public static void main (String[] args) { JFrame frame = new JFrame (“Caesar"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); JPanel primary = new JPanel(); primary.setBackground (Color.yellow); primary.setPreferredSize (new Dimension(180, 75)); JLabel label1 = new JLabel (“왔노라, 보았노라, 이겼노라"); JLabel label2 = new JLabel (“-- 시저"); primary.add (label1); primary.add (label2); frame.getContentPane().add(primary); frame.pack(); frame.setVisible(true); } 실행 결과
단추 단추(button)는 사용자가 마우스의 누름으로 동작을 시작하는 컴포넌트이다 단추는 JButton 클래스에 의해 정의된다 단추는 눌러질 때 Action Event를 발생시킨다 다음 프로그램은 단추들의 작동을 시험한다
예제 프로그램 3: 단추 시험 // 그래픽 사용자 인터페이스와 사건 리스너의 사용을 보여 준다 // 그래픽 사용자 인터페이스와 사건 리스너의 사용을 보여 준다 import javax.swing.JFrame; public class ButtonDemo { // 주 프레임을 만들어 보여 준다 public static void main (String[] args) { JFrame frame = new JFrame ("단추 시험"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new ButtonPanel()); frame.pack(); frame.setVisible(true); } }
예제 프로그램 3: ButtonPanel // 두 개의 단추들과 하나의 레이블을 포함하는 패널을 생성한다 // 두 개의 단추들과 하나의 레이블을 포함하는 패널을 생성한다 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ButtonPanel extends JPanel { private JButton ok, cancel; private JLabel outputlabel; public ButtonPanel () { // 생성자 메소드: GUI를 설정한다 ok = new JButton ("확인"); ok.addActionListener (new ButtonListener()); cancel = new JButton ("취소"); cancel.addActionListener (new ButtonListener()); outputlabel = new JLabel (""); add (ok); add(cancel); add (outputlabel); setPreferredSize (new Dimension(200, 100)); setBackground (Color.cyan); }
예제 프로그램 3: ButtonPanel (cont.) // 단추 누름 사건들에 대한 리스너를 나타낸다 private class ButtonListener implements ActionListener { // 단추가 눌러질 때 레이블을 갱신한다 public void actionPerformed (ActionEvent event) { if (event.getSource() == ok) outputlabel.setText("확인 단추가 눌러졌습니다"); else outputlabel.setText("취소 단추가 눌러졌습니다"); } } }
예제 프로그램 3: 실행 결과
예제 프로그램 3: 설명 GUI 컴포넌트들은 두 개의 단추, 메시지를 보여주는 레이블, 컴포넌트들을 구성하기 위한 패널과 패널을 보여주는 프레임으로 구성된다 프레임은 ButtonDemo 클래스에 의해 정의된다 패널은 ButtonPanel 클래스에 의해 정의된다 ButtonPanel 생성자 메소드가 GUI 요소들을 설정한다
예제 프로그램 3: 설명 ButtonListener 클래스는 단추에 의해 발생되는 Action 사건에 대한 리스너이다 이 클래스는 ButtonPanel 클래스에 의해서만 사용되므로 ButtonPanel 클래스의 내부 클래스로 정의한다 단추가 일으키는 Action 사건을 처리하는 Action 리스너는 ActionListener 인터페이스를 구현함으로서 만들어진다 ButtonListener 클래스는 ActionListener 인터페이스에 있는 유일한 메소드인 actionPerformed 메소드를 구현한다
예제 프로그램 3: 설명 ButtonPanel 생성자 메소드는 다음을 수행한다: ButtonListener 객체를 생성한다 addActionListener 메소드를 호출하여 단추와 리스너사이의 관계를 설정한다 사용자가 단추를 누를 때 단추는 Action 사건 객체를 발생시키고 ButtonListener의 actionPerformed 메소드를 호출한다 이 메소드는 어느 단추가 눌러졌는지를 확인하여 레이블의 텍스트를 변경한다
텍스트 필드 텍스트 필드(text field)는 사용자가 한 줄의 입력을 하는 것을 허락하는 컴포넌트이다 텍스트 필드는 JTextField에 의해 정의된다 커서가 텍스트 필드 안에 있을 때 Enter 키를 누르면 Action Event을 발생시킨다 다음 프로그램은 텍스트 필드의 작동을 시험한다
예제 프로그램 4: 환전 import javax.swing.JFrame; public class MoneyExchange { // 환전기 GUI를 만들고 보여 준다 public static void main (String[] args) { JFrame frame = new JFrame ("환전기"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); MoneyExchangePanel panel = new MoneyExchangePanel(); frame.getContentPane().add(panel); frame.pack(); frame.setVisible(true); } }
예제 프로그램 4: 환전 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MoneyExchangePanel extends JPanel { private JLabel inputLabel, outputLabel, resultLabel; private JTextField money; // 생성자 메소드: GUI를 설정한다 public MoneyExchangePanel() { inputLabel = new JLabel ("환전금액(원화)을 입력하세요:"); outputLabel = new JLabel ("환전받는 금액(달러화): $"); resultLabel = new JLabel ("---"); money = new JTextField (10); money.addActionListener (new MoneyListener()); add (inputLabel); add (money); add (outputLabel); add (resultLabel); setPreferredSize (new Dimension(300, 80)); setBackground (Color.green); }
예제 프로그램 4: 환전 // 텍스트 필드에 대한 사건 리스너를 나타낸다 // 텍스트 필드에 대한 사건 리스너를 나타낸다 private class MoneyListener implements ActionListener { // 텍스트 필드에 Enter 키가 눌러질때 환전 금액을 계산한다 public void actionPerformed (ActionEvent event) { int won, dollar; String text = money.getText(); won = Integer.parseInt (text); dollar = won / 1100; resultLabel.setText (Integer.toString (dollar)); } } }
예제 프로그램 4: 실행 결과
예제 프로그램 4: 설명 GUI는 MoneyExchangePanel 클래스에 정의된다 MoneyListener 내부 클래스는 텍스트필드에 의해 발생되는 Action 사건에 대한 리스너를 정의한다 MoneyExchangePanel의 생성자 메소드는 리스너 객체를 만들고 그것을 텍스트 필드에 추가한다 사용자가 환전 금액을 입력하고 Enter 키가 눌러질 때 Action 사건 객체를 발생시키고 MoneyListener의 actionPerformed 메소드를 호출한다 이 메소드는 환전받는 금액을 계산하여 결과 값을 레이블에 보여 준다
체크박스 체크박스는 마우스를 사용하여 ON이나 OFF 상태중의 하나를 선택하게 하 는 단추이다 체크박스는 JCheckBox 클래스에 의해 정의된다 체크박스는 상태가 바뀔 때마다 Item Event가 발생된다
라디오 단추 라디오 단추는 한번에 한 단추만 선택될 수 있는 단추들의 그룹이다 한 그룹에서 한 라디오 단추가 선택될 때 현재 ON 상태에 있는 라디오 단추는 OFF 상태로 바뀐다 함께 동작할 라디오 단추들의 그룹을 정의하기 위해 각 라디오 단추는 ButtonGroup 객체에 더해진다 라디오 단추는 JRadioButton 클래스에 의해 정의된다 라디오 단추는 Action 사건을 일으킨다
요약 그래픽 사용자 인터페이스 개요 스윙 컨테이너 컴포넌트 사건 처리 예제 프로그램