<예제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
이것도 로직인 줄
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("");
}
}
}