AWT 의 자바 어댑터 클래스들은 리스너 인터페이스의 기본 메소드를 구현해놨다. 어댑터 클래스를 상속하면 리스너의 모든 인터페이스를 구현할 필요가 없다. 안그러면 인터페이스의 메소드를 사용하건 안하건 무조건 다 구현해줘야 한다. 그래서 코드가 줄어든다.
어댑터 클래스는 리스너와 한 쌍을 이룬다.
WindowAdapter - WindowListener
MouseAdapter - MouseListener
...
WindowAdapter를 예를 들면 WindowListener를 implements 할 때 선언만 되어있는 모든 메소드를 구현해줘야 한다.
추상 클래스 윈도우 어댑터는 { } 로 구현을 해놨다. 윈도우 어댑터를 사용하면 사용하고 싶은 메소드만 구현하면 된다.
import java.awt.*;
import java.awt.event.*;
public class AwtGUI9 extends MouseMotionAdapter{
Frame fr1;
Graphics g1;
AwtGUI9(){
// WindowApapter
fr1 = new Frame("Adapter class");
fr1.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
fr1.dispose();
}
});
// MouseAdapter
fr1.addMouseMotionListener(this);
// below is Frame
fr1.setTitle("Adapter class");
fr1.setSize(700,700);
fr1.setLayout(null);
fr1.setVisible(true);
}
public static void main(String[] args) {
new AwtGUI9();
}
public void mouseDragged(MouseEvent e) {
g1 = fr1.getGraphics();
g1.setColor(Color.BLUE);
g1.fillRect(e.getX(), e.getY(), 7, 7);
}
}
Frame 클래스에서 addWindowListener 를 호출하며 윈도우 어댑터 클래스를 생성하여 바로 원하는 메소드를 오버라이드 한다. windowClosing 이다. (윈도우창 종료) 사용하지 않는 코드까지 작성할 필요가 없어서 편리하다. 익명 클래스이므로 클래스를 상속하지 않아도 된다.
마우스를 드래그 할 때의 메소드만 오버라이드 할 것이다. 우선 MouseMotionAdapter 를 상속한다. 이 시점에서 MouseMotionListener의 메소드들은 구현이 된다. 이제 사용할 메서드만 작성하면 된다. mouseDragged 로 간단한 그림판을 만든다.Graphics 클래스 참조변수에 getGraphics( ) 를 사용하여 현재 프레임의 정보를 담은 Graphics 참조변수 g를 대입한다. fillRect 메소드로 드래그 이벤트가 발생하는 클릭 위치에 7x7의 사각형을 그린다.
윈도우를 종료하는 방법은 여러가지가 있다고 말했다.
1)의 익명클래스 사용법과, extends 로 WindowAdapter를 상속하는 방법도 있다. 그런데 extends로는 한개를 초과하는 클래스의 상속이 안된다. 다른 중요한 클래스를 상속하면 사용하지 못한다. 그럴때는 익명클래스를 사용하거나 WindowListener 인터페이스를 직접 구현하면 된다.
반복해서 이야기하는 것 같지만 어쩔 수 없다. 반복이란게 컴퓨터의 숙명과도 같은 것이니까 컴퓨터를 사용하는 인간도 자꾸 반복하게 된다. 똑같은 대상을 다양한 이름으로 부르기도 하고 (인스턴스,객체 같이) 컨텍스트에 따라 미묘한 늬앙스가 숨어있다. 수도없이 반복해서 그 의미를 체득한 사람과 오늘 아침에 처음 알게된 사람의 방법론은 다를 수 있다.
WindowListener 를 Implements 하면 (implements를 구현하다로 번역하는데 모든 상황에서 맞지는 않다고 한다) 그 안에 선언된 모든 메소드의 작동 코드도 만들어 줘야한다. 사용하지 않더라도 { } 라고 컴파일러에게 구현이 되었다고 알려줘야 한다.
여기서는 public void windowClosing(WindowEvent e) { } 하나만 사용할 것인데 그것조차도 dispose ( ) 밖에 쓸 내용이 없다. (뜻은 처분하다, 윈도우를 다 사용했으니 메모리에서 싹 해제시켜서 처분한다는 것이다) System.exit(0)를 사용해되 된다. 마찬가지로 exit 빠져나간다는 뜻.
* 다행히 이클립스에는 이런 기능이 있다. Add unimplemented methods (구현되지 않은 메소드를 추가한다), 7 methods to implement 7개의 메소드를 구현해야 한다. 클릭하면 7개의 메소드가 { } 빈칸으로 구현된다. 이것만으로도 타이핑을 하는 수고를 크게 덜어준다. 과거 IDE 가 발달하지 않았을 때는 개발자들의 인내심이 대단했을 것 같다. 모든 것을 토씨하나 안틀리고 다 입력해야 하니까.
import java.awt.*;
import java.awt.event.*;
public class AwtGUI9 extends Frame implements WindowListener{
AwtGUI9(){
addWindowListener(this);
setTitle("Window Closing");
setSize(500,500);
setLayout(null);
setVisible(true);
}
public static void main(String[] args) {
new AwtGUI9();
}
@Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowClosing(WindowEvent e) {
dispose();
}
@Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub
}
}
윈도우리스너만 추가해주면 된다. this는 이 생성자가 만들어낸 클래스의 인스턴스이다. 그러니까 지금 이 윈도우이다.
* 여기까지 자바 AWT 에 관한 내용을 7장으로 정리해봤다. 아직 많은 세부적인 토픽이 남아있겠지만, AWT는 어찌보면 과거의 유물처럼 되가고 있기 때문에 이 정도로 커버해야 할 것 같다. 자바의 정석 저자인 남궁성 작가님도 AWT를 2판까지만 다루셨는데 지금은 무료로 배포하고 있으니 관심있는 사람은 참고하면 좋을 것 같다. 집필하려고 만드신 것이라 분량도 100페이지가 넘는다. 역시 대단하신 분 같다. 괜히 베스트셀러 작가가 아님.
https://codechobo.tistory.com/6