Java

[Java] Window Adapter 윈도우 어댑터 / Inner Class (Member, Static, Local, Anonymous) / 윈도우 창 응용 (버튼 50개, 구구단)

소댓 2023. 3. 22. 19:37

* Window Adapter 윈도우 어댑터

 

- 창 닫기 위해 매번 override 하면 불필요한 내용도 다 써야 하는 게 불편..

> 해결되기 위해서 나온 게 '윈도우 어댑터'

 

* 이름이 없는 클래스 : Anonymous InnerClass
클래스의 선언과 객체의 생성을 동시에 하는 이름 없는 클래스
WindowAdapter wa = new WindowAdapter() { // 상속 받은 자식을 사용
@Override
public void windowClosing(WindowEvent e) {
System.out.println("종료합니다.");
System.exit(0);
}
};

 

- WindowListener를 구현한 구현 객체

addWindowListener(wa); 

 

- 위의 두 개를 합치면,
addWindowListener (new WindowAdapter() { 
@Override
public void windowClosing(WindowEvent e) {
System.out.println("종료합니다.");
System.exit(0);
}
});

>> 상용구 추가 :  우측 마우스 클릭 > add to Snippets

 

 

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
package day15;
 
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
 
public class MyWin10 extends Frame {
 
    MyWin10() {
        
        // 창 종료
//        addWindowListener(this); 
        
        // java.awt.event > WindowAdapter
        // : 여러 개의 인터페이스를 비워놓은 채 구현해 놓음
//        WindowAdapter wa; = new WindowAdapter(); // 추상 클래스이기 때문에 인스턴스화 불가
        // Parent p = new Child();
        
        // WindowAdapter wa = 윈도우어댑터를 상속 받은 객체의 참조값;
//        WindowAdapter wa = new NewWindowAdapter(); // > 상속한 일반 클래스 만듦
        
        // 이름이 없는 클래스 : Anonymous InnerClass
        // 클래스의 선언과 객체의 생성을 동시에 하는 이름 없는 클래스
//        WindowAdapter wa = new WindowAdapter() { // 상속 받은 자식을 사용
//            @Override
//            public void windowClosing(WindowEvent e) {
//                System.out.println("종료합니다.");
//                System.exit(0);
//        }
//            };
        
//        addWindowListener(wa); // WindowListener를 구현한 구현 객체
        
        // 위의 두 개를 합치면,
        addWindowListener (new WindowAdapter() { 
                @Override
                public void windowClosing(WindowEvent e) {
                    System.out.println("종료합니다.");
                    System.exit(0);
            }
            });
        
        
        setBounds(100100800600);
        setVisible(true);
        
    }
    
    public static void main(String[] args) {
        MyWin10 mw = new MyWin10();
    }
 
 
    
//    @Override
//    public void windowOpened(WindowEvent e) {
//        // TODO Auto-generated method stub
//        
//    }
//
//    @Override
//    public void windowClosing(WindowEvent e) {
//        System.out.println("종료합니다.");
//        System.exit(0);
//        
//    }
//
//    @Override
//    public void windowClosed(WindowEvent e) {
//        // TODO Auto-generated method stub
//        
//    }
//
//    @Override
//    public void windowIconified(WindowEvent e) {
//        // TODO Auto-generated method stub
//        
//    }
//
//    @Override
//    public void windowDeiconified(WindowEvent e) {
//        // TODO Auto-generated method stub
//        
//    }
//
//    @Override
//    public void windowActivated(WindowEvent e) {
//        // TODO Auto-generated method stub
//        
//    }
//
//    @Override
//    public void windowDeactivated(WindowEvent e) {
//        // TODO Auto-generated method stub
//        
//    }
    
}
 
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
package day15;
 
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
 
public class MyWin11 extends Frame {
    
    MyWin11() {
            
        addWindowListener (new WindowAdapter() { 
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("종료합니다.");
                System.exit(0);
        }
        });
        setBounds(100100800600);
        setVisible(true);
    }
    
    
    public static void main(String[] args) {
        MyWin11 mw = new MyWin11();
    }
}
 
cs

 

 

 


 

< Inner class>

- 클래스 안에 포함되어 있는 클래스 : Inner Class

- private 변수에 접근하기 위해서 inner class 활용

 

 

* Member Inner Class

- Member 변수(전역변수)처럼 역할

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package day15;
// OuterClass 참고
public class TestMain {
    public static void main(String[] args) {
        // b = 20 이렇게 출력
        // 다른 클래스의 변수를 쓰려면 클래스의 이름이 와야 함
        System.out.println(" b = "+OuterClassEx1.b);
        
        // a = 10
        OuterClassEx1 oc = new OuterClassEx1();
//        System.out.println(oc.a); // a가 private 변수라서 외부에서 접근 불가
 
        // private 변수에 접근하기 위해서는? > inner class
         
    }
}
 
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
package day15;
// 클래스 안에 포함되어 있는 클래스 : Inner Class
// member Inner Class : member 변수처럼 역할
 
public class OuterClassEx1 {
 
    private int a = 10;
    static int b = 20;
    static final int c = 30;
    
    // inner class > 변수와 메서드 줄 수 있음
    // 그리고 private 변수에도 접근 가능!
    
    class InnerClass { 
        int d = 40;
//        static int e = 50; // 가질 수 없음
        static final int f = 60// 상수 형태이므로 사용 가능
        
        void print() {
            System.out.println(" a : " + a);
            System.out.println(" b : " + b);
            System.out.println(" c : " + c);
            System.out.println(" d : " + d);
//            System.out.println(" e : " + e);
            System.out.println(" f : " + f);
        } // print end
    } // InnerClass end
    
    public static void main(String[] args) {
        OuterClassEx1 oce = new OuterClassEx1();
        System.out.println(" Outer Class private 변수 a = "+oce.a);
        
        OuterClassEx1.InnerClass ic = oce.new InnerClass();
        ic.print();
    }
}
cs

 

 

 

* Static Inner Class

- 앞에 static을 붙이면 static inner class가 됨

- new 할 필요 없이 static 변수처럼 사용 가능

 

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
package day15;
// Static Inner Class : inner 클래스가 static 변수처럼 사용
public class OuterClassEx2 {
 
 
    private int a = 10;
    static int b = 20;
    static final int c = 30;
    
    // static inner class : new 할 필요 없이 static 변수처럼 사용 가능
    static class InnerClass2 { // 앞에 static을 붙이면 static inner class가 됨
        int d = 40;
        static int e = 50;
        static final int f = 60;
        
        void print() {
            System.out.println("static inner class");
//            System.out.println(" a : " + a); // static 클래스이기 떄문에 static이 아닌 변수는 접근해서는 안됨
            System.out.println(" b : " + b);
            System.out.println(" c : " + c);
            System.out.println(" d : " + d);
            System.out.println(" e : " + e);
            System.out.println(" f : " + f);
        } // print() end
        
    }
    public static void main(String[] args) {
        InnerClass2 ic = new InnerClass2();
        ic.print();
    }
}
cs

 

 

 

* Local Inner Class

- 지역변수처럼 사용되는 class

- 메서드가 끝나면 변수가 사라지기 때문에(지역변수)

  포함된 class가 끝나기 전에,  new도 하고(인스턴스화), 실행도 해야 함

 

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
package day15;
// Local Inner Class : 지역변수처럼 사용되는 class
public class OuterClassEx3 {
 
    private int a = 10;
    static int b = 20;
    static final int c = 30;
    
    public void printAll() {
        int k = 0// 지역변수
        class LocalInnerClass { // 변수와 메서드 new 해야 사용 가능
            int d = 40;
//            static int e = 50; // 독립적으로 실행하는 static 변수는 실행이 안됨
            static final int f = 60;
            
            void print() {
                System.out.println("static inner class");
                System.out.println(" a : " + a); 
                System.out.println(" b : " + b);
                System.out.println(" c : " + c);
                System.out.println(" d : " + d);
//                System.out.println(" e : " + e);
                System.out.println(" f : " + f);
                
            } // print() end
        } // LocalInnerClass end
        
        // printAll class가 끝나기 전에,
        LocalInnerClass lic = new LocalInnerClass(); // new도 하고(인스턴스화),
        lic.print(); // 실행도 해야 함
        // 메서드가 끝나면 변수가 사라지기 때문에(지역변수)
        
    } // printAll() end
    
    
        public static void main(String[] args) {
            OuterClassEx3 oce3 = new OuterClassEx3(); // 클래스 생성
            oce3.printAll(); // 메서드 호출
        }
    
// OuterClassEx3 class end
cs

 

 

+) 이름이 없는 클래스 : Anonymous InnerClass
클래스의 선언과 객체의 생성을 동시에 하는 이름 없는 클래스

 


 

[ KeyListener ]

 

* 키보드 방향키 누르면 버튼이 움직이는 윈도우 창 > keyPressed

 

 

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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package day15;
 
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
 
public class ButtonControl extends Frame implements KeyListener{
    
    Button btn; // 멤버변수
    int a; // ButtonControl의 멤버변수 a
    
    ButtonControl(){
        
        int a; // 메서드의 지역변수 a
        a = 10// > 지역변수.. 자바는 가장 가까운 것을 참조하기 때문
        // 하지만 해당 생성자를 빠져 나가는 순간 지역변수 a는 사라져서 멤버변수 a = 0이 됨
        this.a = 10// 전역변수 a에 값을 주는 법
        
        // 배치 관리자 안씀
        setLayout(null);
        
        addWindowListener (new WindowAdapter() { 
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("종료합니다.");
                System.exit(0);
        }
        });
        
        // 컴포넌트 초기화
        btn = new Button("^^"); // 앞에 this.가 생략됨! (전역변수이기 때문에)
//        Button btn = new Button("^^") // 이렇게 쓰면 지역변수라서 생성자 안에서만 의미 있음.. 따라서, 오류가 뜸!
        // 자료형 변수
        
        // 이벤트 처리
        // 1. 이벤트 소스 : btn
        // 2. 리스너 추가 : KeyListener(키보드 감지)
        btn.addKeyListener(this);
        
        // 버튼 크기, 위치 조절
        btn.setBounds(3505006060);
        
        // 프레임에 부착
        add(btn);
    
        
        setBounds(2002001000800);
        setVisible(true);
        
    }
    public static void main(String[] args) {
        ButtonControl bc = new ButtonControl();
    }
    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void keyPressed(KeyEvent e) {
//        System.out.println("키보드 눌림");
        int code = e.getKeyCode();
        System.out.println(code);
        // 37 38 39 40
        // 현재 버튼의 위치
        int x = btn.getX();
        int y = btn.getY();
        
        // 왼쪽 방향키를 누를 때 버튼은 왼쪽으로 보내기
        if(code == 37) {
            x -= 3;
        } else if (code == 39) {
        // 오른쪽 방향키를 누를 때 버튼을 오른쪽으로 보내기
            x -= 3;
        } else if (code == 38) {
            y += 3;    
        } else if (code == 40) {
            y += 3;
        } else if (code == 32) {
            // 점프 기능
            // 오르기
            for (int i = 0; i <30; i++) {
                y -= 4;
                btn.setLocation(x, y);
                
                // 잠시 멈췄다가 실행되는 기능
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } // 1000분의 1초
            }
            
            // 하강
            for (int i =0; i < 30; i++) {
                y += 4;
                btn.setLocation(x, y);
            
                // 잠시 멈췄다가 실행되는 기능
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } // 1000분의 1초
            }
            
        }
        btn.setLocation(x, y);
        
    }
    @Override
    public void keyReleased(KeyEvent e) {
//        System.out.println("키보드에 손을 뗄 때 호출");
    }
 
}
cs

 

 


 

[ 응용 ]

 

Q01. 버튼 50개 생성

창크기 : 800, 600

위치 : 50, 50

배치관리자 : FlowLayout 을 사용해서 버튼 50개 생성하여 창에 부착

>> 버튼 배열로 (Button[] )

 

 

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
package day15;
 
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
 
public class Day15Q02 extends Frame{
 
    Button[] btnArray; 
    
    
    Day15Q02(){
        FlowLayout f1 = new FlowLayout();
        setLayout(f1);
        
        btnArray = new Button[50];
        for(int i = 0; i<btnArray.length; i++) {
            btnArray[i] = new Button("button"+(i+1));
            add(btnArray[i]);
        }
        
        addWindowListener (new WindowAdapter() { 
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("종료합니다.");
                System.exit(0);
        }
        });
        setBounds(5050800600);
        setVisible(true);
    }
    public static void main(String[] args) {
        Day15Q02 d = new Day15Q02();
    }
    
}
 
cs

 

 

 

Q03. 구구단 출력

 

 

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
package day15;
 
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
 
public class Day15Q03 extends Frame implements ActionListener {
 
    
    TextField tf;
    Label lb;
    Button btn;
    
    Day15Q03() {
        
        // 배치관리자 없이
        setLayout(null);
        
        tf = new TextField();
        lb = new Label("단");
        btn = new Button("PRINT");
        
        // 컴포넌트 크기와 위치 지정
        tf.setBounds(100,  50,  100,  30);
        lb.setBounds(250,  50,  100,  30);
        lb.setBackground(Color.red);
        btn.setBounds(12020020080);
        
        // event 처리
        // 1. event source : btn
        // 2. ActionListener 를 부착
        btn.addActionListener(this);
        // 3. 핸들러 객체 정의
        
        add(tf);
        add(lb);
        add(btn);
        
        addWindowListener (new WindowAdapter() { 
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("종료합니다.");
                System.exit(0);
        }
        });
        
        setBounds(300300450450);
        setVisible(true);
        
    }
    
    public static void main(String[] args) {
        
        Day15Q03 d = new Day15Q03();
        
    }
 
    @Override
    public void actionPerformed(ActionEvent e) {
//        System.out.println("버튼 눌림");
        String d = tf.getText();
        // 문자열 d를 정수로 바꿔줌
        int dan = Integer.parseInt(d);
        for(int i = 0; i<=9; i++) {
            System.out.println(dan+" * "+i+" = "+dan*i);
        }
        
    }
}
 
cs