순천향대 JAVA프로그래밍LAB 7주차 레포트
Problem 1
Animal 인터페이스를 구현(implements)하는 강아지, 고양이, 새 클래스를 작성해야 한다.
인터페이스는 메소드가 전부 추상메소드이므로 구현할 메소드에 오버라이딩을 통해 메소드를 완성시켜야 한다.
//구현을 위한 인터페이스 생성
interface Animal{
void makeSound();
}
//Dog 클래스
class Dog implements Animal{
@Override
public void makeSound() { //미정의된 메소드를 재정의 함.
System.out.println("멍멍!");
}
}
//Cat 클래스
class Cat implements Animal{
@Override
public void makeSound() { //미정의된 메소드를 재정의 함.
System.out.println("야옹~");
}
}
//Bird 클래스
class Bird implements Animal{
@Override
public void makeSound() { //미정의된 메소드를 재정의 함.
System.out.println("짹짹!");
}
}
public class Animal_Test {
public static void main(String[] args) {
//각 객체를 생성하고 메소드를 호출한다.
Animal dog = new Dog();
dog.makeSound();
//각 객체를 생성하고 메소드를 호출한다.
Animal cat = new Cat();
cat.makeSound();
//각 객체를 생성하고 메소드를 호출한다.
Animal bird = new Bird();
bird.makeSound();
}
}
위 코드를 통해 각 Animal을 구현하는 클래스를 생성한 후 메소드를 재정의 하였다.
메인함수에서 각 객체를 생성했으며, 해당 객체의 메소드를 호출하였다.
실행결과
Problem 2
위 코드를 실행하게 되면 설정자로 입력한 크기의 윈도우가 만들어지게 된다.
이제 위 코드를 상속받은 코드로 재작성을 해보겠다.
class MyFrame extends JFrame{
public MyFrame() {
super("My GUI");
super.setSize(600, 400);
super.setLayout(null);
super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
super.setVisible(true);
}
}
상속을 통해 JFrame을 상속받는 MyFrame 클래스를 생성하였다.
위 코드를 통해 실행한다면 위와 똑같은 윈도우 창을 생성하게 된다.
Problem 3
2번에서 생성한 윈도우에 원을 그리는 코드를 작성해야 한다.
그림을 그리려면 JFrame의 paint 메소드를 사용하면 된다.
//JFrame을 상속받은 MyFrame 클래스 생성
class MyFrame extends JFrame{
//생성자
public MyFrame() {
super("My GUI"); //윈도우의 이름
super.setSize(600, 400); //윈도우의 크기
super.setLayout(null); //레이아웃 설정
//x창을 눌렀을 때 기능설정
super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
super.setVisible(true); //창 띄우기
}
//paint 메소드 재정의
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.RED); //색은 빨간색으로 설정
g.fillOval(100, 100, 200, 200); //해당 크기의 속이 찬 원 생성
g.drawRect(100, 100, 200, 200); //해당 크기의 사각형 생성
}
}
public class MyGUI {
public static void main(String[] args) {
new MyFrame(); //객체 생성
}
}
원을 그리기 위해 paint 메소드를 오버라이딩하여 재정의 해주었다.
그렇게 내가 원하는 그림을 그릴 수 있게 되었으며 각 명령어를 통해 원하는 도형을 그릴 수 있게 되었다.
해당 코드를 통해 원 뿐만 아니라 원과 동일한 크기를 가진 사각형도 그리는 코드를 작성했다.
실행결과
Problem 4
문제에서 버튼을 생성하는 코드를 제시해 주었다.
class CounterExample extends JFrame {
private int count = 0;
private JLabel countLabel; //레이블 정보를 담을 필드 선언
public CounterExample() {
super.setTitle("Counter Example");
super.setSize(300, 200);
super.setDefaultCloseOperation(EXIT_ON_CLOSE);
//생성한 레이블 변수에 해당 정보를 담은 객체를 저장한다.
countLabel = new JLabel("Count: " + count);
add(countLabel);
//해당 JButton 객체를 생성한다.
JButton incrementButton = new JButton("+");
JButton decrementButton = new JButton("-");
//여기서 FlowLayout을 사용하여 레이블을 정렬하였다.
setLayout(new FlowLayout());
//생성한 버튼 객체를 윈도우에 추가한다.
add(incrementButton);
add(decrementButton);
}
}
public class practice {
public static void main(String[] args) {
new CounterExample().setVisible(true);
}
}
해당 코드를 보면 JLabel을 사용하여 버튼 옆 문자를 표현하기 위해 레이블을 만들어야 한다.
레이블을 만들기 위해서는 우선 JLabel 자료형의 필드를 생성해야 한다.
해당 필드를 통해 객체를 생성하고 매개변수로 작성하고 싶은 문자열을 전달하면 된다.
위 코드를 보면 레이아웃을 설정하는 설정자가 존재했다.
여기서 우리는 해당 레이블을 정렬하기 위해 FlowLayout을 사용하여 레이블을 정상적으로 윈도우에 출력할 수 있다.
다음은 버튼을 만들어야 한다.
버튼도 마찬가지로 객체를 만든 후 add를 통해 윈도우에 추가하면 된다.
실행결과
이처럼 해당 코드를 통해 버튼과 레이블을 추가하였다.
Problem 5
해당 문제는 ActionListener 인터페이스를 구현한 내부 클래스를 작성한 후 객체를 생성하여 액션 리스너 등록을 하면 된다.
class CounterExample extends JFrame {
private int count = 0;
private JLabel countLabel;
public CounterExample() {
super.setTitle("Counter Example");
super.setSize(300, 200);
super.setDefaultCloseOperation(EXIT_ON_CLOSE);
countLabel = new JLabel("Count: " + count);
add(countLabel);
JButton incrementButton = new JButton("+");
JButton decrementButton = new JButton("-");
// 내부 클래스 정의
class IncrementButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
count++;
countLabel.setText("Count: " + count);
}
}
class DecrementButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
count--;
countLabel.setText("Count: " + count);
}
}
// 내부 클래스 인스턴스 생성 및 액션 리스너 등록
ActionListener incrementListener = new IncrementButtonListener();
incrementButton.addActionListener(incrementListener);
ActionListener decrementListener = new DecrementButtonListener();
decrementButton.addActionListener(decrementListener);
setLayout(new FlowLayout());
add(incrementButton);
add(decrementButton);
}
}
public class practice {
public static void main(String[] args) {
new CounterExample().setVisible(true);
}
}
우리가 원하는 이벤트 처리는 +버튼을 누르면 count 1 증가, -버튼을 누르면 count 1감소하는 이벤트들이다.
버튼을 누르면 레이블의 count 숫자가 변경되어야 한다.
그렇기에 두 이벤트를 처리하기 위해서 ActionListener 인스턴스를 구현하는 클래스를 두개 생성한다.
이 후에 actionPerformed 메소드를 오버라이드 하여 내가 원하는 동작을 구현하면 된다.
우선 버튼을 누르면 count를 증감시키기에 count에 증감연산자를 작성하고, 레이블을 수정하기 위해 setText 메소드를 사용하여 레이블 문구를 수정한다.
이제 해당 클래스를 사용하기 위해 객체를 생성해야 한다.
여기서는 업캐스팅을 사용하여 객체를 생성한다.
업캐스팅 이후에는 버튼 객체의 addActionListener 메소드를 사용하여 버튼을 누를 시 이벤트를 처리하게 만들어 준다.
<버튼>.addActionListener(수행할_이벤트_객체명)
실행결과
Problem 6
내부 클래스로 작성한 위 코드를 내부 클래스로 변경하여 문제를 해결한다.
class CounterExample extends JFrame {
private int count = 0;
private JLabel countLabel;
public CounterExample() {
super.setTitle("Counter Example");
super.setSize(300, 200);
super.setDefaultCloseOperation(EXIT_ON_CLOSE);
countLabel = new JLabel("Count: " + count);
add(countLabel);
JButton incrementButton = new JButton("+");
JButton decrementButton = new JButton("-");
//익명 클래스 생성
incrementButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
count++;
countLabel.setText("Count: " + count);
}
});
//익명 클래스 생성
decrementButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
count--;
countLabel.setText("Count: " + count);
}
});
setLayout(new FlowLayout());
add(incrementButton);
add(decrementButton);
}
}
public class practice {
public static void main(String[] args) {
new CounterExample().setVisible(true);
}
}
익명 클래스를 사용하여 코드를 작성하였다.
addActionListener 메소드의 매개변수 안에서 익명 클래스를 생성하였다.
내부 클래스에서 생성할 때 사용하였던 메소드들을 해당 부분에 작성하고 ')'를 반드시 유의하여 닫아주어야 한다.
실행결과는 동일하게 출력되어 생략하겠다.
Problem 7
문제 3에서 만들었던 원을 버튼을 통해 이동시키는 코드를 작성해야 한다.
class CounterExample extends JFrame{
private int count = 0;
private JLabel countLabel;
private JButton incrementButton;
private JButton decrementButton;
int x1 = 50;
int x2 = 170;
public CounterExample() {
super.setTitle("Counter Example");
super.setSize(300, 200);
super.setLayout(null);
super.setDefaultCloseOperation(EXIT_ON_CLOSE);
countLabel = new JLabel("Count: " + count);
incrementButton = new JButton("+");
decrementButton = new JButton("-");
setLayout(new FlowLayout());
add(countLabel);
add(incrementButton);
add(decrementButton);
addActionListeners(); // 이 메서드를 호출하여 이벤트 리스너를 추가
}
private void addActionListeners() {
incrementButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
x1 += 20;
x2 += 20;
repaint();
updateCounterLabel();
}
});
decrementButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
x1 -= 20;
x2 -= 20;
repaint();
updateCounterLabel();
}
});
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.RED);
g.fillOval(x1, 100, 100, 100);
g.fillOval(x2, 100, 100, 100);
}
private void updateCounterLabel() {
countLabel.setText("Count: " + count);
}
}
public class MyGUI {
public static void main(String[] args) {
new CounterExample().setVisible(true);
}
}
위 코드에서 addActionListeners 함수를 생성하여 필요한 동작 및 이벤트들을 생성하였다.
해당 함수 내에서 두개의 원과 버튼을 생성하고 특정 위치에 원을 위치시킨다.
그렇게 버튼을 누르면 x좌표가 20씩 증감되게 이벤트를 생성한 다음 버튼에 할당하였다.
실행결과