(13)-23.10.11[JAVA]

DANA·2023년 10월 11일

KDT-구디아카데미

목록 보기
13/56
<예제1>
package com.step5;
class A1{
	public A1(AMain aMain) {
		System.out.println("A1에서 출력한 AMain 원본: "+aMain);
	}
	// 경유한다 - 실행문(초기화, 재정의, if문 - 흐름이 바뀐다 - boolean - 결과가 달라진다)
	public A1() {
		// TODO Auto-generated constructor stub
	}
	int i;
}
class A2{
	public A2(AMain aMain) {
		
		System.out.println("A2에서 출력한 AMain 원본: "+aMain);
	}
	
	public A2() {
		// TODO Auto-generated constructor stub
	}

	void methodA() {
		System.out.println("methodA 호출 성공");
	}
}
public class AMain {
	A1 a1 = new A1(this); // 인스턴스화는 이미 생성자를 포함하고 있다
	A2 a2 = new A2(this);
	public static void main(String[] args) {
		// static 내부에서는 this나 super 예약어는 불가함
		AMain am = new AMain(); // 생성자 호출 -> 전변의 초기화 -> 생성자 경유
		// 파라미터를 갖는 생성자가 하나라도 존재하면 디폴트 생성자 마저도 제공 안 됨
		A1 a1 = new A1();
		System.out.println(a1.i); // 0
		A2 a2 = new A2();
		a2.methodA();
	}
}
<예제2>
package com.step5;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

// 자바를 자바답게 코딩하기 - 재사용성과 이식성
// 효과적으로 코딩을 전개하기 - 추상클래스와 인터페이스 설계하고 구현해 나가기
// 클래스 사이의 결합도를 낮춰서 단위테스트 가능하게 하고 통합테스트 가능하고
// 그러고나서 납품하기(배포하기)
// 코드의 양은 늘어나더라도 코드의 복잡도는 늘어나지 않도록 코딩을 했나? 고민 - 코드리뷰
import javax.swing.JButton;
import javax.swing.JFrame;

class B1{
	JButton jbtnSelect = new JButton("조회");

}
class B2{
	JButton jbtnInsert = new JButton("입력");
	
}
public class BMain implements ActionListener {
	JFrame jf = new javax.swing.JFrame(); // 자바 최초 MVC 패턴 API 적용한 사례
	B1 b1 = new B1(); // 위치, 유지(쿠키, 세션/ 서버: 캐쉬메모리 -시간지배함), 가치, 활용범위 - 사이드프로젝트 - 꾸준히 관찰하기
	B2 b2 = null; // 선언만 - 생성자 호출은 없다
	BMain(){
		b2 = new B2(); // 생성하기 - 생성자 경유한다
		/*
		for(double d=0.0;d<9999999.0;d++) {
			System.out.println("지연");
		}
		*/
		initDisplay();
		// b2 = new B2();
	}
	public void initDisplay() {
		// 인스턴스화, 전역변수 호출
		// B1 b1 = new B1();
		// 이벤트 소스와 이벤트 처리를 담당하는 클래스 연결하기 - 콜백메소드(시스템이 자동으로 호출한다-시점에 대한 결정권이 개발자에게 없다) 호출
		// 주소번지를 두 번 접근해야 처리가 가능한 경우 -> 대표적인 예가 이차배열, 객체배열, List의 Dept
		b1.jbtnSelect.addActionListener(this);
		jf.add("North", b1.jbtnSelect); // 호출이면 재사용성
		jf.add("South", b2.jbtnInsert); // 호출이면 재사용성
		jf.setSize(500,400);
		jf.setVisible(true);
	}
	public static void main(String[] args) {
		BMain bm = new BMain();
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		// 사용자가 누른 버튼에 대한 주소번지 얻어내기
		Object obj = e.getSource();
		if(obj==b1.jbtnSelect) { // 조회버튼을 누른거야?
			System.out.println(b1.jbtnSelect.getText());
		}
	}

}
<예제3>
// 주소번지 2번 접근하기
package com.step5;
class C {
	int i;
	C getInstance() { // Calendar cal = Calaendar.getInstance(); // 싱글톤패턴
		return new C();
	}
}
public class CMain {

	public static void main(String[] args) {
		C c = new C();
		System.out.println(c.i); // 0
		c.i = 10; // 재정의
		// System.out.println(c.i); 여기서 c와
		// getInstance()리턴 타입으로 받는 c는 서로 다른 걸 가리킨다
		System.out.println(c.getInstance().i); // 0
	}
}
<예제4>
package com.step5;

public class GMain {

	public static void main(String[] args) {
		String s = "hello";
		System.out.println(s.length()); // 5
		System.out.println(new int[3].length); // 3
	}

}

야구게임 - 클래스 나누기

1.이건 어디 클래스로 가야할까?
ranCom():void
이것도 로직인 줄

  1. 전역변수 위치도 정해보자
    int com[] = new int[3]; // 정답
    int my[] = new int[3]; // 사용자가 입력한 숫자 - > account(String user)
    my[0] = temp/100
    난 UI
  1. 힌트문 - 처리(판별식:판정) 어디로 보낼지?
    account(String): String
  • 여기가 로직이라고 함 / BaseBallGameLogic
    for(){
    for(){
    if(com[i]==my[j]) // 참-어느 위치이던 그 숫자가 들어있다 ball++
    if(i==j) // 백의 자리와 백의 자리가 같은지 따진다. strike++
    }
    }
  1. exit():void - 나가기 버튼, 종료 -> 버튼을 눌렀을 때.
    버튼을 눌렀을 때 감지하는 건 이벤트. 이벤트 처리 클래스
    감지한 후에는 후처리하기 필요 -> actionperformed

initDisplay(): void - 화면을 담당한다 - BaseBallGameUI
: 데려가야할 전변이 있나요? - 크기를 결정, 비활성화 할 것인가 아님 활성화 할 것인가(setVisible),

<BaseBallGameLogic>
package com.step5;

import java.util.Random;
//게임에 관련된 규칙이나 약속들 - 로직클래스 배치하자
public class BaseBallGameLogic {
	//현재는 null이므로 NullPointerException발동하겠지만 
	//이문제를 생성자를 통해 해결함
	BaseBallGameUI baseBallGameUI = null;
	int my[]  = new int[3];
	int com[] = new int[3];//컴터가 채번한 숫자 담기 -BaseBallGameUI or BaseBallGameLogic or BaseBallGameEvent	
	//단 이와같은 방법을 사용할 때 순환구조에 빠지지 않도록 주의할것.- 제어역행
	public BaseBallGameLogic(BaseBallGameUI baseBallGameUI) {
		this.baseBallGameUI = baseBallGameUI;
	}
	//세자리 임의의 숫자를 채번하는 메소드 구현하기
	public void ranCom() {
		Random r = new Random();
		//첫번째 자리는 중복검사가 필요없다
		com[0] = r.nextInt(10);
		//while문과는 다르게 무조건 한번은 실행됨
		do {
			com[1] = r.nextInt(10);			
		}while(com[0]==com[1]);//중복된 숫자이면 계속 돌아라
		do {
			com[2] = r.nextInt(10);			
		}while((com[0]==com[2]) || (com[2]==com[1]));//중복된 숫자이면 계속 돌아라
	}
	//사용자가 입력한 값을 판정하는 메소드를 구현해 봅시다.
	public String account(String user) {
		if(user.length()!=3) {//length명사형은 배열의 원소의 수반환. length()동사형은 문자열의 길이를 반환함
			return "세자리 숫자를 입력하세요.";
		}
		//사용자가 jtf_user에 입력한 숫자는 보기에는 숫자 처럼 보여도 알맹이는 문자열로 
		//인식을 합니다. 그래서 형전환을 한 후 my[]배열에 담아야 함니다.
		//문자열 "256"을 숫자로 담을 변수 선언
		int temp 	= 0;
		int strike 	= 0;//힌트로 사용될 스트라이크를 담을 변수 선언
		int ball 	= 0;//볼을 담을 변수 선언
		//strike와ball을 지역변수로 해야 하는건 매 회차 마다 값이 변해야 하기 때문이다.
		try {
			temp = Integer.parseInt(user);//안녕 - NumberFormatException발생
		} catch (NumberFormatException e) {
			return "숫자만 입력하세요.";
		}
		my[0] = temp/100;//256/100=> 2.56 -> 2만 담김
		my[1] = (temp%100)/10;//십의자리 - 몫 2 나머지 56-> 5.6 -> 5만 담김
		my[2] = temp%10;//몫: 25 - 6만담김
		//이 중 for 문 사용해서 자리는 다르더라도 그 숫자가 존재하니? 네-> ball확보됨
		//네 일때 다시 한번 i ==j가 같은지  비교해서 index값 마저도 동일하면 자리까지도 일치함 - strike++
		for(int i=0;i<3;i++) {//9가지 경우의 수가 발생
			for(int j=0;j<3;j++) {
				if(com[i] == my[j]) {//그 숫자가 존재하니? 네 -ball확보
					if(i==j) {//자리값도 일치하는 거야? 네 -strike결정됨
						strike++;
					}else {//숫자는 있지만 자리는 달라요
						ball++;
					}
				}//end of if
			}/// end of inner for
		}//////end of outter for
		if(strike == 3) {
			return "정답입니다. 축하합니다.";
		}
		return strike+"스  "+ball+"볼";
	}
}
<BaseBallGameEvent>
package com.step5;

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

public class BaseBallGameEvent implements ActionListener {
	int cnt = 0;
	BaseBallGameUI bbgUI = null;
	//아래 생성자 호출은 BaseBallGameEvent에서 일어나는게 아니고
	//BaseBallGameUI에서 생성자 호출이 일어난다.
	//그때 파라미터 자리에 this를 넣었다.- 그(BaseBallGameUI의 main메소드에서
	//인스턴스화를 통해 메모리에 로딩된 바로 그 원본이다)
	public BaseBallGameEvent(BaseBallGameUI baseBallGameUI) {
		this.bbgUI = baseBallGameUI;
	}
	//나가기 버튼이나 나가기 메뉴 아이템을 선택(클릭)했을때 호출되는 메소드 구현
	public void exit() {
		System.exit(0);
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed 호출 성공");
		String label = e.getActionCommand();//감지된 클래스의 라벨담기
		System.out.println("너가 누른 버튼의 문자열은 "+label+ " 입니다.");
		Object obj = e.getSource();//이벤트소스의 주소번지를담아줌.
		System.out.println(obj);
		if("지우기".equals(label)) {
			bbgUI.jta_display.setText("");//화면측 - BaseBallGameUI
		}
		//너 나가기 버튼이니?
		//|만 있을 땐 앞에 조건이 true이면 실행문이 결정되었지만 뒤에 조건을 따짐
		//||가 있을 땐 앞에 조건이 true이면 뒤에 조건이 false이어도 어차피 실행됨 - 뒤에 조건을 안따짐- 일량이 줄어듦
		else if("나가기".equals(label) || obj == bbgUI.jmi_exit) {//or이니까 둘중 하나만 true이어도 호출된다.
			exit();//사용자 정의 메소드 호출이다.
		}
		//새게임을 누른거야?
		else if(obj == bbgUI.jbtn_new || obj == bbgUI.jmi_new) {
			cnt = 0;
			//순환구조에 빠지지 않도록 하기 위해서 Logic클래스와 Event클래스는 직접 연결하지 않음
			bbgUI.bbgLogic.ranCom();
			bbgUI.jta_display.setText("");
			bbgUI.jta_display.append("정답은 "+bbgUI.bbgLogic.com[0]+bbgUI.bbgLogic.com[1]+bbgUI.bbgLogic.com[2]+" 입니다.\n");
		}
		//이벤트가 발생한 이벤트 소스의 문자열을 비교하기
		else if(e.getSource()==bbgUI.jtf_user) {
			bbgUI.jta_display.append(++cnt+"회 : "+bbgUI.jtf_user.getText()+" : "+bbgUI.bbgLogic.account(bbgUI.jtf_user.getText())+"\n");
			bbgUI.jtf_user.setText("");
		}///////////입력하고 엔터 쳤을 때
		else if(obj==bbgUI.jmi_dap || "정답".equals(label)) {
			//1-먼저 채번(동사-기능-메소드 호출)하고 그 다음에 com배열에 있는 값을 출력해 준다.
			//ranCom();
			bbgUI.jta_display.append("정답은 "+bbgUI.bbgLogic.com[0]+bbgUI.bbgLogic.com[1]+bbgUI.bbgLogic.com[2]+" 입니다.\n");
			//jta_display.append(com[0]+com[1]+com[2]);//0
		}
	}

}
<BaseBallGameUI>
package com.step5;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class BaseBallGameUI {
	//선언부
	JFrame jf = new JFrame();
	//이미지를 담은 물리적인 위치 선언하기.
	String 		imgPath = "D:\\workspace_java\\dev_java\\src\\com\\week2\\";
//	ImageIcon 	titleIcon = new ImageIcon(imgPath+"yagu.png");
	//ImageIcon 	bg = new ImageIcon(imgPath+"dreamballpark.jpg");
	Image img = null;
	JMenuBar 	jmb 		= new JMenuBar();
	JMenu	 	jm_game 	= new JMenu("게임");
	JMenuItem   jmi_new 	= new JMenuItem("새게임");
	JMenuItem   jmi_dap 	= new JMenuItem("정답");
	JMenuItem   jmi_clear 	= new JMenuItem("지우기");
	JMenuItem   jmi_exit 	= new JMenuItem("나가기");
	JMenu	 	jm_info 	= new JMenu("도움말");
	JMenuItem   jmi_detail 	= new JMenuItem("야구숫자게임이란?");
	JMenuItem   jmi_create 	= new JMenuItem("만든사람들");
	//중앙에 들어갈 속지 선언
	JPanel jp_center = new JPanel();
	//세자리 숫자를 입력 후 엔터를 쳤을때 사용자가 입력한 숫자와 숫자를 맞추기 위한 힌트문
	//을 출력해줄 화면.
	JTextArea jta_display = null;
	JScrollPane jsp_display = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
	JTextField jtf_user   = new JTextField();
	//글꼴과 글꼴에 대한 스타일과 글자 크기를 정해줌.-인스턴스화를 통해서, 그 값들은 생성자의 파라미터로 결정됨
	Font f = new Font("Thoma",Font.BOLD,14);
	//동쪽에 들어갈 속지 생성하기
	JPanel jp_east   = new JPanel();
	//새게임, 정답, 지우기, 나가기 버튼 추가하기
	JButton jbtn_new 	= new JButton("새게임");
	JButton jbtn_dap 	= new JButton("정답");
	JButton jbtn_clear 	= new JButton("지우기");
	JButton jbtn_exit 	= new JButton("나가기");	
	//파라미터로 넘어가는 주소번지는 BaseBallGameUI타입이다.
	BaseBallGameEvent bbgEvent = new BaseBallGameEvent(this);
	BaseBallGameLogic bbgLogic = new BaseBallGameLogic(this);
	//생성자
	BaseBallGameUI(){
		bbgLogic.ranCom();
	}
	//화면을 그려주는 메소드 선언
	public void initDisplay() {
		jta_display = new JTextArea();
		jsp_display = new JScrollPane(jta_display);
		jta_display.setOpaque(false);
		jf.setResizable(false);
		//jf.setContentPane(new BgPanel());
		//////////////// 툴바에 들어갈 이미지 버튼 추가하기 ///////////////
		//////////////// 메뉴 바 추가 시작 /////////////////
		jm_game.add(jmi_new);
		jm_game.add(jmi_dap);
		jm_game.add(jmi_clear);
		jm_game.add(jmi_exit);
		jm_info.add(jmi_detail);
		jm_info.add(jmi_create);
		jmb.add(jm_game);
		jmb.add(jm_info);
		//////////////// 메뉴 바 추가  끝   /////////////////
		System.out.println("initDisplay 호출 성공");
		//이벤트 소스와 이벤트 처리 클래스를 매핑하는 코드 추가
		//EventHandler ehandler = new EventHandler();
		//jtf_user.addActionListener(ehandler);//여기서 this는 자기자신 클래스를 가리킴.-BaseBallGame:내안에 actionPerformed
		jtf_user.addActionListener(bbgEvent);//여기서 this는 자기자신 클래스를 가리킴.-BaseBallGame:내안에 actionPerformed
		jbtn_new.addActionListener(bbgEvent);
		jbtn_dap.addActionListener(bbgEvent);
		jbtn_clear.addActionListener(bbgEvent);
		jbtn_exit.addActionListener(bbgEvent);
		jmi_exit.addActionListener(bbgEvent);
		jbtn_new.setBackground(new Color(158,9,9));
		jbtn_new.setForeground(new Color(212,212,212));
		jbtn_dap.setBackground(new Color(7,84,170));
		jbtn_dap.setForeground(new Color(212,212,212));
		jbtn_clear.setBackground(new Color(19,99,57));
		jbtn_clear.setForeground(new Color(212,212,212));
		jbtn_exit.setBackground(new Color(54,54,54));
		jbtn_exit.setForeground(new Color(212,212,212));
		jp_east.setLayout(new GridLayout(4,1));
		jp_east.add(jbtn_new);
		jp_east.add(jbtn_dap);
		jp_east.add(jbtn_clear);
		jp_east.add(jbtn_exit);
		jta_display.setFont(f);
		jta_display.setBackground(new Color(255,255,200));
		jta_display.setForeground(new Color(57,109,165));

		jf.setJMenuBar(jmb);
		jtf_user.setBackground(new Color(255,255,200));
		jp_center.setBackground(Color.green);
		jp_east.setBackground(Color.black);
		jp_center.setLayout(new BorderLayout(0,10));
		jp_center.add("Center",jsp_display);
		jp_center.add("South",jtf_user);
		jta_display.setLineWrap(true);
		jf.setLayout(new BorderLayout(10,20));
		jf.add("Center",jp_center);
		jf.add("East",jp_east);
		jf.setTitle("야구 숫자 게임 Ver1.0");
		jf.setSize(400, 300);
		jf.setVisible(true);
	}////////////////end of initDisplay ///////////////
	
	
	public static void main(String[] args) {
		 BaseBallGameUI bbgUI = new BaseBallGameUI();
		 bbgUI.initDisplay();
	}

}

객체배열

<예제1>
package com.step5;
// 데이터를 처리하기 위한 클래스 설계(VO-value object패턴, DTO-data transfer object패턴)
// 변수 선언의 목적: 어떤 정보를 기억하기 위한 것 - 하나만 아니고 여러 개를 한 번에 기억하는 것이 가능함(그 여러 개가 관계를 갖고 있다)
// 여러 개의 변수를 선언하고 있는 DeptVO 설계하였다. 한 번에 한 개 로우만 담을 수 있다(여러 개의 로우는 못 담는다-객체배열이면 가능)
// DeptVO dVO = new DeptVO();
class DeptVO{
	private int deptno; // 0
	private String dname; // null
	private String loc; // null
	
	public int getDeptno() {
		return deptno; // 캡슐화로 인해서 직접 접근 불가능하니까 getter/setter
	}
	public void setDeptno(int deptno) {
		this.deptno = deptno;
	}
	public String getDname() {
		return dname;
	}
	public void setDname(String dname) {
		this.dname = dname;
	}
	public String getLoc() {
		return loc;
	}
	public void setLoc(String loc) {
		this.loc = loc;
	}
}
public class DeptTest {

	public static void main(String[] args) {
		DeptVO dVOs[]=new DeptVO[3];
		for(DeptVO dVO:dVOs) {
			dVO = new DeptVO();
			System.out.println(dVO);
		}
		System.out.println(dVOs[0]);
		System.out.println(dVOs[1]);
		System.out.println(dVOs[2]);
	}

}
<예제2>
package com.step5;
// 데이터를 처리하기 위한 클래스 설계(VO-value object패턴, DTO-data transfer object패턴)
// 변수 선언의 목적: 어떤 정보를 기억하기 위한 것 - 하나만 아니고 여러 개를 한 번에 기억하는 것이 가능함(그 여러 개가 관계를 갖고 있다)
// 여러 개의 변수를 선언하고 있는 DeptVO 설계하였다. 한 번에 한 개 로우만 담을 수 있다(여러 개의 로우는 못 담는다-객체배열이면 가능)
// DeptVO dVO = new DeptVO();
class DeptVO{
	private int deptno; // 0
	private String dname; // null
	private String loc; // null
	
	public DeptVO() {}
	public DeptVO(int deptno, String dname, String loc) {
		this.deptno = deptno;
		this.dname = dname;
		this.loc = loc;
	}
		

	public int getDeptno() {
		return deptno; // 캡슐화로 인해서 직접 접근 불가능하니까 getter/setter
	}
	public void setDeptno(int deptno) {
		this.deptno = deptno;
	}
	public String getDname() {
		return dname;
	}
	public void setDname(String dname) {
		this.dname = dname;
	}
	public String getLoc() {
		return loc;
	}
	public void setLoc(String loc) {
		this.loc = loc;
	}
}
public class DeptTest {

	public static void main(String[] args) {
		DeptVO dVOs[]=new DeptVO[3];
		System.out.println(dVOs[0]+","+dVOs[1]+","+dVOs[2]);
		DeptVO dVO1 = new DeptVO(10,"영업부","대전");
		System.out.println(dVO1);
		dVOs[0]=dVO1;
		System.out.println(dVOs[0]);
		DeptVO dVO2 = new DeptVO(20,"개발부","부산");
		dVOs[1]=dVO2;
		System.out.println(dVOs[1]);
		DeptVO dVO3 = new DeptVO(30,"운영부","대구");
		dVOs[2]=dVO3;
		System.out.println(dVOs[2]);
		if(dVOs[2]==dVO3) System.out.println("같은 주소번지다");
		for(int i=0;i<dVOs.length;i++) {
			dVOs[i]=new DeptVO(10,"영업부","대전");
			System.out.println(dVOs[i].getDeptno()+","+dVOs[i].getDname()+dVOs[i].getLoc());
		}
	}
}
<예제-기타>
package com.step5;

import javax.swing.JButton;

public class JButtonArray2 {

	public static void main(String[] args) {
		// 초기화를 하지 않으면 주소번지를 출력하지 못하고 null만 세 번 출력한다
		JButton jbtns[]=new JButton[3]; // nullx3
		JButton jbtnSelect=new JButton("조회");
		System.out.println(jbtns[0]); // null
		jbtns[0]=jbtnSelect;
		System.out.println(jbtns[0]); // 주소번지
	}

}

계산기 클래스 쪼개기

<CalcView-원클래스>
package com.week3;

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

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

public class CalcView implements ActionListener{
	JFrame jf = new JFrame();
	JTextField jtf_display = new JTextField("0");
	JPanel jp = new JPanel();
	JButton jbtnOne = new JButton("1");
	JButton jbtnTwo = new JButton("2");
	JButton jbtnPlus = new JButton("+");
	JButton jbtnEqual = new JButton("=");
	JButton jbtnBack = new JButton("<=");
	JButton jbtnClear = new JButton("C");
	// 연산자(+) 누르기 전에 입력된 값 담기
	String v1 = "";
	// 연산자(=) 누르고 난 뒤에 입력된 값 담기
	String v2 = "";
	// 연산자 담기(+,-,*,/)
	String op = "";
	public void initDisplay() {
		jtf_display.setHorizontalAlignment(JTextField.RIGHT);
		//이벤트 처리를 담당하는 핸들러 클래스의 인스턴스변수를 준다.
		jbtnOne.addActionListener(this);
		jbtnTwo.addActionListener(this);
		jbtnPlus.addActionListener(this);
		jbtnEqual.addActionListener(this);
		jbtnBack.addActionListener(this);
		jbtnClear.addActionListener(this);
		jp.add(jbtnOne);
		jp.add(jbtnTwo);
		jp.add(jbtnPlus);
		jp.add(jbtnEqual);
		jp.add(jbtnBack);
		jp.add(jbtnClear);
		jf.add("North",jtf_display);
		jf.add("Center",jp);
		jf.setSize(400, 400);
		jf.setVisible(true);
	}
	/*****************************************************
	 * 사칙연산을 구현하기
	 * @param v1 - 연산자가 눌리기 전까지 입력된 숫자묶음
	 * @param v2 - = 눌렸을 때 그 전까지 입력된 숫자묶음
	 * @param op - +,-,*,/
	 * @return - JTextField에 계산된 결과를 출력해야 한다. String이다. jtf_display.setText("3");
	 ****************************************************/
	public String calcurate(String v1, String v2, String op) {
		double d1 = Double.parseDouble(v1);
		double d2 = Double.parseDouble(v2);
		if("+".equals(op)) {
			return String.valueOf(d1+d2);
		}
		else if("-".equals(op)) {
			return String.valueOf(d1-d2); 
		}
		else if("*".equals(op)) {
			return String.valueOf(d1*d2); 
		}
		else if("/".equals(op)) {
			return String.valueOf(d1/d2); 
		}
		else {
			return "error";
		}
	}
	public static void main(String[] args) {
		CalcView cv = new CalcView();
		cv.initDisplay();
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();
		if("1".equals(command)) {//너 숫자 1 버튼 누른거야?
			// 전처리하기 - 맨 앞에 0이 있는 경우 전처리함
			if("0".equals(jtf_display.getText())) {
				jtf_display.setText("");
			}
			jtf_display.setText(jtf_display.getText()+"1");
		}
		else if("2".equals(command)) {//너 숫자 2 버튼 누른거야?
			// 전처리하기 - 맨 앞에 0이 있는 경우 전처리함
			if("0".equals(jtf_display.getText())) {
				jtf_display.setText("");
			}
			jtf_display.setText(jtf_display.getText()+"2");			
		}
		else if("+".equals(command)) {//너 + 버튼 누른거야?
			System.out.println("더하기 버튼");
			// insert here - v1 담기
			v1 = jtf_display.getText();
			System.out.println("v1 :"+v1);
			op="+";
			jtf_display.setText("");
		}
		else if("=".equals(command)) {//너 = 버튼 누른거야?
			System.out.println("계산 결과는 얼마");			
			// insert here - v2 담기
			v2 = jtf_display.getText();
			String result = calcurate(v1,v2,op);
			jtf_display.setText(result);
		}		
		else if("<=".equals(command)) {//너 = 버튼 누른거야?
			System.out.println("한글자씩 지우기 구현");		
		}		
		else if("C".equals(command)) {//너 Clear 버튼 누른거야?
			jtf_display.setText("");
		}		
	}

}
<MyCalcView>
package com.week3;

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

public class MyCalcView {
	// 전역변수에 선언되어 있어도 해당 클래스를 인스턴스화 하지 않으면 생성자 호출이 안됨(꼭 기억하자)
	// 생성자 호출 왜 한다고? 초기화. 뭘 방어한다고? NullPointerException
	MyCalcLogic mcLogic = new MyCalcLogic(this); // 여기서 this는 MyCalcView
	MyCalcEvent mcEvent = new MyCalcEvent(this); 
	
	JFrame jf = new JFrame();
	JTextField jtf_display = new JTextField("0");
	JPanel jp = new JPanel();
	JButton jbtnOne = new JButton("1");
	JButton jbtnTwo = new JButton("2");
	JButton jbtnPlus = new JButton("+");
	JButton jbtnEqual = new JButton("=");
	JButton jbtnBack = new JButton("<=");
	JButton jbtnClear = new JButton("C");
	
	public void initDisplay() {
		jtf_display.setHorizontalAlignment(JTextField.RIGHT);
		//이벤트 처리를 담당하는 핸들러 클래스의 인스턴스변수를 준다.
		jbtnOne.addActionListener(mcEvent);
		jbtnTwo.addActionListener(mcEvent);
		jbtnPlus.addActionListener(mcEvent);
		jbtnEqual.addActionListener(mcEvent);
		jbtnBack.addActionListener(mcEvent);
		jbtnClear.addActionListener(mcEvent);
		jp.add(jbtnOne);
		jp.add(jbtnTwo);
		jp.add(jbtnPlus);
		jp.add(jbtnEqual);
		jp.add(jbtnBack);
		jp.add(jbtnClear);
		jf.add("North",jtf_display);
		jf.add("Center",jp);
		jf.setSize(400, 400);
		jf.setVisible(true);
	}
	
	public static void main(String[] args) {
		MyCalcView mcv = new MyCalcView();
		mcv.initDisplay();
	}
}
<MyCalcLogic>
package com.week3;
// 어떤 업무의 프로세스를 담당하는 클래스는 상속이나 인터페이스에 대한 implements를 피하는 게 맞다. 왜? 재사용성, 이식성 등
// 어떠한 추상클래스나 인터페이스도 구현하지 않는 순수하게 사용자 정의 메소드나 변수로만 구현하기
// 모델계층은 순수하게 남겨둔다 - 재사용성, 이식성, 유지보수를 위해서
public class MyCalcLogic {
	MyCalcView myCalcView = null; // 1. 이렇게만 하면 NullPointerException이 발생하니까 
	public MyCalcLogic(MyCalcView myCalcView) {
		this.myCalcView = myCalcView; // 2. 여기에 이렇게 작성
	}

	/*****************************************************
	 * 사칙연산을 구현하기
	 * @param v1 - 연산자가 눌리기 전까지 입력된 숫자묶음
	 * @param v2 - = 눌렸을 때 그 전까지 입력된 숫자묶음
	 * @param op - +,-,*,/
	 * @return - JTextField에 계산된 결과를 출력해야 한다. String이다. jtf_display.setText("3");
	 ****************************************************/
	public String calcurate(String v1, String v2, String op) {
		double d1 = Double.parseDouble(v1);
		double d2 = Double.parseDouble(v2);
		if("+".equals(op)) {
			return String.valueOf(d1+d2);
		}
		else if("-".equals(op)) {
			return String.valueOf(d1-d2);
		}
		else if("*".equals(op)) {
			return String.valueOf(d1*d2); 
		}
		else if("/".equals(op)) {
			return String.valueOf(d1/d2); 
		}
		else {
			return "error";
		}
	} // end of calcurate
}
<MyCalcEvent>
package com.week3;

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

public class MyCalcEvent implements ActionListener {
	MyCalcView myCalcView = null; // 여기서 new하면 절대 안 됨 - 복제본이 만들어지니까
		// 연산자(+) 누르기 전에 입력된 값 담기
		String v1 = ""; // calcurate에서 필요함
		// 연산자(=) 누르고 난 뒤에 입력된 값 담기
		String v2 = "";
		// 연산자 담기(+,-,*,/)
		String op = "";
	public MyCalcEvent(MyCalcView myCalcView) {
		this.myCalcView = myCalcView; // 초기화 또는 재정의
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();
		if("1".equals(command)) {//너 숫자 1 버튼 누른거야?
			// 전처리하기 - 맨 앞에 0이 있는 경우 전처리함
			if("0".equals(myCalcView.jtf_display.getText())) {
				myCalcView.jtf_display.setText("");
			}
			myCalcView.jtf_display.setText(myCalcView.jtf_display.getText()+"1");
		}
		else if("2".equals(command)) {//너 숫자 2 버튼 누른거야?
			// 전처리하기 - 맨 앞에 0이 있는 경우 전처리함
			if("0".equals(myCalcView.jtf_display.getText())) {
				myCalcView.jtf_display.setText("");
			}
			myCalcView.jtf_display.setText(myCalcView.jtf_display.getText()+"2");			
		}
		else if("+".equals(command)) {//너 + 버튼 누른거야?
			System.out.println("더하기 버튼");
			// insert here - v1 담기
			v1 = myCalcView.jtf_display.getText();
			System.out.println("v1 :"+v1);
			op="+";
			myCalcView.jtf_display.setText("");
		}
		else if("=".equals(command)) {//너 = 버튼 누른거야?
			System.out.println("계산 결과는 얼마");			
			// insert here - v2 담기
			v2 = myCalcView.jtf_display.getText();
			String result = myCalcView.mcLogic.calcurate(v1,v2,op);
			myCalcView.jtf_display.setText(result);
		}		
		else if("<=".equals(command)) {//너 = 버튼 누른거야?
			System.out.println("한글자씩 지우기 구현");		
		}		
		else if("C".equals(command)) {//너 Clear 버튼 누른거야?
			myCalcView.jtf_display.setText("");
		}		
	}

}

0개의 댓글