Outline 클래스의 해부 캡슐화(Encapsulation) 메쏘드의 해부 그래픽 객체(Graphical Objects) 그래픽 사용자 인터페이스 버튼과 텍스트 필드
그래픽 사용자 인터페이스 자바에서 Graphical User Interface (GUI)는 적어도 세가지 종류의 객체가 필요하다. 컴포넌트(components) 이벤트(events) 감청자(listeners) 3장에서 언급했듯이, GUI 컴포넌트는 정보를 표시하거나 사용자가 특정 방식으로 프로그램과 상호작용할 수 있도록 해주는 스크린의 요소(screen elements )를 정의하는 객체이다. 레이블(labels), 버튼(buttons), 텍스트필드(text fields), 메뉴(menus) 등 어떤 컴포넌트는 다른 컴포넌트를 조직하는데 사용되는 특별한 용도의 컴포넌트이다. 프레임(frames), 패널(panels), 애플릿(applets)
이벤트(Events) 이벤트는 어떤 일이 발생한 것을 나타내는 객체이다. 예를 들어, 아래의 일들이 발생 했을 때 어떠한 행동을 하도록 프로그램하길 원하게 된다. the mouse is moved the mouse is dragged a mouse button is clicked a graphical button is clicked a keyboard key is pressed a timer expires 이벤트는 사용자의 동작과 대응한다. 대부분의 GUI컴포넌트들은 각 컴포넌트에 연계된 사용자 동작을 지시하는 이벤트를 발생시킨다.
이벤트와 감청자(Listeners) 자바의 standard class library는 이벤트를 표현하는 몇 개의 클래스를 포함하고 있다. 예를 들어 버튼 같은 컴포넌트는 이벤트가 발생했을 때 이벤트를 생성된다. 감청자는 이벤트가 일어나기를 기다리고 있다가 이벤트가 발생했을때 대응하는 객체이다. 이벤트가 발생했을때 적절한 동작을 하게하는 리스너객체를 디자인할 수 있다. Event 는 컴포넌트에서 사용자나 시스템에 의하여 발생하는 일이다 자바는 event를 나타내는 많은 이벤트 클래스를 제공한다 사건 소스(Event Source)는 event가 발생되는 진원지이다. event 소스는 보통 컴포넌트이다. event 리스너는 대응하는 컴포넌트와의 밀접한 관계 때문에 자주 내부 클래스로 정의된다 event처리를 위해서는 event가 발생되는 컴포넌트에서 event 리스너를 등록해야 한다
사건이 발생할 때 컴포넌트는 리스너의 적절한 메소드를 호출한다 이벤트와 감청자(Listeners) 이벤트 컴포넌트 컴포넌트 객체는 사건을 발생시킬 수 있다 이벤트 리스너 대응하는 리스너 객체는 사건을 처리한다 사건이 발생할 때 컴포넌트는 리스너의 적절한 메소드를 호출한다 이 때 사건을 기술하는 객체를 넘겨 준다
GUI 개발 일반적으로 자바클래스라이브러리내의 클래스로 미리 정의되어져 있는 컴포넌트와 이벤트를 사용한다. GUI프로그램 작성 필요한 컴포넌트들과 객체를 만들고 초기화 한다 특정 사건들이 발생할 때 일어나는 것을 정의하는 리스너 클래스들을 구현한다 이벤트를 발생시키는 컴포넌트들과 이벤트 리스너들 사이의 관계를 설정한다
Outline 클래스의 해부 캡슐화(Encapsulation) 메쏘드의 해부 그래픽 객체(Graphical Objects) 그래픽 사용자 인터페이스 버튼과 텍스트 필드
Buttons 단추(button)는 사용자가 마우스의 누름으로 동작을 시작하는 컴포넌트이다 단추는 JButton 클래스에 의해 정의된다 단추는 눌러질 때 Action Event를 발생시킨다 PushCounter예제는 버튼들의 작동을 시험한다 See PushCounter.java (page 192) See PushCounterPanel.java (page 193)
PushCounter.java //******************************************************************** // PushCounter.java Authors: Lewis/Loftus // // Demonstrates a graphical user interface and an event listener. import javax.swing.JFrame; public class PushCounter { //----------------------------------------------------------------- // Creates the main program frame. public static void main (String[] args) JFrame frame = new JFrame ("Push Counter"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new PushCounterPanel()); frame.pack(); frame.setVisible(true); }
PushCounterPanel.java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class PushCounterPanel extends JPanel { private int count; private JButton push; private JLabel label; // Constructor: Sets up the GUI. public PushCounterPanel () count = 0; push = new JButton ("Push Me!"); push.addActionListener (new ButtonListener()); label = new JLabel ("Pushes: " + count); add (push); add (label); setPreferredSize (new Dimension(300, 40)); setBackground (Color.cyan); } // Represents a listener for button push events. private class ButtonListener implements ActionListener { public void actionPerformed (ActionEvent event) count++; label.setText("Pushes: " + count); }
Push Counter Example 버튼과 counter를 보여줄 레이블 컴포넌트 필요하고, 패널은 그 컴포넌트들을 조직한다. PushCounterPanel class 는 버튼과 레이블을 보여주는데 사용되는 패널을 표현한다. PushCounterPanel class는 상속을 이용하여 Jpanel로부터 파생된다. PushCounterPanel의 생성자(구성자)는 GUI의 요소들을 셋업하고 카운터를 0으로 초기화한다.
Push Counter Example ButtonListener class는 버튼에 의해 생성되는 동작에 대한 리스너이다. ButtonListener class는 다른 클래스의 몸체내에 정의되는 inner class로 구현되어 있음으로써 리스너와 GUI컴포넌트간의 커뮤니케이션이 쉽게 이루어지도록 한다. Inner classes는 두 클래스사이의 관계가 매우 밀접하며 Inner class가 다른 곳에서는 사용되지 않을 경우에 사용한다.
Push Counter Example Listener classes는 listener interface를 구현함으로써 작성한다. ButtonListener class는 ActionListener interface를 구현한다. 인터페이스는 구현클래스에서 반드시 정의해야 하는 메소드의 목록이다. 자바 표준 클래스 라이브러리에는 많은 종류의 이벤트를 위한 인터페이스를 포함하고 있다. ActionListener interface내에는 actionPerformed method만이 존재한다. 6장에서 interface에 대해 좀더 자세히 배우게 된다.
Push Counter Example PushCounterPanel 생성자(구성자): ButtonListener 객체의 인스턴스를 생성하고 addActionListener를 호출함으로써 버튼과 리스너사이의 관계를 설정한다. 사용자가 버튼을 눌렀을때 버튼 컴포넌트는 ActionEvent객체를 생성하고 리스너의 actionPerformed method를 호출한다. actionPerformed method에서는 카운터를 증가시키고 레이블의 텍스트를 다시 조정한다.
예제 프로그램 See LeftRight.java See LeftRightPanel.java . left = new JButton ("Left"); right = new JButton ("Right"); ButtonListener listener = new ButtonListener(); left.addActionListener (listener); right.addActionListener (listener);
//******************************************************************** // LeftRight.java Authors: Lewis/Loftus // // Demonstrates the use of one listener for multiple buttons. import javax.swing.JFrame; public class LeftRight { //----------------------------------------------------------------- // Creates the main program frame. public static void main (String[] args) JFrame frame = new JFrame ("Left Right"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new LeftRightPanel()); frame.pack(); frame.setVisible(true); }
LeftRightPanel.java import java.awt.*; import java.awt.event.*; import javax.swing.*; //두 개의 단추들과 하나의 레이블을 포함하는 패널을 생성한다 public class LeftRightPanel extends JPanel { private JButton left, right; private JLabel label; private JPanel buttonPanel; public LeftRightPanel () left = new JButton ("Left"); right = new JButton ("Right"); ButtonListener listener = new ButtonListener(); left.addActionListener (listener); right.addActionListener (listener); label = new JLabel ("Push a button"); buttonPanel = new JPanel(); buttonPanel.setPreferredSize (new Dimension(200, 40)); buttonPanel.setBackground (Color.blue); buttonPanel.add (left); buttonPanel.add (right); setPreferredSize (new Dimension(200, 80)); setBackground (Color.cyan); add (label); add (buttonPanel); }
LeftRightPanel.java //***************************************************************** // Represents a listener for both buttons. // 단추 누름 event들에 대한 리스너를 나타낸다 private class ButtonListener implements ActionListener { //-------------------------------------------------------------- // Determines which button was pressed and sets the label // text accordingly. public void actionPerformed (ActionEvent event) // 단추가 눌러질 때 레이블을 갱신한다 if (event.getSource() == left) label.setText("Left"); else label.setText("Right"); }
Text Fields 텍스트 필드(text field)는 사용자가 한 줄의 입력을 하는 것을 허락하는 컴포넌트이다 텍스트 필드는 JTextField에 의해 정의된다 커서가 텍스트 필드 안에 있을 때 Enter 키를 누르면 Action Event을 발생시킨다 다음 프로그램은 텍스트 필드의 작동을 시험한다 See Fahrenheit.java (page 195) See FahrenheitPanel.java (page 197)
Fahrenheit.java //******************************************************************** // Fahrenheit.java Author: Lewis/Loftus // // Demonstrates the use of text fields. import javax.swing.JFrame; public class Fahrenheit { //----------------------------------------------------------------- // Creates and displays the temperature converter GUI. public static void main (String[] args) JFrame frame = new JFrame ("Fahrenheit"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); FahrenheitPanel panel = new FahrenheitPanel(); frame.getContentPane().add(panel); frame.pack(); frame.setVisible(true); }
FahrenheitPanel.java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class FahrenheitPanel extends JPanel { private JLabel inputLabel, outputLabel, resultLabel; private JTextField fahrenheit; public FahrenheitPanel() // Constructor: Sets up the main GUI components. inputLabel = new JLabel ("Enter Fahrenheit temperature:"); outputLabel = new JLabel ("Temperature in Celsius: "); resultLabel = new JLabel ("---"); fahrenheit = new JTextField (5); fahrenheit.addActionListener (new TempListener()); add (inputLabel); add (fahrenheit); add (outputLabel); add (resultLabel); setPreferredSize (new Dimension(300, 75)); setBackground (Color.yellow); }
FahrenheitPanel.java //***************************************************************** // Represents an action listener for the temperature input field. private class TempListener implements ActionListener { //-------------------------------------------------------------- // Performs the conversion when the enter key is pressed in // the text field. public void actionPerformed (ActionEvent event) int fahrenheitTemp, celsiusTemp; String text = fahrenheit.getText(); fahrenheitTemp = Integer.parseInt (text); celsiusTemp = (fahrenheitTemp-32) * 5/9; resultLabel.setText (Integer.toString (celsiusTemp)); }
Fahrenheit Example PushCounter예제와 같이, GUI부분을 별도의 panel클래스로 작성했다. TempListener inner class는 텍스트필드에 의해 생성되는 action 이벤트에 대한 리스너를 정의한다. FahrenheitPanel생성자(구성자)는 리스너의 인스턴스를 생성하고 텍스트필드에 추가한다. 사용자가 온도를 입력하고 엔터키를 누르면, 텍스트 필드는 action 이벤트를 발생시키고 리스너의 actionPerformed method 를 호출한다. actionPerformed method는 화씨온도를 섭씨로 바꾸는 계산을 하고 result레이블을 수정한다.