내부 클래스

Download Report

Transcript 내부 클래스

12장. GUI
학습목표
GUI
이벤트, 이벤트 리스너와 이벤트 소스
그림 그리기
내부 클래스
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
창
Jframe의 모양(Metal L&F)
Jframe의 모양(Aqua L&F)
창을 만드는 방법
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
1. 프레임(JFrame) 만들기
JFrame frame = new JFrame();
2. 위젯 만들기
JButton button = new JButton(“click me”);
3. 위젯을 프레임에 추가
frame.getContentPane().add(button);
4. 화면에 표시
frame.setSize(300, 300);
frame.setVisible(true);
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
import javax.swing.*;
public class SimpleGui1 {
public static void main(String[] args) {
JFrame frame = new JFrame();
JButton button = new JButton(“click me”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(button);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
버튼
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
이벤트
 사용자가 클릭했을 때 호출할 메소드
public void changeIt() {
button.setText(“I’ve been clicked!”);
}
 그 메소드를 언제 실행시켜야 할지 알아내는 방법
코드
Button 객체
리스너 인터페이스
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
 이벤트 소스(event source)
 사용자의 행동을 이벤트로 바꿔주는 객체
 java.awt.event 패키지
 리스너(listener) 인터페이스
 리스너와 이벤트 소스를 연결해주는 다리 역할을 함
 필요한 이벤트 유형에 맞는 리스너 인터페이스를 구현
하면 그 이벤트를 받아올 수 있습니다.
ActionListener
actionPerformed(ActionEvent ev)
ItemListener
itemStateChanged(ItemEvent ev)
KeyListener
KeyPressed(KeyEvent ev)
KeyReleased(KeyEvent ev)
KeyTyped(KeyEvent ev)
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
button.addActionListener(this)
actionPerformed(theEvent)
Event 객체
리스너와 소스
ActionEvent를 받는 방법
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
1. ActionListener
인터페이스 구
현
2. 버튼에 등록
3. 이벤트 처리 메
소드 구현
import javax.swing.*;
import java.awt.event.*;
public class SimpleGui1B implements ActionListener {
JButton button;
public static void main(String[] args) {
SimpleGui1B = new SimpleGui1B();
gui.go();
}
public void go() {
JFrame frame = new JFrame();
button = new JButton(“click me”);
button.addActionListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(button);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent ev) {
button.setText(“I’ve been clicked!”);
}
}
이벤트 소스인지 알아내는 방법
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
 API 문서를 찾아보면 됩니다.
 add로 시작하고 Listener로 끝나는 이름을 가지고
리스너 인터페이스 인자를 받아들이는 메소드가
있는지 찾아보면 됩니다.
addKeyListener(KeyListener k)
addActionListener(ActionListener a)
GUI에 요소를 추가하는 방법
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
1. 프레임에 위젯을 집어넣는 방법
frame.getContentPane().add(myButton);
2. 위젯에 2D 그래픽을 그리는 방법
graphics.fillOval(70, 70, 100, 100);
3. 위젯에 그림 파일을 집어넣는 방법
graphics.drawImage(myPic, 10, 10, this);
그림을 그리기 위한 위젯
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
 JPanel의 하위클래스를 만들고 paintComponent()
라는 메소드를 오버라이드
 paintComponent() 메소드
 시스템에서 위젯을 화면에 표시하기 위해 호출하는 메
소드
 그래픽 관련 코드는 대부분 여기에 집어넣습니다.
 JVM에서 화면을 갱신할 때마다 호출됩니다.
 사용자가 직접 호출하는 일은 절대 없습니다. 대신
repaint() 메소드를 호출하면 화면이 갱신되면서 이 메
소드가 실행됩니다.
paintComponent()
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
import java.awt.*;
import javax.swing.*;
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.orange);
g.fillRect(20, 50, 100, 100);
}
}
paintComponent()
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
 JPEG 파일 표시
public void paintComponent(Graphics g) {
Image image = new ImageIcon(“catzilla.jpg”).getImage();
g.drawImage(image, 3, 4, this);
}
 그리기
public void paintComponent(Graphics g) {
g.fillRect(0, 0, this.getWidth(), this.getHeight());
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color randomColor = new Color(red, green, blue);
g.setColor(randomColor);
g.fillOval(70, 70, 100, 100);
}
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
Graphics2D
public void paintComponent(Graphics g) {
 g 매개변수는 사실 Graphics2D 객체를 참조함
Animal a = new Dog();
a.bark();
Dog d = (Dog) a;
d.bark();
Graphics2D g2d = (Graphics2D) g;
이벤트를 받아서 그림을 고쳐그리는 방법
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
GUI 레이아웃
 한 프레임에 두 개 이상의 위젯을 넣는 방법
frame.getContentPane().add(button);
frame.getContentPane().add(BorderLayout.CENTER, button);
북쪽(NORTH)
서쪽
(WEST)
중앙
(CENTER)
남쪽(SOUTH)
동쪽
(EAST)
버튼이 두 개 있으면?
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
북쪽(NORTH)
서쪽
(WEST)
중앙
(CENTER)
남쪽(SOUTH)
동쪽
(EAST)
여러 개의 이벤트를 처리하는 방법
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
1. actionPerformed() 메소드를 두 개 구현
class MyGui implements ActionListener {
……
public void actionPerformed(ActionEvent ev) {
frame.repaint();
}
public void actionPerformed(ActionEvent ev) {
label.setLabel(“That hurt!”);
}
}
여러 개의 이벤트를 처리하는 방법
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
2. 똑같은 리스너를 두 버튼에 모두 등록
class MyGui implements ActionListener {
……
public void go() {
……
colorButton = new JButton();
labelButton = new JButton();
colorButton.addActionListener(this);
labelButton.addActionListener(this);
……
}
public void actionPerformed(ActionEvnet ev) {
if (event.getSource() == colorButton) {
frame.repaint();
} else {
label.setLabel(“That hurt!”);
}
}
}
여러 개의 이벤트를 처리하는 방법
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
3. 각 버튼마다 별도의 ActionListener 클래스 제작
class MyGui {
JFrame frame;
JLabel label;
void gui() {
…
}
}
class ColorButtonListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
frame.repaint();
}
}
class LabelButtonListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
label.setLabel(“That hurt!”);
}
}
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
내부 클래스
 내부 클래스(inner class)
 외부 클래스에 있는 것을 마음대로 사용할 수 있음
class MyOuterClass {
private int x;
class MyInnerClass {
void go() {
x = 42;
}
}
}
내부 클래스와 외부 클래스 인스턴스
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
1. 외부클래스 인스턴스를 만듭니다.
2. 외부클래스의 인스턴스를
이용하여 내부클래스의 인스
턴스를 만듭니다.
MyOuter 객체
MyInner 객체
int x
3. 외부 객체와 내
부 객체는 각별한
사이가 됩니다.
String s
외부 객체
내부 객체
내부 클래스의 인스턴스
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
 일반 클래스의 인스턴스를 만들 때와 똑같은 식으
로 하면 됩니다.
class MyOuter {
private int x;
MyInner inner = new MyInner();
public void doStuff() {
inner.go();
}
class MyInner {
void go() {
x = 42;
}
}
}
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
애니메이션
1. 특정 좌표에 객체를 그림
g.fillOval(20, 50, 100, 100);
2. 다른 좌표에 객체를 서로
그림
g.fillOval(25, 55, 100, 100);
3. 좌표를 바꿔가면서 위의
단계 반복
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
애니메이션
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.orange);
g.fillOval(x, y, 100, 100);
}
}
 x, y 좌표는 어디에서 바꿀까?
 repaint()는 어디에서 호출할까?
 그림 패널을 내부 클래스로…
 paintComponent에서 순환문을 쓰지 않고…
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
뮤직 비디오(?)
GUI와 무관한 이벤트
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
 미디 이벤트를 받아서 처리해야 함
 미디 이벤트(NOTE ON 이벤트)를 직접 받아 쓸 수 없음
 ControllerEvent라는 이벤트를 사용




첫
두
세
네
번째
번째
번째
번째
박자 –
박자 –
박자 –
박자 –
NOTE
NOTE
NOTE
NOTE
ON, ControllerEvent
OFF
ON, ControllerEvent
OFF
메시지를 쉽게 만드는 방법
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
1. 메시지 인스턴스 만들기
ShortMessage first = new ShortMessage();
2. SetMessage()를 호출하여 지시사항 전달
first.setMessage(192, 1, instrument, 0);
3. 메시지에 대한 MidiEvent 인스턴스 만들기
MidiEvent noteOn = new MidiEvent(first, 1);
4. 이벤트를 트랙에 추가
track.add(noteOn);
ShortMessage a = new ShortMessage();
a.setMessage(144, 1, 44, 100);
MidiEvent noteOn = new MidiEvent(a, 1);
track.add(noteOn);
메시지/이벤트를 만들기 위한 메소드
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
public static MidiEvent makeEvent(int comd, int chan,
int one, int two, int tick) {
MidiEvent event = null;
try {
ShortMessage a = new ShortMessage();
a.setMessage(comd, chan, one, two);
event = new MidiEvent(a, tick);
} catch(Exception ex) { }
return event;
}
RUNNING HEADER, 14 PT., ALL CAPS, Line Spacing=1 line
숙제
 본문을 꼼꼼하게 읽어봅시다.
 코드를 전부 입력해서 실행시켜보고 조금씩 고쳐
봅시다.
 장 중간 및 맨 끝에 나와있는 모든 연습문제를 자
기 힘으로 해결해봅시다.
 API 문서에서 이 장에 나와있는 클래스 및 메소드
에 대한 내용을 직접 찾아봅시다.