프로젝트 개발 프로그램/[JAVA] 계산기 프로그램
[JAVA] 계산기 프로그램 프로젝트_2일차(기능 구현I)
코밍이
2021. 7. 27. 00:53
2. 계산기 프로그램 기능 구현I
1) 계산기 프로그램 개발 환경
구분 | 내용 |
사용 프로그래밍 언어 | JAVA |
개발환경 | eclipse |
GUI 관련 주요 클래스 | SWING,AWT |
기능 관련 주요 인터페이스 | ActionListener |
벤치마킹 프로그램 | Windows 계산기 |
2) 개발 소스
package calculator;
// GUI 구현을 위해 사용하는 클래스들(awt, swing)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Calculator extends JFrame implements ActionListener{
JPanel p_all, p_cal, p_cont; // 객체 선언
JButton rem, ce, c, b_space, frac, squa, root, div, seven, eight, nine, mul, four, five,
six, minus, one, two, three, plus, sign, zero, point, equal;// 버튼 선언
JLabel process, result; // 레이블 선언
String num1 , num2; // 피연산자들을 저장하는 변수
String func; // 연산자 저장하는 변수
String pro; // 연산 관정을 저장하는 변수
String result_num; // 결과값을 저장하는 변수
public Calculator(String title) {
// 기본 프로그램 설정(제목, 크기, 위치)
this.setTitle(title);
this.setSize(350, 450);
this.setLocation(800, 280);
//종료(EXIT_ON_CLOSE를 사용, 없으면 작업 프로세스에 남아서 메모리만 차지함.)
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/* 1. 배치 관리자 종류
* 1) FlowLayout : 왼쪽에서 오른쪽으로 배치, 오른쪽 공간 없으면 아래로 자동 배치
* - 사용 예제 : FlowLatout(FlowLayout.LEFT, 10, 20); // 왼쪽 정렬, 좌우간격 10, 상하간격 20
* 2) BorderLayout : 상하좌우 + 중앙 5개의 영역으로 나눠 배치
* - 사용 예제 : BorderLayout(30,20); //좌우간격 30, 상하간격 20
* 3) GridLayout : 2차원 그리드로서 n x n 으로 설정, 왼->오, 위->아래 순 배치
* - 사용 예제 : GridLayout(4,3,5,50); // 4 x 3 그리드, 좌우간격 5, 상하간격 50
* 4) CardLayout : 컴포넌트를 포개어 배치
* 5) Null : 레이아웃을 쓰지 않고 각 컴포넌트마다 수동으로 위치 설정해줄 때 사용
*/
//Panel 객체 생성
p_all = new JPanel();
p_cal = new JPanel();
p_cont = new JPanel();
//폰트 생성
Font bold = new Font("맑은 고딕", Font.BOLD, 40);
Font bt_bold = new Font("맑은 고딕", Font.BOLD, 30);
//색깔 생성
Color gray = new Color(204,204,204);
Color white = new Color(255,255,255);
Color light_blue = new Color(153,153,255);
//p_all(전체적인 레이아웃) 설정
this.add(p_all);
p_all.setLayout(new FlowLayout());
//p_cal 레이아웃
p_cal.setLayout(new GridLayout(2,1));
p_cal.setPreferredSize(new Dimension(290,80)); // 레이아웃 크기 설정
process = new JLabel("",JLabel.RIGHT);
result = new JLabel("0",JLabel.RIGHT);
p_cal.add(process);
p_cal.add(result);
//p_cal 레이블 정렬
process.setAlignmentX(RIGHT_ALIGNMENT);
result.setAlignmentX(RIGHT_ALIGNMENT);
//p_cal 폰트 적용
result.setFont(bold);
//p_cal 색상 적용
process.setForeground(Color.gray);
//p_cont 레이아웃
p_cont.setLayout(new GridLayout(6,4));
p_cont.setPreferredSize(new Dimension(290,300));
//p_cont 1번줄
rem = new JButton("%");
rem.addActionListener(this); // 이벤트에 사용하기 위한 작업
p_cont.add(rem);
ce = new JButton("CE");
ce.addActionListener(this);
p_cont.add(ce);
c = new JButton("C");
c.addActionListener(this);
p_cont.add(c);
b_space = new JButton("←");
b_space.addActionListener(this);
p_cont.add(b_space);
//p_cont 2번줄
frac = new JButton("¹/x");
frac.addActionListener(this);
p_cont.add(frac);
squa = new JButton("x²");
squa.addActionListener(this);
p_cont.add(squa);
root = new JButton("²√x");
root.addActionListener(this);
p_cont.add(root);
div = new JButton("÷");
div.addActionListener(this);
p_cont.add(div);
//p_cont 3번줄
seven = new JButton("7");
seven.addActionListener(this);
p_cont.add(seven);
eight = new JButton("8");
eight.addActionListener(this);
p_cont.add(eight);
nine = new JButton("9");
nine.addActionListener(this);
p_cont.add(nine);
mul = new JButton("×");
mul.addActionListener(this);
p_cont.add(mul);
//p_cont 4번줄
four = new JButton("4");
four.addActionListener(this);
p_cont.add(four);
five = new JButton("5");
five.addActionListener(this);
p_cont.add(five);
six = new JButton("6");
six.addActionListener(this);
p_cont.add(six);
minus = new JButton("-");
minus.addActionListener(this);
p_cont.add(minus);
//p_cont 5번줄
one = new JButton("1");
one.addActionListener(this);
p_cont.add(one);
two = new JButton("2");
two.addActionListener(this);
p_cont.add(two);
three = new JButton("3");
three.addActionListener(this);
p_cont.add(three);
plus = new JButton("+");
plus.addActionListener(this);
p_cont.add(plus);
//p_cont 6번줄
sign = new JButton("+/-");
sign.addActionListener(this);
p_cont.add(sign);
zero = new JButton("0");
zero.addActionListener(this);
p_cont.add(zero);
point = new JButton(".");
point.addActionListener(this);
p_cont.add(point);
equal = new JButton("=");
equal.addActionListener(this);
p_cont.add(equal);
//p_cont 폰트 사이즈 설정
zero.setFont(bt_bold);
one.setFont(bt_bold);
two.setFont(bt_bold);
three.setFont(bt_bold);
four.setFont(bt_bold);
five.setFont(bt_bold);
six.setFont(bt_bold);
seven.setFont(bt_bold);
eight.setFont(bt_bold);
nine.setFont(bt_bold);
//p_cont 버튼 배경색 설정
rem.setBackground(gray);
ce.setBackground(gray);
c.setBackground(gray);
b_space.setBackground(gray);
frac.setBackground(gray);
squa.setBackground(gray);
root.setBackground(gray);
div.setBackground(gray);
mul.setBackground(gray);
minus.setBackground(gray);
plus.setBackground(gray);
sign.setBackground(gray);
point.setBackground(gray);
equal.setBackground(light_blue);
zero.setBackground(white);
one.setBackground(white);
two.setBackground(white);
three.setBackground(white);
four.setBackground(white);
five.setBackground(white);
six.setBackground(white);
seven.setBackground(white);
eight.setBackground(white);
nine.setBackground(white);
//전체내용
p_all.add(p_cal);
p_all.add(p_cont);
//창 보이기 설정(true : 보임 , false 안보임)
setVisible(true);
}
public static void main(String[] args) {
// Corine의 계산기 실행
new Calculator("계산기");
}
// 마우스 클릭에 의한 동작
public void actionPerformed(ActionEvent e) {
// getActionCommand()는 action 명령을 나타내는 문자열을 제공
// getSource()는 이벤트가 발생된 객체를 가져옴
// 첫번째 피연산자에 값이 있고 두번째 피연산자와 연산자를 받지 않은 경우 처리
if(num1 != null && num2 == null && func == null) {
if (e.getSource() == one) {
num1 = num1 + "1";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == two) {
num1 = num1 + "2";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == three) {
num1 = num1 + "3";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == four) {
num1 = num1 + "4";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == five) {
num1 = num1 + "5";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == six) {
num1 = num1 + "6";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == seven) {
num1 = num1 + "7";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == eight) {
num1 = num1 + "8";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == nine) {
num1 = num1 + "9";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == zero) {
num1 = num1 + "0";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if(e.getSource() == plus) {
func = "+";
pro = pro + func;
process.setText(pro);
} else if (e.getSource() == minus){
func = "-";
pro = pro + func;
process.setText(pro);
} else if (e.getSource() == mul){
func = "×";
pro = pro + func;
process.setText(pro);
} else if (e.getSource() == div){
func = "÷";
pro = pro + func;
process.setText(pro);
} else if (e.getSource() == rem){
func = "%";
pro = pro + func;
process.setText(pro);
} else if (e.getSource() == frac){
pro = "1/(" + num1 + ")";
result_num = Double.toString(1/Double.valueOf(num1));
process.setText(pro);
result.setText(result_num);
num1 = result_num;
} else if (e.getSource() == squa){
pro = "sqr(" + num1 + ")";
result_num = Double.toString(Double.valueOf(num1) * Double.valueOf(num1));
process.setText(pro);
result.setText(result_num);
num1 = result_num;
} else if (e.getSource() == root){
pro = "√(" + num1 + ")";
result_num = Double.toString(Math.sqrt(Double.valueOf(num1)));
process.setText(pro);
result.setText(result_num);
num1 = result_num;
} else if (e.getSource() == sign){
result_num = Double.toString((-1) * (Double.valueOf(num1)));
pro = result_num;
process.setText(pro);
result.setText(result_num);
num1 = result_num;
} else if (e.getSource() == point){
result_num = "0.";
pro = result_num;
process.setText(pro);
result.setText(result_num);
num1 = result_num;
}
// 첫번째 피연산자, 두번째 피연산자와 연산자를 받지 않은 경우 처리
} else if(num1 == null && num2 == null && func == null){
if (e.getSource() == one) {
num1 = "1";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == two) {
num1 = "2";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == three) {
num1 = "3";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == four) {
num1 = "4";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == five) {
num1 = "5";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == six) {
num1 = "6";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == seven) {
num1 = "7";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == eight) {
num1 = "8";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == nine) {
num1 = "9";
pro = num1;
result_num = num1;
process.setText(pro);
result.setText(result_num);
} else if (e.getSource() == zero) {
num1 = "0";
pro = num1;
result_num = num1;
process.setText("0");
result.setText("0");
}
// 첫번째 피연산자, 연산자에 값이 있고 두번째 피연산자를 받지 않은 경우 처리
} else if(num1 != null && num2 == null && func != null) {
if(e.getSource() == plus) {
func = "+";
pro = num1 + func;
process.setText(pro);
} else if (e.getSource() == minus){
func = "-";
pro = num1 + func;
process.setText(pro);
} else if (e.getSource() == mul){
func = "×";
pro = num1 + func;
process.setText(pro);
} else if (e.getSource() == div){
func = "÷";
pro = num1 + func;
process.setText(pro);
} else if (e.getSource() == rem){
func = "%";
pro = num1 + func;
process.setText(pro);
} else if (e.getSource() == one) {
num2 = "1";
pro = pro + num2;
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == two) {
num2 = "2";
pro = pro + num2;
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == three) {
num2 = "3";
pro = pro + num2;
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == four) {
num2 = "4";
pro = pro + num2;
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == five) {
num2 = "5";
pro = pro + num2;
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == six) {
num2 = "6";
pro = pro + num2;
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == seven) {
num2 = "7";
pro = pro + num2;
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == eight) {
num2 = "8";
pro = pro + num2;
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == nine) {
num2 = "9";
pro = pro + num2;
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == zero) {
num2 = "0";
pro = pro + num2;
process.setText(pro);
result.setText(num2);
}
// 첫번째 피연산자, 두번째 피연산자, 연산자에 값이 있는 경우 처리
} else if(num1 != null && num2 != null && func != null) {
if (e.getSource() == one) {
num2 = num2 + "1";
pro = pro + num2.substring(num2.length()-1);
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == two) {
num2 = num2 + "2";
pro = pro + num2.substring(num2.length()-1);
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == three) {
num2 = num2 + "3";
pro = pro + num2.substring(num2.length()-1);
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == four) {
num2 = num2 + "4";
pro = pro + num2.substring(num2.length()-1);
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == five) {
num2 = num2 + "5";
pro = pro + num2.substring(num2.length()-1);
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == six) {
num2 = num2 + "6";
pro = pro + num2.substring(num2.length()-1);
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == seven) {
num2 = num2 + "7";
pro = pro + num2.substring(num2.length()-1);
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == eight) {
num2 = num2 + "8";
pro = pro + num2.substring(num2.length()-1);
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == nine) {
num2 = num2 + "9";
pro = pro + num2.substring(num2.length()-1);
process.setText(pro);
result.setText(num2);
} else if (e.getSource() == zero) {
num2 = num2 + "0";
pro = pro + num2.substring(num2.length()-1);
process.setText(pro);
result.setText(num2);
} else if(e.getSource() == plus) {
func = "+";
num2 = null;
pro = num1 + func;
process.setText(pro);
} else if (e.getSource() == minus){
func = "-";
num2 = null;
pro = num1 + func;
process.setText(pro);
} else if (e.getSource() == mul){
func = "×";
num2 = null;
pro = num1 + func;
process.setText(pro);
} else if (e.getSource() == div){
func = "÷";
num2 = null;
pro = num1 + func;
process.setText(pro);
} else if (e.getSource() == rem){
func = "%";
num2 = null;
pro = num1 + func;
process.setText(pro);
} else if(e.getSource() == equal) {
if(func == "-")
result_num = Double.toString(Double.valueOf(num1) - Double.valueOf(num2));
else if(func == "×")
result_num = Double.toString(Double.valueOf(num1) * Double.valueOf(num2));
else if(func == "÷")
result_num = Double.toString(Double.valueOf(num1) / Double.valueOf(num2));
else if(func == "%")
result_num = Double.toString(Double.valueOf(num1) % Double.valueOf(num2));
else if(func == "+")
result_num = Double.toString(Double.valueOf(num1) + Double.valueOf(num2));
process.setText(result_num);
result.setText(result_num);
num1 = result_num;
}
}
// c 버튼을 클릭한 경우 처리
if(e.getSource() == c) {
num1 = null;
num2 = null;
func = null;
process.setText("");
result.setText("");
// ce 버튼을 클릭한 경우 처리
} else if(e.getSource() == ce) {
if(num1 != null && num2 == null) {
process.setText("");
result.setText("");
} else if(num1 != null && num2 != null) {
result.setText("");
process.setText(num1 + func);
num2 = null;
} else if(num1 == null && num2 == null) {
result.setText("");
process.setText("");
num1 = null;
num2 = null;
}
// <- 버튼을 누른 경우 처리
} else if(e.getSource() == b_space) {
if(num1!= null) {
num1 = num1.substring(0,num1.length()-1);
if(result_num.length() > 0)
result.setText(result_num.substring(0,num1.length()));
}
if(num2 != null) {
num2.substring(0,num2.length()-1);
if(result_num.length() > 0)
result.setText(result_num.substring(0,num1.length()));
}
}
}
}
3) 실행 결과(예시)
4) 결과 상태 및 추가 보완점
- UI 완성
- 숫자 및 연산, 기타 버튼들 모두 동작은 하나 모든 케이스에 대한 대응 못함.
(ex. 소수점의 경우 첫번째 피연산자 입력 시에만 적용)
- 기호 폰트 크기 키우기
- 키패드 벌려놓기(여백칸 없애기)
- 키패드 모양 다른 모양으로 해보기(ex. 원, 삼각형 등)
- 키패드 폰트 넣어보기
- 패드 클릭 시 소리 나오게 하기
- 키패드 배경색 그라데이션으로 하기
- 제작 정보 탭으로 만들어 보기
5) Review
- 이벤트용 클래스를 제외하고 계산 관련 클래스를 만들지 않고 조건문으로만 처리하려고 하니까 코드가 더 복잡해지기만 하고 제기능을 하지 못했다. 내 생각만큼 로직이 점점 복잡해지고 애초에 로직 생각을 잘 안했던 것이 드러났다. 기능 그나마 이벤트 동작 인터페이스 및 클래스는 Google를 뒤적거리며 찾아 쓴 것이다. 문제는 그 안 내용물을 어제 시간을 다 쓰면서 혼자 코딩한 덕분에 시간만 낭비하고 스스로 고쳐나간게 별로 없다. 이미 하루가 지나가고 너무 늦어서 여기까지 하고 내일은 다른 자료도 찾아보고 클래스를 이용해서 반복적인 거는 소거해 나가는 식으로 진행해야겠다.