<연습문제>
피보나치 수열을  a1, a2, a3, a20항까지 출력하는 프로그램을 
작성하시오
<예제1-1>
package com.week2;
// 모든 클래스는 object를 상속받고 있어서 부모가 가진 메소드를 
// 호출할 수 있고 재정의(메소드 오버라이딩)할 수도 있다
// 자바는 같은 이름의 메소드를 중복정의 가능하다
// 메소드 오버로딩
// 메소드 오버라이딩(단, 상속관계인지 따져야 한다)
public class Car extends Object {

	public static void main(String[] args) {
		Car myCar = new Car();
		System.out.println(myCar); // 주소번지 출력
		// Car 클래스에는 toString()메소드를 정의하지 않았지만
		// 부모가 정의하고 있는 메소드라서 나는 호출할 수 있다
		System.out.println(myCar.toString()); // 주소번지 출력 
		// toString 정의 안했는데? -> Object 상속받았으니까~
	}
}
<예제1-2>
package com.week2;
// 모든 클래스는 object를 상속받고 있어서 부모가 가진 메소드를 
// 호출할 수 있고 재정의(메소드 오버라이딩)할 수도 있다
// 자바는 같은 이름의 메소드를 중복정의 가능하다
// 메소드 오버로딩
// 메소드 오버라이딩(단, 상속관계인지 따져야 한다)
public class Car extends Object {
	int speed = 0;
	String carColor = "검정색";
	int wheelNum = 4;
	// 부모가 가진 메소드는 쉐도우메소드이다.
	// 모든 클래스는 Object클래스를 상속받고 있어서 부모가 가진 메소드를 그대로 사용할 수 있고
	// 원한다면 재정의해서 기능에 변화를 줄 수도 있다.
	// 이럴 경우 부모가 정의한 메소드는 가려진다.
	@Override //annotation
	public String toString() {
		return "당신의 자동차는 현재 "+speed+"로 달리고 있는 바퀴수는 "+wheelNum+"이고 색상은 "+carColor+"입니다.";
	}
	public static void main(String[] args) {
		Car myCar = new Car();
		System.out.println(myCar); // 주소번지 출력
		// Car 클래스에는 toString()메소드를 정의하지 않았지만
		// 부모가 정의하고 있는 메소드라서 나는 호출할 수 있다
		System.out.println(myCar.toString()); // 주소번지 출력 
		// toString 정의 안했는데? -> Object 상속받았으니까~
	}
}
<예제2-랜덤으로 숫자 뽑기>
package com.week2;

import java.util.Random;

// 사용자클래스와 자바제공 클래스 - 2개를 가지고 연습하시오
// 사용자클래스도 당연히 해당되는 것. 사용자클래스와 사용자클래스 - 2개를 선언해서 훈련하기
// 인스턴스화이다 -> 클래스와 클래스 관계
// 그다음 스텝은 업무를 나누어준다. 나신입/나초보 -> 업무 분장 -> 형상관리 해야 함 -> 잘 하려면 Git 도구 활용
// 이런 버전 관리를 통해서 단위테스트를 하고, 이 단위테스트 하려면 테스트 시나리오가 필요하다->통합테스트까지 나가야 함
// 이런 테스트를 통해서 업무와 업무 사이의 관계를 확인 -> 칼퇴근
public class Random1 {

	public static void main(String[] args) {
		Random r = new Random(); // 내가 정의한 클래스가 아니야(그래서 import 함)->인스턴스화
		// 나는 두 번째 메소드 선택함(파라미터가 1개-메소드 오버로딩)
		// 메소드 호출시 리턴타입이 있는 메소드라면 왼쪽에 대입연산자를 사용할 수 있다.
		for(int i=0;i<10;i=i+1) {
			int s = r.nextInt(10); //0.0~10.0
		System.out.println(s);
		}
	}
}
<예제3-1>: 생성자 호출
package com.week2;

public class Pride {
	// 생성자 - 파라미터가 없는 생성자는 JVM이 대신 주입해줌 - 그래서 나는 안했음
	public Pride() {
		System.out.println("Pride()디폴트 생성자 호출 성공");
	}
	public static void main(String[] args) {
		Pride myCar = null; // 선언만 했다 - myCar의 타입만 결정되었다
		System.out.println(myCar); // 주소번지가 아닌 null로 출력. 가리키는 객체가 없다는 것(타입만 결정되고 실체가 없어~) 
		// -> 선언만 한다고 주소번지가 할당되지 않음 
		// 그러면 사용할 수 있을까? -> 안 되지. NullPointerException이 발생해서 안 돼.
		System.out.println(myCar.toString()); // 내 안에 없지만, 아빠 메소드 통해서 사용이 가능
		// 이것만 있으면 안 됨. myCar가 null이니까. 그래서 예외처리를 배워야 한다(나중에 배울 것임)
	}
}
<예제 3-2> 처리순서
package com.week2;

public class Pride {
	
	public Pride() { // 4 
		System.out.println("Pride()디폴트 생성자 호출 성공"); // 5
	} // 6
	public static void main(String[] args) { // 1
		Pride myCar = null; // 2
		myCar = new Pride(); // 생성도 하였다. -> 이때 주소번지가 결정되었다.
		// 3
		System.out.println(myCar.toString()); // 7
	}
}
<예제 4-1>-생성자호출 : 0출력
package com.week2;

public class Pride {
	int speed = 0; // 자동차가 전시장에 주차된 상태 상상
	public Pride() { 
		System.out.println("Pride()디폴트 생성자 호출 성공"); 
	} 
	public static void main(String[] args) {
		Pride myCar = null; 
		myCar = new Pride(); 
		System.out.println(myCar.toString());
		System.out.println(myCar.speed); // 0 출력 // 전변이니까 (int speed = 0;)
	}
}
<예제4-2>: 10출력
package com.week2;

public class Pride {
	int speed = 0; 
	public Pride() { 
		System.out.println("Pride()디폴트 생성자 호출 성공"); 
		speed = 10; // 왜 인스턴스 변수 없이도 접근이 가능한거죠?
	} 
	public static void main(String[] args) {
		Pride myCar = null; 
		myCar = new Pride(); // 여기서 생성, 주소번지 결정
		System.out.println(myCar.toString());
		System.out.println(myCar.speed); 
	}
}
<예제4-2>: 20출력
package com.week2;

public class Pride {
	int speed = 0; 
	public Pride() { 
		System.out.println("Pride()디폴트 생성자 호출 성공"); 
		speed = 10;
	} 
	public static void main(String[] args) {
		Pride myCar = null; 
		myCar = new Pride(); 
		System.out.println(myCar.toString());
		myCar.speed = 20; // 이걸 봐야한다. 전역변수만 이렇게 쓸 수 있다
        ~~speed = 20;~~ // 이렇게 하면 지변이 바뀌는 것
		~~speed = 30;~~ // static 영역 안에서 non-static 타입의 변수는 접근이 불가하다
		// 만일 가능하게 하려면 인스턴스변수.speed로 호출할 수 있다. 재정의할 수 있다. 초기화할 수 있다.
		System.out.println(myCar.speed); 
	}
}
<예제5>
package com.week2;

import javax.swing.JFrame;

public class JFrameTest1 extends JFrame {
	// 파라미터가 한 개도 없으니까 JVM이 대신 만들어줄 수 있다
	// 파라미터가 있으면 만들어줄 수 없다. 왜냐면 JVM이 임의로 정하면 안 되니까.
	public JFrameTest1() { // 파라미터가 없는 생성자를 디폴트 생성자라 함 // 3
		// 생성자 선언
		System.out.println("디폴트 생성자 호출"); // 4
	} // 5
	// 사용자 메소드 정의하기 - 화면을 출력하는 메소드 선언해 보기
	public void initDisplay() { // 7
		System.out.println("initDisplay 호출"); // 8
		// 내 안(JFrameTest1)에 선언된 메소드(setSize(int, int)가 아니다. 그럼 어디에?? JFrame에 있다. 누가? setSize가. 
		// this는 자바가 제공하는 수정자이고, 보통 자기 자신을 가리킬 때 사용함
		// 주로 전변과 지변의 이름이 같은 경우 구분하기 위해 개발자가 명시적으로 붙여준다.-생략하지 않는다. 왜? 직관적이라
		this.setSize(500,400); // 메소드호출이다 // 9
		this.setVisible(true); // 10
	} // 11
	// 
	public static void main(String[] args) { // 1
		JFrameTest1 jft = new JFrameTest1(); // 2
		jft.initDisplay(); // 6 // 12
	}
}
<예제6-1>
package com.week2;

import javax.swing.JFrame;

public class JFrameTest1 extends JFrame {
	public JFrameTest1() { 

		System.out.println("디폴트 생성자 호출"); 
	} 
	public void initDisplay() { 
		System.out.println("initDisplay 호출"); 
		this.setSize(500,400);
		this.setVisible(true); 
	}
	public void methodA() {
		System.out.println("methodA() 호출");
	}
	public static void main(String[] args) { 
		JFrameTest1 jft = new JFrameTest1(); 
		jft.initDisplay();
		jft.methodA();
	}
}
<예제6-2>
package com.week2;

import javax.swing.JFrame;

public class JFrameTest1 extends JFrame {
	public JFrameTest1() { 

		System.out.println("디폴트 생성자 호출");
		// 3. 여기로 옮기고 앞에 jft 뺀다
		initDisplay();
		methodA();
		// 생성자 안에서는 static이 없어서 인스턴스 변수 없이도 사용 가능함
	} 
	public void initDisplay() { 
		System.out.println("initDisplay 호출"); 
		this.setSize(500,400);
		this.setVisible(true); 
	}
	public void methodA() {
		System.out.println("methodA() 호출");
	}
	public static void main(String[] args) { 
		new JFrameTest1(); 
		// 1. 아래는 변수 이름이 없어서 에러 발생 - 변수이름 사용할 수 없다면 생성자 위치로 옮겨서 할 수 있다
		// jft.initDisplay();
		// jft.methodA();
		// 2. 그래서 위 두 줄을 
		// 변수 이름이 없으면 지역변수로 선언되어 참조되는 클래스를 다른 메소드에서 재사용이 불가능하다.
	}
}
<예제6-3> : 이런 식 별로
package com.week2;

import javax.swing.JFrame;

public class JFrameTest1 extends JFrame {
	public JFrameTest1() { 

		System.out.println("디폴트 생성자 호출");
		// 3. 여기로 옮기고 앞에 jft 뺀다
		initDisplay();
		methodA();
		// 생성자 안에서는 static이 없어서 인스턴스 변수 없이도 사용 가능함
	} 
	public void initDisplay() { 
		System.out.println("initDisplay 호출"); 
		this.setSize(500,400);
		this.setVisible(true); 
	}
	public void methodA() {
		System.out.println("methodA() 호출");
	}
	public static void main(String[] args) { 
		new JFrameTest1(); 
		new JFrameTest1().methodA();
		// initDisplay 2번 호출. 이런 식 코드 별로다..
	}
}
<예제6-4>
package com.week2;

import javax.swing.JFrame;

public class JFrameTest1 extends JFrame {
	public JFrameTest1() { 

		System.out.println("디폴트 생성자 호출");
		// 3. 여기로 옮기고 앞에 jft 뺀다
		initDisplay();
		// 아래 메소드는 이름은 같지만 파라미터의 개수가 달라서 다른 메소드로 인지함
		// methodA(); // 다른 메소드라 에러. 수용을 하려면 public void methodA() {} 추가
		// 생성자 안에서는 static이 없어서 인스턴스 변수 없이도 사용 가능함
	} 
	public void initDisplay() { 
		System.out.println("initDisplay 호출"); 
		this.setSize(500,400);
		this.setVisible(true); 
	}
	public void methodA() {
		System.out.println("methodA()출력 호출");
	}
	public void methodA(JFrameTest1 jft) {
		System.out.println("methodA(JFrameTest1) 호출");
		System.out.println(jft); // 지변이지만 메소드 호출시 파라미터를 통해서 원본을 넘길 수 있다
	}
	public static void main(String[] args) { 
		// main 내부에서 인스턴스화를 하면 지변의 성격을 갖는다
		JFrameTest1 jft = new JFrameTest1(); 
		System.out.println(jft);
		// 메소드 파라미터 자리가 원시형 타입인 경우 + 개수 판단하고 결정 처리
		// 메소드 파라미터 자리가 참조형 타입인 경우 + 동일
		jft.methodA(jft);
	}
}
<예제7-인스턴스화 문제>
*인스턴스 방법 다양하게 연습하기
package com.week2;

public class AddressBook {
	AddressBook abook = null;
	// 제목: 메소드를 활용해서 나는 인스턴스화를 할 수 있다 - 
	// 다양한 방법으로 다른 사람이 구현한 클래스를 주입하는 방법에 대해서 학습하기
	// 다양한 인스턴스화에 대한 관찰 및 활용 등은 spring과 같은 프레임워크에서 '의존성 주입, 제어역행' 키워드에 대해 사전 준비를 할 수 있는 첫단추가 될 수 있다.
	// 1) 메소드 안에서 조건에 따라 인스턴스화를 다르게 가져갈 수도 있다 - 다른 선택지가 생기는 순간
	public AddressBook getObject() {
		// 이와 같이 null 유무를 체크해서 생성하는 건 하나만 관리하겠다라는 걸 의미한다 - '싱글톤 찾아봐'라는 것과 같음(어느 오브젝트 하나 가지고 공유하며 서비스) / 싱글톤패턴 - 싱글톤 패턴이 어디서 나오냐? 웹개발
		if(abook == null) { // 객체를 생성하기 전에 null 체크를 먼저 해서(선처리)
			abook = new AddressBook();
		}
		return abook;
	}
	public static void main(String[] args) {
		// 인스턴스화 방법에는 여러가지가 있다.
		AddressBook abook = new AddressBook(); // 기본
	}
}
<예제8-1 주소록 만들기>
package com.week2;

import javax.swing.JDialog;

public class AddressDialog {
	// 선언부
	JDialog jdg_address = new JDialog();
	// 화면처리부
	public void initDisplay() {
		jdg_address.setTitle("조회|입력|수정"); // 메소드 설계, 파라미터 결정함
		jdg_address.setSize(400,500);
		jdg_address.setVisible(true);
	}
	// 메인메소드
	public static void main(String[] args) {
		AddressDialog ad = new AddressDialog();
		ad.initDisplay();
	}
}

🙋 현재 코드에서 actionPerformed 메소드를 호출하는 코드는 어디에도 없다. 그런데 System.out.println(command);는 어떻게 실행되는 걸까요?

actionPerformed 메소드는 마치 main메소드처럼 버튼이 눌려졌다는 사실을 JVM이 감지하면 그때 자동으로 호출되는 메소드입니다.
→ 콜백(callback) 메소드

<예제8-2>
package com.week2;

import javax.swing.JDialog;

public class AddressDialog {
	// 선언부
	JDialog jdg_address = new JDialog();
	// 화면처리부
	public void initDisplay() {
		jdg_address.setTitle("조회|입력|수정"); // 메소드 설계, 파라미터 결정함
		jdg_address.setSize(400,500);
		jdg_address.setVisible(true);
		
	}
	// 메인메소드
	public static void main(String[] args) {
		AddressDialog ad = new AddressDialog();
		ad.initDisplay();
	}

}
<예제9-equals>
package com.week2;

public class String1 {

	public static void main(String[] args) {
		// String 클래스는 일반과 다르게 같은 객체를 가리키는.
		// s1, s2는 새로운 주소번지 할당이 아니라 같은 주소번지 참조
		// equals는 주소번지가 아닌 값을 비교하는 것.
		String s1 = "안녕";
		String s2 = "안녕";
		
		String s3 = new String("안녕"); // 새로운 객체 생성
		String s4 = new String("안녕");
		System.out.println(s1==s2); // true // 주소번지 비교
		System.out.println(s1==s3); // false
		System.out.println(s1.equals(s3)); // true // 값을 비교
		System.out.println(s1==s4); // false
		System.out.println(s1.equals(s4)); // true
	}

}

<7교시 수업>

🤦‍문제1. AddressBook 화면이 열릴 때 동시에 AddressDialog 화면도 보여지도록 하려면 어디를 어떻게 수정해야 할까요?

  • 힌트1
    - AddressDialog 메인메소드 삭제
~~ public static void main(String[] args) {
     AddressDialog ad = new AddressDialog();
	 ad.initDisplay();
   } ~~

: AddressDialog 메인 메소드는 서브화면에 대한 테스트용이기 때문에 역할이 없어져야 합니다.

  • AddressDialog 클래스에서 누구를 불렀는지 보자 → ad.initDisplay();
    : 그럼 AddressBook 클래스에서 initDisplay를 호출하면 되는 것
* 생성자를 이용하는 방법

<답변1-AddressDialog>

package com.week2;

import javax.swing.JDialog;

public class AddressDialog {
	// 선언부
	JDialog jdg_address = new JDialog();
	public AddressDialog() {
		initDisplay();
	}
	// 화면처리부
	public void initDisplay() {
		jdg_address.setTitle("조회|입력|수정"); 
        // 메소드 설계, 파라미터 결정함
		jdg_address.setSize(400,500);
		jdg_address.setVisible(true);
	}
 }
  1. 메인 메소드 없앤 다음 인스턴스화를 한다
  2. 인스턴스화 위치를 선택한다 - 전역으로 할까, 지역으로 할까?
<답변1-AddressBook>

package com.week2;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class AddressBook implements ActionListener {
	// 선언부
	JFrame jf = new JFrame();
	AddressDialog aDialog = new AddressDialog(); 
    // 생성부가 생성자를 호출한다
	JPanel jp_north = new JPanel(); 
	JButton btnSelect = new JButton("조회");
	JButton btnInsert = new JButton("입력");
	JButton btnUpdate = new JButton("수정");
	JButton btnDelete = new JButton("삭제");
	// 생성자
	public AddressBook() { 
	}
	// 화면처리 구현
	public void initDisplay() {
		btnSelect.addActionListener(this); 
        // this는 addActionListener 구현하고 있는 구현체 클래스 가리킨다 -> AddressBook
		btnInsert.addActionListener(this);
		btnUpdate.addActionListener(this);
		btnDelete.addActionListener(this);
		jp_north.add(btnSelect);
		jp_north.add(btnInsert);
		jp_north.add(btnUpdate);
		jp_north.add(btnDelete);
		jf.add("North", jp_north);
		jf.setTitle("주소록 Ver1.0");
		jf.setSize(800, 500);
		jf.setVisible(true);
        ~~aDialog.initDisplay();~~ 
        // 이 코드 추가하는 것이 두 번째 방법(위치: 부모가 열린 후)
	}
	// 메인메소드
	public static void main(String[] args) {
		AddressBook abook = new AddressBook(); 
		abook.initDisplay();
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();
		System.out.println(command);
		if("조회".equals(command)) {
			System.out.println("조회버튼을 클릭하였습니다");
		}
	}
}

🤦‍문제2. 지금 이 상태에서 부모가 열렸을 때, 서브창이 열리지 않으려면 어떻게 해야 할까?

  • 생각해보자
    - jf.setVisible(true); : 메모리에 올라왔지만 보이지 않는 것
    - 메모리에 아예 올라오지 않은 두 가지가 있을 것
  • 생각해보자
    - AddressDialog 클래스 - jdg_address.setVisible(true);를
    false로 바꾸는 건 어떨까? -> 이거 왜 안 되는지 정확히 모르겠음
    (선언부: 전역변수 자리임. 주소번지를 알면 접근할 수 있다. 주소 번지를 2번 접근해야 함

정답: AddressBook 클래스 - aDialog.jdg_address.setVisible(false); 추가

<답변2-AddressBook>
package com.week2;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class AddressBook implements ActionListener {
	// 선언부
	JFrame jf = new JFrame();
	AddressDialog aDialog = new AddressDialog(); 
	JPanel jp_north = new JPanel(); 
	JButton btnSelect = new JButton("조회");
	JButton btnInsert = new JButton("입력");
	JButton btnUpdate = new JButton("수정");
	JButton btnDelete = new JButton("삭제");
	// 생성자
	public AddressBook() { 
	}
	// 화면처리 구현
	public void initDisplay() {
		btnSelect.addActionListener(this); 
		btnInsert.addActionListener(this);
		btnUpdate.addActionListener(this);
		btnDelete.addActionListener(this);
		jp_north.add(btnSelect);
		jp_north.add(btnInsert);
		jp_north.add(btnUpdate);
		jp_north.add(btnDelete);
		jf.add("North", jp_north);
		jf.setTitle("주소록 Ver1.0");
		jf.setSize(800, 500);
		jf.setVisible(true);
		aDialog.initDisplay(); // 부모가 열린 후
		aDialog.jdg_address.setVisible(false); 
        // 원시형타입은 어떻게 된다고? 오버라이드
	}
	// 메인메소드
	public static void main(String[] args) {
		AddressBook abook = new AddressBook(); 
		abook.initDisplay();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();
		System.out.println(command);
		if("조회".equals(command)) {
			System.out.println("조회버튼을 클릭하였습니다");
			aDialog.jdg_address.setTitle("조회");
			aDialog.jdg_address.setVisible(true); 
            // 조회버튼이 눌렸을 때 서브화면 나옴
		}
	}
}

🤦‍문제3. 그럼 이제 버튼을 눌렀을 때 해당 창이 나오게 하자

<답변3>
package com.week2;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class AddressBook implements ActionListener {
	// 선언부
	JFrame jf = new JFrame();
	AddressDialog aDialog = new AddressDialog(); 
	JPanel jp_north = new JPanel(); 
	JButton btnSelect = new JButton("조회");
	JButton btnInsert = new JButton("입력");
	JButton btnUpdate = new JButton("수정");
	JButton btnDelete = new JButton("삭제");
	// 생성자
	public AddressBook() { 
	}
	// 화면처리 구현
	public void initDisplay() {
		btnSelect.addActionListener(this); 
		btnInsert.addActionListener(this);
		btnUpdate.addActionListener(this);
		btnDelete.addActionListener(this);
		jp_north.add(btnSelect);
		jp_north.add(btnInsert);
		jp_north.add(btnUpdate);
		jp_north.add(btnDelete);
		jf.add("North", jp_north);
		jf.setTitle("주소록 Ver1.0");
		jf.setSize(800, 500);
		jf.setVisible(true);
		aDialog.initDisplay(); 
		aDialog.jdg_address.setVisible(false); 
	}
	// 메인메소드
	public static void main(String[] args) {
		AddressBook abook = new AddressBook(); 
		abook.initDisplay();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();
		System.out.println(command);
        // 조회할 때
		if("조회".equals(command)) {
			System.out.println("조회버튼을 클릭하였습니다");
			aDialog.jdg_address.setTitle("조회");
			aDialog.jdg_address.setVisible(true); 
		}
		// 입력할 때
		else if("입력".equals(command)) {
			aDialog.jdg_address.setTitle("입력");
			aDialog.jdg_address.setVisible(true);			
		}
		// 수정할 때
		else if("수정".equals(command)) {
			aDialog.jdg_address.setTitle("수정");
			aDialog.jdg_address.setVisible(true);			
		}
		// 삭제할 때
	}
}
  • if나 else if 다음에 else if(command.equals()) 이렇게 쓰면 안 되는지?
package com.week2;

public class String2 {

	public static void main(String[] args) {
		String s1 = " ";
		String s2 = null;
		System.out.println(s1);
		System.out.println(s2);
		System.out.println(s1.equals(s2));
		~~System.out.println(null.toString());~~
        // 이건 안됨
		System.out.println("".toString()); 
        // 이건 됨. null이 아니니까
		System.out.println(s2.equals(s1));
	}
}

🤦‍문제4. 같은 코드가 반복되네. 어떻게 바꾸지? (힌트: 메소드로 처리하자)

<답변4-AddressBook>
package com.week2;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
// 클래스 선언하기
// ActionListener는 인터페이스 이라서 추상메소드를 가지고 있다
// 추상메소드란 선언만 되어있고 좌중괄호와 우중괄호가 없는 메소드 말함
public class AddressBook implements ActionListener{
	//선언부
	JFrame jf = new JFrame();
	AddressDialog aDialog = new AddressDialog();
	JPanel jp_north = new JPanel();
    // 버튼 4개 배치하는데 사용함-단독으로 모양이 없다
	JButton btnSelect = new JButton("조회");
	JButton btnInsert = new JButton("입력");
	JButton btnUpdate = new JButton("수정");
	JButton btnDelete = new JButton("삭제");
	//생성자
	public AddressBook() {}
	//화면처리 구현
	public void initDisplay() {
		// 이벤트 처리 3단계 -  버튼의 이벤트를 지원하는 인터페이스를 implements한다. - ActionListener
		// 해당 인터페이스가 선언하고 있는 메소드를 오버라이딩 해야한다. - actionPerformed(ActionEvent e)
		// 이벤트소스와 이벤트 처리를 담당하는 클래스를 매칭해줌
		btnSelect.addActionListener(this);
		btnInsert.addActionListener(this);
		btnUpdate.addActionListener(this);
		btnDelete.addActionListener(this);
		jp_north.add(btnSelect);
		jp_north.add(btnInsert);
		jp_north.add(btnUpdate);
		jp_north.add(btnDelete);
		jf.add("North", jp_north);
		jf.setTitle("주소록 Ver1.0");
		jf.setSize(800,500);
		jf.setVisible(true);
		aDialog.initDisplay();
		aDialog.jdg_address.setVisible(false);
	}
	// 메인메소드
	public static void main(String[] args) {
		AddressBook abook = new AddressBook();
		abook.initDisplay();
	}
	//아래 메소드는 ActionListener인터페이스에 이름이 정해져 있다.
	//구현체 클래스인 너가 재정의하여 구현해라
	//현재 코드에서 actionPerformed메소드를 호출하는 코드는 어디에도 없다.
	//그런데 54번 라인은 어떻게 실행되는 걸까요?
	//actionPerformed메소드는 마치 main메소드 처럼 버튼이 눌려지고 눌려졌다는 사실을 JVM이 감지하면
	//그때 자동으로 호출되는 메소드 입니다. - 콜백메소드(callback)
	@Override
	public void actionPerformed(ActionEvent e) {
		//눌려진 버튼의 문자열을 읽어온다. - 언제 버튼이 눌렸을 때 - 버튼을 누르는건 사용자 이지만 
		//눌렸다는 느끼는건 JVM만이 알수 있다.- 파라미터 자리에 e가지고 getActionCommand()호출하면 String타입의 라벨 출력함
		String command = e.getActionCommand();
		System.out.println(command);
		// 조회할 때
		if("조회".equals(command)) {
			System.out.println("조회버튼을 클릭하였습니다.");
			aDialog.set(command, true);
		}
		// 입력할 때
		else if("입력".equals(command)) {
			aDialog.set(command, true);
		}
		// 수정할 때
		else if("수정".equals(command)) {
			aDialog.set(command, true);
		}
		// 삭제할 때
	}
}
<답변4-AddressDialog>

package com.week2;

import javax.swing.JDialog;

public class AddressDialog {
	//선언부 - 전역변수 자리임
	JDialog jdg_address = new JDialog();
	public AddressDialog() {
		//initDisplay();
	}
	//메소드 설계를 통해서 반복되는 코드와 제어권은 AddressBook에 가지면서도
	//그 변화된 부분은 AddressDialog에서 처리하는 방법을 알아보자.
	//버튼이 눌리는 건 AddressBook 클래스에서 알고 있다. - actionPerformed가 있음
	//그런데 그 버튼이 눌렸을 AddressDialog클래스의 title값을 변경해야 한다.
	//AddressBook에서 눌린 버튼의 라벨값을 set메소드의 파라미터를 통해서 
	//받아오고 setTitle메소드를 호출하여 이 문제를 해결할  수 있다.
	//조회버튼을 감지하는 if문 안에서 set메소드를 호출하시오.
	public void set(String title, boolean isView) {
		jdg_address.setTitle(title);
		jdg_address.setVisible(isView);
	}
	//화면처리부
	public void initDisplay() {
		jdg_address.setSize(400, 500);
		// jdg_address.setVisible(true);
	}
}

⚾야구게임 화면

0개의 댓글