1. LayoutManager
배치관리자(LayoutManager) : 컨테이너에 컴퍼넌트를 부착할 때 컴포넌트의 크기와 출력위치를 자동으로 변경하여 부착하는 기능을 제공하는 클래스
border |
컴퍼넌트를 동서남북 중앙에 부착하는 배치관리자(프레임의 기본배치 관리자이므로 인스턴스 생성이 생략 가능하다) |
1. 컴퍼넌트를 부착할 때 반드시 부착위치 지정 - 부착위치가 생략된 경우 무조건 중앙에 부착 2. 동일한 위치에 컴퍼넌트가 이미 부착된 경우 덮어씌우기 발생 |
|
flow |
컴포넌트를 왼쪽에서 오른쪽으로 차례대로 부착하는 배치관리자 |
1. 컨테이너의 크기를 벗어날 경우 자동으로 아래에 위치하여 부착됨 | |
grid |
컴포넌트를 행렬로 구분하여 부착하는 배치관리자 |
행과 열의 갯수를 지정하여 컴포넌트를 부착할 수 있도록 함 |
컨테이너(특히 패널)에 부착하는 메소드의 사용
add() | 컴퍼넌트를 원하는 위치에 부착하는 메소드 (Border의 경우 부착위치는 borderLayout 클래스의 상수필드를 이용) |
Button btn1 = new Button("button1"); //버튼 인스턴스 생성 add(btn1); //컨테이너에 btn1을 부착(원하는 위치에 부착가능, 단, 크기는 설정 불가능) |
public class BorderLayoutApp extends Frame{
public BorderLayoutApp(String title) {
super(title);
Button btn1 = new Button("button1");
Button btn2 = new Button("button2");
Button btn3 = new Button("button3");
Button btn4 = new Button("button4");
Button btn5 = new Button("button5");
//프레임의 기본배치관리자가 borderlayout이므로, 변경은 무의미! 그래서 생략가능
//setLayout(new BorderLayout());
//component.add(Container c, object constraints) : 컴퍼넌트를 원하는 위치에 부착하는 메소드
//=> 부착위치는 borderLayout 클래스의 상수필드를 이용
add(btn1, BorderLayout.EAST);
add(btn2, BorderLayout.WEST);
add(btn3, BorderLayout.SOUTH);
add(btn4, BorderLayout.NORTH);
add(btn5, BorderLayout.CENTER);
setBounds(500, 100, 400, 400);
setVisible(true);
}
2. panel(컴포넌트를 그룹화한다고 생각하면됨)
Panel |
panel에 add시켜서 하나의 컴포넌트로 그룹화해주는 |
버튼이름 | 패널에 컨포넌트를 부착 |
redButton | panel.add(red); | ||
greenButton | panel.add(green); | ||
blueButton | panel.add(blue); | ||
TextArea | 문자열을 여러 줄 입력하거나 출력하는 컴포넌트 | panel.add(area) | |
TextField | 문자열을 한 줄 입력하거나 출력하는 컴포넌트 |
자주 사용하는 함수 | 기능 |
setFont(font f) | 컴포넌트의 글자관련 속성을 변경하는 메소드 |
font : 글자관련 속성을 저장하기 위한 클래스 - name, style, size를 지정할 수 있다. - 컨테이너의 디자인 속성을 변경하면 종속된 컴퍼넌트도 변경됨(색은 영향x) |
|
setForeground(color c) |
컴퍼넌트의 글자색을 변경 |
Color : 색상정보(RGB)를 저장하기 위한 클래스 | |
setBackground | 컴퍼넌트의 배경색을 변경 - Color 클래스에는 대표적인 색을 상수필드로 제공 - 컨테이너에 종속된 컴포넌트에 배경색은 변경 불가 |
setEnabled(boolean b) | 컴포넌트의 활성여부를 설정하기 위한 메소드 - false : 비활성화, true : 활성화 |
setEditable(boolean b) |
텍스트 컴포넌트의 문자열 수정여부를 설정하기 위한 메소드 - false : 수정불가능, true : 수정가능 |
setFocusable(boolean b) | 입력컴포넌트의 입력초점 위치여부를 설정하는 메소드 - false : 초점위치 불가, true : 가능 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
package site.itwill.awt;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
//
public class PanelApp extends Frame{
private static final long serialVersionUID = 1L;
public PanelApp(String title) {
super(title);
Button red = new Button("red");
Button green = new Button("green");
Button blue = new Button("blue");
//panel : 컴포넌트를 부착하기위한 컨테이너 = 기본레이아웃은 flow
Panel panel = new Panel();
//패널에 컨포넌트를 부착
panel.add(red);
panel.add(green);
panel.add(blue);
//TextArea : 문자열을 여러줄 입력하거나 출력하는 컴포넌트이다.
TextArea area = new TextArea();
//TextField : 문자열을 한 줄 입력하거나 출력하는 컴포넌트
TextField field = new TextField();
add(panel, BorderLayout.NORTH);
add(area, BorderLayout.CENTER);
add(field, BorderLayout.SOUTH);
//setFont(font f) : 컴포넌트의 글자관련 속성을 변경하는 메소드
//font : 글자관련련 속성을 저장하기 위한 클래스 : name(글꼴) style(스타일), size(크기)지정 가능
//=>컨테이너의 디자인 속성을 변경하면 종속된 컴퍼넌트도 변경됨(색은 영향x)
panel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 16));//버튼에게 영향이 간다.
area.setFont(new Font(Font.SERIF, Font.BOLD, 16));
field.setFont(new Font(Font.SERIF, Font.ITALIC, 16));
panel.add(area);
//SetForeground(Color c) : 컴퍼넌트의 글자색을 변경
//Color : 색상정보(RGB)를 저장하기 위한 클래스
red.setForeground(new Color(255,0,0));
green.setForeground(new Color(150,255,150));
blue.setForeground(new Color(0,0,255));
//setBackground : 컴퍼넌트의 배경색을 변경
//=> Color클래스에는 대표적인 색을 상수필드로 제공
//-> 컨테이너에 종속된 컴포넌트에 배경색은 미변경
panel.setBackground(Color.yellow);
//setEnabled(boolean b) : 컴포넌트의 활성여부를 설정하기 위한 메소드
//false : 비활성화, true : 활성화
red.setEnabled(false);
//setEditable(boolean b) : 텍스트 컴포넌트의 문자열 수정여부를 설정하기 위한 메소드
//=> false : 수정불가능, true : 수정가능
//area.setEditable(false);
//setFocusable(boolean b) : 입력컴포넌트의 입력초점 위치여부를 설정하는 메소드
//=> false : 초점위치 불가, true : 가능
area.setFocusable(false);//결국 출력 컴포넌트로밖에 사용할수밖에 없음
setBounds(500,100,300,400);
setVisible(true);
}
public static void main(String[] args) {
new PanelApp("title");
}
}
|
cs |
3. 이벤트 핸들러
크게 4가지의 방법이 있다.
1 | 2 | 3 | 4 |
이벤트 핸들러 클래스를 따로 작성 |
디자인클래스와 이벤트 핸들러 클래스를 한 파일로 구현 | 내부클래스를 이용★ | 익명의 내부클래스★ |
- ActionEvent를 처리하기 위해 ActionListener인터페이스를 상속받아 작성 - 이벤트가 무수히 많기 때문에 인터페이스를 상속받아 하는것임 -> 다중상속이 더 용이. 그렇기 때문에 인터페이스를 사용 |
-이벤트를 처리하는 오버라이드된 메소드가 여기 디자인 클래스 자체에 있으므로 this를 호출 | - 이벤트 핸들러 클래스에서 디자인 클래스의 컴퍼넌트를 사용할 수 있다.(내부 클래스로 선언한 거니까 아우터 필드 접근 가능) - 이렇게 하면 이벤트 핸들러를 여러개 만들 수 있다. |
이벤트 핸들러 클래스를 생성하지 않고도 직접 이벤트 핸들러를 등록하는 방법 -클래스 없이 인스턴스만을 만드는 경우사용된다. (종종 사용됨) |
* 내부클래스란?
외부클래스(=Outer클래스) |
내부 클래스가 선언된 클래스 - 내부 클래스로 인스턴스를 생성하여 필드와 메소드에 접근가능 |
내부클래스(=Inner클래스) |
클래스 안에 선언된 클래스 cf)메소드안에 클래스 선언도 가능 - 외부클래스에 선언된 필드와 메소드에 접근이 가능하다. - 외부클래스에서만 인스턴스를 생성할 수 있는 클래스이다. - inner클래는 outer클래스의 메소드를 가져다 사용할 수 있다. |
* 익명의 내부클래스
- 추상클래스(인터페이스)를 이용하여 인스터스 생성 불가능하기 때문에 추상클래스(인터페이스)의 추상메소드를 직접 오버라이드 선언하여 생성한다.
- 상속받는 자식 클래스의 이름을 명시하지 않고도(참조변수 선언x) 직접 인스턴스를 생성할 수 있다는 장점
- 단점이라면, 하나의 인스턴스만 생성이 가능함
- 아래와 같이 사용된다.
exit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
내부클래스 예시 코드 전체보기
package site.itwill.event;
//외부 클래스 (outer 클래스) : 내부클래스가 선언된 클래스
//=> 내부 클래스로 인스턴스를 생성하여 필드와 메소드에 접근가능
public class Outer {
private int outerNum;
public Outer() {
// TODO Auto-generated constructor stub
}
public Outer(int outerNum) {
super();
this.outerNum = outerNum;
}
public int getOuterNum() {
return outerNum;
}
public void setOuterNum(int outerNum) {
this.outerNum = outerNum;
}
public void outerDisplay() {
System.out.println("outerNum = " + outerNum);
}
public void outerInnerDisplay() {
//내부클래스를 이용하여 인스턴스 생성
//=> 생성된 인스턴스를 이용하여 필드와 메소드접근가능
Inner inner = new Inner(100);
inner.innerDisplay();
}
// 내부클래스 (inner 클래스) : 클래스 안에 선언된 클래스 cf)메소드안에 클래스 선언도 가능
// => 외부클래스에 선언된 필드와 메소드에 접근이 가능
// => 외부클래스에서만 인스턴스를 생성할 수 있는 클래스
public class Inner {
private int innerNum;
public Inner() {
// TODO Auto-generated constructor stub
}
public Inner(int innerNum) {
super();
this.innerNum = innerNum;
}
public int getInnerNum() {
return innerNum;
}
public void setInnerNum(int innerNum) {
this.innerNum = innerNum;
}
public void innerDisplay() {
System.out.println("innerNum = " + innerNum);
}
//이너클래스는 아우터클래스의 메소드를 가져다 사용 가능
public void innerOuterDisplay() {
outerDisplay();
}
}
//내부정적클래스.....외부에는 static절대 붙을 수 없음
// 클래스 안에 선언된 정적클래스
//=> 외부클래스에 선언된 필드와 메소드에 접근 불가능
//=> 외부클래스에 선언된 정적필드와 정적메소드에는 접근 불가능
// => 다른 클래스에서도 인스턴스 생성이 가능한 클래스
public static class Nested{
private int nestedNum;
public Nested() {
// TODO Auto-generated constructor stub
}
public int getNestedNum() {
return nestedNum;
}
public void setNestedNum(int nestedNum) {
this.nestedNum = nestedNum;
}
public Nested(int nestedNum) {
super();
this.nestedNum = nestedNum;
}
public void nesteDisplay() {
System.out.println("nestedNum = " + nestedNum);
System.out.println();
}
}
}
1) 이벤트 핸들러 클래스를 따로 작성
- 디자인클래스와 이벤트 핸들러 메소드를 같은 클래스로 구현 (간단한 이벤트 몇개만 있을 때)
package site.itwill.event;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//디자인 클래스
public class EventHandlerApp extends Frame {
private static final long serialVersionUID = 1L;
public EventHandlerApp(String title) {
super(title);
//Button 컴퍼넌트를 사용자가 누룰 경우 Action이벤트가 발생
//-> 시스템(os)에서 컴퍼넌트의 이벤트에 대한 인스턴스를 자동생성
Button exit = new Button("프로그램 종료");
setLayout(new FlowLayout());;
add(exit);
//Button 컴퍼넌트에 액션이벤트를 처리하는 ActionListener를 추가한다.
exit.addActionListener(new ActionEventHandler());
setBounds(500,100,300,300);
setVisible(true);
}
public static void main(String[] args) {
new EventHandlerApp("이벤트");
}
}
//이벤트 핸들러 클래스
// => ActionEvent를 처리하기 위해 ActionListener인터페이스를 상속받아 작성
// 이벤트가 무수히 많기 때문에 인터페이스를 상속받아 하는것임 -> 다중상속이 더 용이. 그렇기 때문에 인터페이스를 사용
class ActionEventHandler implements ActionListener {
//ActionEvent가 발생된 경우, 자동 호출되는 메소드(JVM이 알아서 호출~)
//이벤트 처리메소드
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
2) 디자인클래스와 이벤트 핸들러 클래스를 같은 클래스로 구현
- extends Frame (클래스상속) implements ActionListener (인터페이스 상속)
package site.itwill.event;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//디자인 클래스(Frame클래스 상속)와 이벤트 핸들러(인터페이스 상속) 클래스를 같은 클래스로 구현
public class EventsourceHandlerApp extends Frame implements ActionListener{
private static final long serialVersionUID = 1L;
public EventsourceHandlerApp(String title) {
super(title);
Button exit = new Button("프로그램 종료");
setLayout(new FlowLayout());
add(exit);
exit.addActionListener(this); //이벤트를 처리하는 오버라이드된 메소드가 여기 디자인 클래스 자체에 있으므로this호출
setBounds(500,100,300,300);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
public static void main(String[] args) {
new EventsourceHandlerApp("event");
}
}
3)내부클래스를 이용
package site.itwill.event;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//디자인 클래스를 이벤트 핸들러 클래스 구현
public class EventInnerHandlerApp extends Frame {
private static final long serialVersionUID = 1L;
public EventInnerHandlerApp(String title) {
super(title);
Button exit = new Button("프로그램 종료");
setLayout(new FlowLayout());
add(exit);
exit.addActionListener(new ActionEventHandler()); // 이벤트를 처리하는 오버라이드된 메소드가 여기 디자인 클래스 자체에 있으므로this호출
setBounds(500, 100, 300, 300);
setVisible(true);
}
public static void main(String[] args) {
new EventInnerHandlerApp("app");
}
//이벤트 핸들러 클래스에서 디자인 클래스의 컴퍼넌트 사용가능
//이렇게하면 이벤트핸들러를 여러개 만들 수 있음
public class ActionEventHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
}
4) 익명의 내부클래스
package site.itwill.event;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import site.itwill.event.EventInnerHandlerApp.ActionEventHandler;
//이벤트 핸들러 클래스를 생성하지 않고도 직접 이벤트 핸들러를 등록하는 방법
//클래스없이 인스턴스만을 만드는 경우(종종사용됨)
public class EventAnnonymousHandlerApp extends Frame {
private static final long serialVersionUID = 1L;
public EventAnnonymousHandlerApp(String title) {
super(title);
Button exit = new Button("프로그램 종료");
setLayout(new FlowLayout());
add(exit);
//추상클래스(인터페이스)를 이용하여 인스턴스 생성불가능
// => 클래스가 상속받아 사용하는 상속전용자료형
//=> 추상클래스(인터페이스)의 추상메소드를 직접 오버라이드 선언하여 생성가능
//=> 상속 받는 자식 클래스의 이름을 명시하지 않고도 직접인스턴스를 생성할 수 있다.
//=> 익명의 내부클래스는 하나의 인스턴스만 생성이 가능하다.
//익명의 내부클래스(Annonymous inner클래스)로 이벤트핸들러 등록
exit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}); //단점 이벤트 소스를 계속 만들어줘야한다는 것.//
setBounds(500, 100, 300, 300);
setVisible(true);
}
public static void main(String[] args) {
new EventAnnonymousHandlerApp("app");
}
}
이벤트 프로그램 작성 방법
1. 컴퍼넌트를(컨테이너를) 이용하여 디자인 클래스를 작성
=> Frame클래스를 상속받아 작성
=> 컨테이너(컴포넌트)에서 다양한 이벤트가 발생 - 이벤트 소스 (모두 다가 이벤트가 되는것은 아님)
2. 이벤트를 처리하기 위한 이벤트 핸들러 클래스를 작성
=> 컴퍼넌트에서 발생된 이벤트를 처리하기 위한 클래스
=> 컴퍼넌트에서 발생된 xxx이벤트를 처리하기 위해 xxxListener 인터페이스를 상속받아
=> 리스너 인터페이스 : 이벤트를 처리하기 위한 추상메소드가 선언된 인터페이스
=> 추상메소드를 오버라이드 선언하여 메소드에 이벤트 처리 명령을 작성
★3.이벤트 소스에서 이벤트가 발생될 경우, 이벤트 핸들러가 동작되도록 이벤트 등록을 해야한다.
=> Component.addXXXListener(Listener l) : 컴퍼넌트에서 이벤트가 발생될 경우 이벤트 헨들러 인스터스를 이용하도록 처리하는 메소드
=> 이벤트 핸들러 인스턴스가 이벤트 처리 메소드를 자동 호출하여 이벤트 처리
디자인클래스와 이벤트 핸들러클래스를 같은 클래스로 만들면 좋은점?
디자인클래스의 필드를 이벤트 핸들러가 갖다 쓸 수 있기 때문에 편하다.
but, 이벤트핸들러의 엄청나게 많아지면 , 이것도 불편해 질 수 있다.
이벤트 소스가 여러개인 경우 이벤트를 처리하는 방법?
- 이벤트 핸들러 메소드에서 사용할 컴포넌트는 필드로 선언해주는 것이 좋다. => 이벤트 핸들러가 접근하여 사용할 수 있도록
- 컴포넌트들은 해당 앱의 생성자에서 만들어 준다. (여기서 주의 ★ 이벤트 핸들러 등록을 꼭 해주어야 함)
- 겹치는 핸들러는 최대한 한번에 만들어 주는것이 좋다.
- implements ActionListener를 상속받아주고, actionPerformed 메소드를 오버라이드 해준다.(반드시 꼭)
- 매개변수인 ActionEvent e는 이벤트소스를 구분하여 해당 이벤트를 처리 할 수 있도록 해준다.
getActionCommand( ) | 이벤트 소스의 actionCommand를 반환하는 메소드이다. |
- actionCommand란 ? 이벤트 소스의 대표값이다. 예를 들면 , 버튼 컴포넌트에서는 기본적으로 라벨명이 ActionCommand가 된다.
String actionCommand = e.getActionCommad(); |
하여 값을 받아와, 전달되는 이벤트 소스에따라 구분지어 명령을 실행하도록 if문을 돌린다.
버튼4개 이벤트 핸들러 만드는 예시 전체코드 보기
package site.itwill.event;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
//이벤트 소스가 여러개인 경우의 이벤트 처리 방법
//색상버튼을 누른경우, 캔버스의 배경색을 변경하는 프로그램
public class MultiHandlerApp extends Frame {
private static final long serialVersionUID = 1L;
//이벤트 핸들러 메소드에서 사용할 컴포넌트는 필드로 선언해주어야 한다.
//=>그래야지 이벤트 핸들러에서도 사용가능
Button red, green, blue, white;
Canvas canvas;
//컴포넌트는 생성자에서 만들어 준다.
public MultiHandlerApp(String title) {
super(title);
red = new Button("red");
green = new Button("green");
blue = new Button("blue");
white = new Button("white");
Panel panel = new Panel();
panel.add(red);
panel.add(green);
panel.add(blue);
panel.add(white);
canvas = new Canvas();
add(panel, BorderLayout.NORTH);
add(canvas, BorderLayout.CENTER);
panel.setBackground(Color.gray);
panel.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16));
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
red.addActionListener(new ColorButtonEventHandler()); //레드 버튼 액션이벤트
green.addActionListener(new ColorButtonEventHandler());
blue.addActionListener(new ColorButtonEventHandler());
white.addActionListener(new ColorButtonEventHandler());
white.setEnabled(false);
setBounds(500, 100, 400, 400);
setVisible(true);
}
/*
//모든 색상버튼을 활성화하는 기능을 제공하는 메소드
public void initColorButton() {
red.setEnabled(true);
green.setEnabled(true);
blue.setEnabled(true);
white.setEnabled(true);
}
*/
public static void main(String[] args) {
new MultiHandlerApp("app");
}
/*
public class redbuttonEventHandler implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
initColorButton();
red.setEnabled(false);
canvas.setBackground(Color.RED);
//white.setEnabled(true);
}
}
public class greenbuttonEventHandler implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
initColorButton();
green.setEnabled(false);
canvas.setBackground(Color.green);
}
}
public class bluebuttonEventHandler implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
initColorButton();
blue.setEnabled(false);
canvas.setBackground(Color.blue);
}
}
public class whitebuttonEventHandler implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
initColorButton();
white.setEnabled(false);
canvas.setBackground(Color.white);
}
}
*/
//버튼에 대한 이벤트를 1개만 만들어 준다.
public class ColorButtonEventHandler implements ActionListener{
//이벤트 핸들러 메소드의 매개변수에는 이벤트 정보가 자동으로 전달되어 저장된다
@Override
public void actionPerformed(ActionEvent e) {//전달되어지는 매개변수가 중요
red.setEnabled(true);
green.setEnabled(true);
blue.setEnabled(true);
white.setEnabled(true);
//이벤트 소스를 구분하여 이벤트를 처리한다.
//getActionCommand() : 이벤트 소스의 actionCommand를 반환하는 메소드이다.
//=> actionCommand : 이벤트 소스의 대푯값
//=> Button 컴포넌트는 기본적으로 라벨명이 ActionCommand가된다.
String actionCommand = e.getActionCommand();
//전달되는 이벤트 소스에따라 구분지어 명령을 실행하도록 한다.
if(actionCommand.equals("red")) {
red.setEnabled(false);
canvas.setBackground(Color.red);
}else if(actionCommand.equals("green")){
green.setEnabled(false);
canvas.setBackground(Color.green);
}else if(actionCommand.equals("blue")){
blue.setEnabled(false);
canvas.setBackground(Color.blue);
}else if(actionCommand.equals("white")){
white.setEnabled(false);
canvas.setBackground(Color.white);
}
}
}
}
4. Adapter 클래스의 사용
EventListener를 사용하게 될 경우, 인터페이스를 상속받아 사용하는 것이기 때문에 추상메소드 7개를 모두 오버라이드 해야하는 경우가 생긴다.
그래서 Adapter클래스를 사용하면 원하는 추상메소드를 1개만 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
package site.itwill.event;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//디자인 클래스
public class EventHandlerApp extends Frame {
private static final long serialVersionUID = 1L;
public EventHandlerApp(String title) {
super(title);
//Button 컴퍼넌트를 사용자가 누룰 경우 Action이벤트가 발생
//-> 시스템(os)에서 컴퍼넌트의 이벤트에 대한 인스턴스를 자동생성
//
Button exit = new Button("프로그램 종료");
setLayout(new FlowLayout());;
add(exit);
//Button 컴퍼넌트에 액션이벤트를 처리하는 ActionListener를 추가한다.
exit.addActionListener(new ActionEventHandler());
setBounds(500,100,300,300);
setVisible(true);
}
public static void main(String[] args) {
new EventHandlerApp("이벤트");
}
}
//이벤트 핸들러 클래스
// => ActionEvent를 처리하기 위해 ActionListener인터페이스를 상속받아 작성
// 이벤트가 무수히 많기 때문에 인터페이스를 상속받아 하는것임 -> 다중상속이 더 용이. 그렇기 때문에 인터페이스를 사용
class ActionEventHandler implements ActionListener {
//ActionEvent가 발생된 경우, 자동 호출되는 메소드(JVM이 알아서 호출~)
//이벤트 처리메소드
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
package site.itwill.event;
//외부 클래스 (outer 클래스) : 내부클래스가 선언된 클래스
//=> 내부 클래스로 인스턴스를 생성하여 필드와 메소드에 접근가능
public class Outer {
private int outerNum;
public Outer() {
// TODO Auto-generated constructor stub
}
public Outer(int outerNum) {
super();
this.outerNum = outerNum;
}
public int getOuterNum() {
return outerNum;
}
public void setOuterNum(int outerNum) {
this.outerNum = outerNum;
}
public void outerDisplay() {
System.out.println("outerNum = " + outerNum);
}
public void outerInnerDisplay() {
//내부클래스를 이용하여 인스턴스 생성
//=> 생성된 인스턴스를 이용하여 필드와 메소드접근가능
Inner inner = new Inner(100);
inner.innerDisplay();
}
// 내부클래스 (inner 클래스) : 클래스 안에 선언된 클래스 cf)메소드안에 클래스 선언도 가능
// => 외부클래스에 선언된 필드와 메소드에 접근이 가능
// => 외부클래스에서만 인스턴스를 생성할 수 있는 클래스
public class Inner {
private int innerNum;
public Inner() {
// TODO Auto-generated constructor stub
}
public Inner(int innerNum) {
super();
this.innerNum = innerNum;
}
public int getInnerNum() {
return innerNum;
}
public void setInnerNum(int innerNum) {
this.innerNum = innerNum;
}
public void innerDisplay() {
System.out.println("innerNum = " + innerNum);
}
//이너클래스는 아우터클래스의 메소드를 가져다 사용 가능
public void innerOuterDisplay() {
outerDisplay();
}
}
//내부정적클래스.....외부에는 static절대 붙을 수 없음
// 클래스 안에 선언된 정적클래스
//=> 외부클래스에 선언된 필드와 메소드에 접근 불가능
//=> 외부클래스에 선언된 정적필드와 정적메소드에는 접근 불가능
// => 다른 클래스에서도 인스턴스 생성이 가능한 클래스
public static class Nested{
private int nestedNum;
public Nested() {
// TODO Auto-generated constructor stub
}
public int getNestedNum() {
return nestedNum;
}
public void setNestedNum(int nestedNum) {
this.nestedNum = nestedNum;
}
public Nested(int nestedNum) {
super();
this.nestedNum = nestedNum;
}
public void nesteDisplay() {
System.out.println("nestedNum = " + nestedNum);
System.out.println();
}
}
}
|
cs |
'💻 수업정리 (2020) > 자바' 카테고리의 다른 글
[6/4] 버튼입력받아 계산기 만들기 (0) | 2020.06.04 |
---|---|
[6/3] Menu만들기와, Swing이용해보기 (0) | 2020.06.03 |
[6/1] 자료구조클래스와 awt패키지 (0) | 2020.06.01 |
[5/29] java.util패키지 (0) | 2020.05.29 |
[5/28] java.lang패키지 (0) | 2020.05.28 |