안녕하세요.


진도를 잘 따라오고 계신가요? ㅎ


지금까지의 코드는 아래와 같습니다.



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
// Study01.java
 
package study;
 
import java.awt.Font;
import java.util.Enumeration;
 
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.plaf.FontUIResource;
 
public class Study01 {
 
    // 빈 슬라임 변수
    static Slime s = null;
 
    public static void main(String[] args) {
 
        // 라벨 변수 선언
        JLabel lbl;
 
        // 슬라임과 인간 객체 생성
        Slime s1 = new Slime("슬라삐");
        Slime s2 = new Slime("슬라디");
        Human h = new Human("알렉스");
 
        // 모든 글꼴 통일
        Enumeration<Object> keys = UIManager.getDefaults().keys();
        while (keys.hasMoreElements()) {
            Object key = keys.nextElement();
            Object value = UIManager.get(key);
            if (value instanceof FontUIResource)
                UIManager.put(key, new FontUIResource("굴림", Font.PLAIN, 14));
        }
 
        // [start] 프레임 설정
        JFrame frm = new JFrame();
        frm.setTitle("슬라임 퇴치하기");
        frm.setSize(350300);
        frm.setLocationRelativeTo(null);
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.getContentPane().setLayout(null);
        // [end]
 
        // 버튼 설정
        JButton btn1 = new JButton(s1.name);
        JButton btn2 = new JButton(s2.name);
        btn1.setBounds(3017012230);
        btn2.setBounds(18217012230);
        frm.getContentPane().add(btn1);
        frm.getContentPane().add(btn2);
 
        // 라벨 설정
        lbl = new JLabel();
        lbl.setBounds(3020027450);
        lbl.setText("게임을 시작합니다");
        lbl.setHorizontalAlignment(JLabel.CENTER); // 수평 가운데 정렬
        frm.getContentPane().add(lbl);
 
        // [start] 이미지 라벨 생성
        JLabel imgLbl = new JLabel();
        ImageIcon bsImg = new ImageIcon(Study01.class.getResource("/study/img/slime(blue).png"));
        imgLbl.setIcon(bsImg);
        imgLbl.setBounds(3030122130);
        imgLbl.setHorizontalAlignment(JLabel.CENTER);
        frm.getContentPane().add(imgLbl);
        // [end]
 
        // [start] 이미지 라벨2 생성
        JLabel imgLbl2 = new JLabel();
        imgLbl2.setIcon(bsImg);
        imgLbl2.setBounds(18230122130);
        imgLbl2.setHorizontalAlignment(JLabel.CENTER);
        frm.getContentPane().add(imgLbl2);
        // [end]
 
        // 프레임이 보이도록 설정
        frm.setVisible(true);
 
        // 버튼을 눌렀을때
        btn1.addActionListener(event -> {
            s = s1;
 
        });
 
        btn2.addActionListener(event -> {
            s = s2;
        });
 
        System.out.println(s.name);
    }
 
}
 
cs


아직 실행하지는 마시구요, 마지막 부분을 다시한번 봅시다.






버튼을 눌렀을때 작동하는 코드를 맨 아래쪽으로 옮겼습니다. 이러한 특수한 코드가 디자인 코드속에 섞여 있으면 가독성이 떨어지니까요.


아무튼 위 코드의 의도는 버튼을 누르면 해당하는 객체가 변수 s에 할당이 되어서 콘솔창에 그 이름이 표시되게 하는 것입니다.


실행해볼까요?






웁스~ 실행하자마자 93행에 에러가 났다고 빨간 글씨가 뜨네요. 버튼을 클릭해도 아무 반응이 없습니다.


왜그럴까요? 93행을 아래와 같이 수정하고 실행하면 감이 잡히실 겁니다.



System.out.println(1);



실행해봅시다.






버튼을 누르기도 전에 1이 뜨네요. 이게 중요합니다. 


일반적으로 코드는 위에서 아래로 순서대로 실행되지만 '버튼을 눌렀을때', '마우스를 갖다댔을때', '특정키를 눌렀을때' 같은 이벤트(한국말로 사건) 코드는 그 사건이 발생했을때 실행됩니다.





따라서 버튼을 눌렀을때의 코드보다 93행이 먼저 실행이 된다는거죠. 변수 s에 아무것도 할당되어 있지 않으니 에러가 나는게 당연합니다.


슬라임의 이름을 보려면 아래와 같이 수정해야겠죠.





1
2
3
4
5
6
7
8
9
10
        // 버튼을 눌렀을때
        btn1.addActionListener(event -> {
            s = s1;
            System.out.println(s.name);
        });
 
        btn2.addActionListener(event -> {
            s = s2;
            System.out.println(s.name);
        });
cs

(행번호는 무시하세요)


콘솔출력을 액션 함수 속에 넣으니 잘 되는군요^^




그런데 그렇다면 우리는 아래처럼 코딩할 수 밖에 없을까요?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        // 버튼을 눌렀을때
        btn1.addActionListener(event -> {
            s = s1;
            
            // 슬라임이 살아있을때만 공격
            // ...
            
            // 슬라임이 모두 죽으면 게임 클리어
            // ...
            
        });
 
        btn2.addActionListener(event -> {
            s = s2;
            
            // 슬라임이 살아있을때만 공격
            // ...
            
            // 슬라임이 모두 죽으면 게임 클리어
            // ...
        });
cs

(행번호는 실제 행번호와 다릅니다)


똑같은 내용을 2번 적어줘야 되니 중복이네요. 슬라임이 10마리라면 10번... ㄷ ㄷ 애초에 s변수를 만들어준 의미가 없어졌네요.


좋은 방법이 없을까요? 답은 의외로 간단합니다. 다음 시간에 알아보죠.


감사합니다.

+ Recent posts