1. 과제 안내문
다음과 같이 On 혹은 Off 버튼을 누르면 출입문과 창문의 색상이 변경되는 JFrame 애플리케이션을 작성하라. 출입문과 창문이 처음에는 집과 같은 회색이다가 On 버튼이 눌리면 노란색으로 바뀌고, Off 버튼을 누르면 다시 회색으로 바뀐다. 최대한 아래 그림과 동일하게 완성하라. 집과 출입문 등은 paint 메소드에서 그린다. 하단의 버튼 2개는 JPanel(FlowLayout)에 넣고 그 JPanel을 내용창(BorderLayout)의 하단("South")에 배치하면 된다. 스윙 컴포넌트와 paint 메소드가 둘 다 필요한 프로그램이므로, 유사한 구조를 가지는 LightOnOffExample 클래스를 참고하여 작성하라.
우리 학교의 java교수님은...... 그래픽을 너무 좋아하신다...... 물론 C언어와 비슷한 문법을 가진 java에서(기본적인 연산이나 반복문) java를 활용한 GUI제작을 선호하시는 방식은 어찌보면 좋은 일이지만...... C++을 배우지도 않은 상황에서(학교 커리큘럼상) 처음 맞는 객체지향 프로그래밍 언어로 GUI를 경험하다니...... "대면이었으면 이리 어렵진 않았으려나... ..."라는 생각도 든다. 일단 저렇게 안내문만 보면 뭔지 뭘 만들라는 건지 모르겠지만 실행 예시를 보면 알 수 있다.
2. 시행 결과 예시
하하.... 일단 paint를 이용하여 저 모양을 잡는 것부터 무서웠다...... 그리고 ActionListener을 이용한 이벤트 처리...... 한숨 나왔다......
3. 코드 제작
일단 코드 작성의 순서를 간략하게 작성하자면
- 그래픽 작성
- 이벤트 객체 생성
- 그래픽 레이아웃 설정 및 객체 추가
- 그래픽 구성
public void paint(Graphics g) {
int xpoints[] = {350, 150, 150, 550, 550};
int ypoints[] = {100, 250, 400, 400, 250};
int npoints = 5;
Graphics2D g2d = (Graphics2D)g;
g2d.setStroke(new BasicStroke(2));
g.setColor(Color.GRAY);
g.fillPolygon(xpoints,ypoints,npoints);
if(isOn) {
g.setColor(Color.BLACK);
g.drawRect(250,250,100,150);
g.drawRect(400,230,70,70);
g.setColor(Color.yellow);
g.fillRect(250,250,100,150);
g.fillRect(400,230,70,70);
}else {
g.setColor(Color.BLACK);
g.drawRect(250,250,100,150);
g.drawRect(400,230,70,70);
}
g.setColor(Color.BLACK);
g.drawLine(435, 230, 435, 300);
g.drawLine(400, 265, 470, 265);
}
일단 내가 선택한 알고리즘은 On을 눌렀을 때, 노란색의 도형을 그리고, Off를 눌렀을 때 검은 선을 가지는 사각형들을 그리는 것이다. 굳이 이런걸 선택한 이유는 바꾸는걸 몰라서...... ㅎㅎ 그리고 event 를 실행하는 객체와 paint가 연결되어야 하는 상황에서 같은 class내에 private변수 하나를 선언하여 그것을 매개체로 on버튼과 off버튼의 클릭 여부를 구분하였다.
- 이벤트 객체 생성
public class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
if(e.getSource() == on) isOn = true;
else isOn = false;
repaint();
}
}
이벤트 객체에서는 별로 할게 없었다... 말 그대로 버튼의 유무에 따라 isOn의 값을 바꿔주고 paint를 한번 더 실행해주기만 하면 됐기 때문이다. (물론 implements와 같은 문법은 완벽하게 이해하지 못했지만...... 다음 강의 때 알려준다고 하셨으니 넘어갔다 ㅎㅎ)
- 그래픽 레이아웃 설정 및 버튼과 객체 추가
public Hw1() {
setTitle("Hw1");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(700, 500);
Container cPane = getContentPane();
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
on.addActionListener(new ButtonListener());
off.addActionListener(new ButtonListener());
panel.add(on);
panel.add(off);
cPane.add(panel, BorderLayout.SOUTH);
}
이 클래스의 이름은 Hw1이기 때문에 성성자에서 size와 title을 모두 정해주었다. 버튼을 두개를 하나로 묶기 위해 panel객체를 따로 만들어 주어 버튼 두개를 추가하였고 버튼마다 이벤트 객체를 추가하였다. 패널을 container안에 넣어주고 layout을 BorderLayout의 지정하여 SOUTH로 지정하여 맨 밑에 들어갈 수 있게 설정하였다.
- 전체 소스코드
package testForLecture;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Hw1 extends JFrame{
private boolean isOn = false;
JButton on = new JButton("on");
JButton off = new JButton("off");
public Hw1() {
setTitle("Hw1");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(700, 500);
Container cPane = getContentPane();
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
on.addActionListener(new ButtonListener());
off.addActionListener(new ButtonListener());
panel.add(on);
panel.add(off);
cPane.add(panel, BorderLayout.SOUTH);
}
public void paint(Graphics g) {
int xpoints[] = {350, 150, 150, 550, 550};
int ypoints[] = {100, 250, 400, 400, 250};
int npoints = 5;
Graphics2D g2d = (Graphics2D)g;
g2d.setStroke(new BasicStroke(2));
g.setColor(Color.GRAY);
g.fillPolygon(xpoints,ypoints,npoints);
if(isOn) {
g.setColor(Color.BLACK);
g.drawRect(250,250,100,150);
g.drawRect(400,230,70,70);
g.setColor(Color.yellow);
g.fillRect(250,250,100,150);
g.fillRect(400,230,70,70);
}else {
g.setColor(Color.BLACK);
g.drawRect(250,250,100,150);
g.drawRect(400,230,70,70);
}
g.setColor(Color.BLACK);
g.drawLine(435, 230, 435, 300);
g.drawLine(400, 265, 470, 265);
}
public class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
if(e.getSource() == on) isOn = true;
else isOn = false;
repaint();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
(new Hw1()).setVisible(true);
}
}
main에서는 별로 할 일이 없었다. 그저 새로운 class를 생성하고 setVisible에 true값만을 넣어주면 끝나기 때문이다. button을 전역 변수로 선언한 이유는ButtonListener Class에서 Button의 값으로 isOn변수의 값을 정하기 때문이다.
- 실행 결과
다음은 실행 결과이다. 선의 굵기가 조금 다른 것 같지만 이런걸로 감점하시면...... 아마 울듯......
4. 결어
사실 나는 java를 잘하는 편이 아니다. (C++도 잘 하는 편은 아니다 ㅎ) 심지어 C++도 학교 과정에서 들은 것이 아니라 개인적으로 자료구조를 공부할 때 자료구조를 전부 C++의 Class로 구현하는 서적 때문에 그때그때 구글링을 했을 뿐 깊이 알지는 못한다. 그렇다고 내가 지금 java에 거부감이 드는것이 객체 지향의 특성이라고 하기는 어렵다...... 100% 아니라고 하지는 못하지만 아마 GUI구현과 객체지향 언어의 특성이 합쳐져서 이런 멀미가 나는 것이라고 예측해본다. 고백하자면 아직도 paint와 이벤트 객체를 완벽하게 이해하지는 못했다...... 이들을 완벽이 이해하여 꼭 이 블로그에 나의 설명을 올릴 수 있기를 바란다!
'대학교 과제 > Java [ 2 - 1 ]' 카테고리의 다른 글
[Java 과제] - 12주차 ( Arrays.sort() ) (0) | 2020.06.02 |
---|---|
[Java 과제] - 11주차 (0) | 2020.06.02 |
Java 10주차 과제 - 상속 (0) | 2020.05.13 |