이야기박스
Java) 후위수식 계산기 본문
반응형
후위수식 계산기입니다.
마우스 클릭 혹은 키보드로 입력을 받고, 계산을 하는 방식입니다 ^^
간단하게 정수의 계산만 구현했습니다.
<< 클래스 >>
Main - Frame을 키는 클래스
Calculator - JPanel을 상속받아 전체적인 이벤트 및 화면을 담당하는 클래스
NumPad - 버튼들을 담당하는 클래스
History - 결과물을 출력해주는 클래스
Convert - 후위 수식으로 전환해주는 클래스
Evaluate - 후위 수식을 통해 계산을 해주는 클레스
Stack - 스택 클래스
1. Main class
import javax.swing.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Calculator primary = new Calculator();
frame.getContentPane().add(primary);
frame.pack();
frame.setVisible(true);
}
}
2. Calculator class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Calculator extends JPanel implements KeyListener {
private Dimension displaySize;
private JPanel title;
private History history;
private NumPad numPad;
private String strInfix, strResult;
private CalcListener listener;
private JButton[] btnNums, btnOperators;
public Calculator() {
displaySize = new Dimension(800,800);
this.setPreferredSize(displaySize);
this.setBackground(Color.black);
this.setLayout(null);
strInfix = new String("");
strResult = new String("");
listener = new CalcListener();
addKeyListener(this);
setFocusable(true);
layOut();
} // Calculator()
public void layOut() {
title = new JPanel();
title.setBackground(Color.white);
title.setBounds(0, 0, displaySize.width, displaySize.height/8);
this.add(title);
history = new History();
history.setBounds(0,displaySize.height/8,displaySize.width,displaySize.height/8);
this.add(history);
numPad = new NumPad(this, listener);
numPad.setBounds(0, displaySize.height*2/8, displaySize.width, displaySize.height*6/8);
this.add(numPad);
} // layOut()
public void setBtns(JButton[] nums, JButton[] opers) {
btnNums = nums;
btnOperators = opers;
} // setBtns()
public void keyPressed(KeyEvent e) {
} // keyPressed()
public void keyReleased(KeyEvent e) {
} // keyReleased()
public void keyTyped(KeyEvent e) {
char input = e.getKeyChar();
// 0~9
if(input >= '0' && input <= '9') {
strInfix = strInfix + input;
history.setNow(strInfix);
}
// +*-/
else if(input == '+' || input == '-' || input == '*' || input == '/') {
strInfix = strInfix + input;
history.setNow(strInfix);
}
// clear
else if(input == 'c') {
strInfix = "";
history.setNow("0");
}
// calc
else if (input == '=' || input == '\n') {
doCalc();
}
} // keyTyped()
public void doCalc() {
// convert to postfix
Convert convert = new Convert(strInfix);
// calculate
Evaluate evaluate = new Evaluate(convert.getQue());
Double result = evaluate.getResult();
// round
int round = (int)Math.round(result);
// display
strResult = Integer.toString(round);
history.setNow(strResult);
history.setBefore(strInfix);
// feedback
strInfix = strResult;
} // doCalc()
private class CalcListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
JButton but = (JButton)e.getSource();
// clear
if(e.getSource() == btnNums[11]) {
strInfix = "";
history.setNow("0");
}
// calc
else if(e.getSource() == btnNums[10]) {
doCalc();
} else {
strInfix = strInfix + but.getText();
history.setNow(strInfix);
}
} // actionPerformed()
} // CalcListener class
} // Calculator class
3. NumPad class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class NumPad extends JPanel {
private JPanel numbers, operators;
private JButton[] btnNums, btnOperators;
private String[] strNums={"7","8","9","4","5","6","1","2","3","0","=","C"};
private String[] strOperators = {"+","-","*","/"};
private ActionListener listener;
private Calculator calc;
// 800 , 600
public NumPad(Calculator c, ActionListener l) {
this.setLayout(null);
calc = c;
listener = l;
design();
} // NumPad()
public void design() {
numbers = new JPanel();
numbers.setBounds(40, 50, 600, 500);
numbers.setLayout(new GridLayout(4,3));
this.add(numbers);
operators = new JPanel();
operators.setBounds(660, 50, 100, 500);
operators.setLayout(new GridLayout(4,1));
this.add(operators);
addButton();
} // design()
public void addButton() {
btnNums = new JButton[12];
for(int i=0; i<12; i++) {
btnNums[i] = new JButton(strNums[i]);
btnNums[i].addActionListener(listener);
numbers.add(btnNums[i]);
}
btnOperators = new JButton[4];
for(int i=0; i<4; i++) {
btnOperators[i] = new JButton(strOperators[i]);
btnOperators[i].addActionListener(listener);
operators.add(btnOperators[i]);
}
calc.setBtns(btnNums, btnOperators);
} // addButton()
} // NumPad class
4. History class
import javax.swing.*;
import java.awt.*;
public class History extends JPanel{
private JLabel lblNow, lblBefore;
// 800, 100
public History() {
this.setLayout(null);
design();
} // History()
public void design() {
lblNow = new JLabel("0");
lblNow.setBounds(50,60,700,40);
lblNow.setHorizontalAlignment(SwingConstants.LEFT);
lblNow.setFont(new Font("Monofour",Font.ITALIC,25));
this.add(lblNow);
lblBefore = new JLabel();
lblBefore.setBounds(50,10,700,40);
lblBefore.setHorizontalAlignment(SwingConstants.LEFT);
lblBefore.setFont(new Font("Monofour",Font.ITALIC,15));
this.add(lblBefore);
} // design()
public void setNow(String now) {
lblNow.setText(now);
} // setNow()
public void setBefore(String before) {
lblBefore.setText(before);
}
} // History class
5. Stack class
public class Stack {
private Object[] list;
private int top;
private int max;
public Stack() {
max = 150;
top = -1;
list = new Object[max];
}
public void push(Object elem){
list[++top] = elem;
}
public Object pop() {
top--;
return list[top+1];
}
public Object getStack() {
return list[top];
}
public boolean isEmpty() {
return top < 0;
}
public int getTop() {
return top;
}
} // Stack class
6. Convert class
import java.util.regex.*;
import java.util.*;
public class Convert {
private Stack stack;
private String tmp;
private StringBuilder postfix;
private Pattern pat;
private Matcher mat;
private Queue postfixQue;
public Convert(String infix) {
postfix = new StringBuilder();
postfixQue = new LinkedList();
stack = new Stack();
pat = Pattern.compile("[0-9]+|\\(|\\)|\\+|\\-|\\*|\\/");
mat = pat.matcher(infix);
while(mat.find()) {
tmp = mat.group();
if(isNumber(tmp)) {
postfix.append(tmp);
postfixQue.add(tmp);
}
else if (tmp.equals("(")) {
stack.push(tmp);
}
else if (tmp.equals(")")) {
while ( stack.getStack().equals("(") ) {
String savePop = (String)stack.pop();
postfix.append(savePop);
postfixQue.add(savePop);
}
stack.pop();
}
else {
while(!stack.isEmpty() && checkPriority(tmp)) {
String savePop = (String)stack.pop();
postfix.append(savePop);
postfixQue.add(savePop);
}
stack.push(tmp);
} // if.. else
} // for i
while(!stack.isEmpty()) {
String savePop = (String)stack.pop();
postfix.append(savePop);
postfixQue.add(savePop);
}
} // Convert()
public boolean isNumber(String str) {
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
} // try.. catch
} // isStringDouble()
public boolean checkPriority(String tmp) {
return priority(tmp) <= priority((String)stack.getStack());
}
public int priority(String word) {
switch (word) {
case "*": return 5;
case "/": return 5;
case "+": return 4;
case "-": return 4;
default: return 0;
} // switch
} // priority()
public Queue getQue() {
return postfixQue;
}
} // Convert class
7. Evaluate class
import java.util.*;
public class Evaluate {
private double result, oper1, oper2;
private Stack stack;
private String tmp;
public Evaluate(Queue postfix) {
stack = new Stack();
while(!postfix.isEmpty()) {
tmp = postfix.remove();
if(isNumber(tmp)) {
stack.push(Double.valueOf(tmp));
}
else {
oper2 = (double)stack.pop();
oper1 = (double)stack.pop();
stack.push(doOperator(tmp,oper1,oper2));
}
}
result = (double)stack.pop();
} // Evaluate()
public boolean isNumber(String str) {
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
} // try.. catch
} // isStringDouble()
public double doOperator(String op, double oper1, double oper2) {
double retVal;
switch (op) {
case "+": retVal = oper1 + oper2; break;
case "-": retVal = oper1 - oper2; break;
case "*": retVal = oper1 * oper2; break;
case "/": retVal = oper1 / oper2; break;
default: retVal = 0; break;
}
return retVal;
}
public double getResult() {
return result;
}
} // Evaluate class
<< 실행 화면 >>
<< 마무리 >>
디자인은 좀 투박합니다.. ㅎㅎ
어려운 코딩이 아닌만큼 금방 끝났네요.
패턴분석쪽은 잘 몰라서 구글링하다가 찾았어요 ㅎㅎ..
이쪽을 더 공부해 봐야 할거 같아요
그럼 20000
반응형
'Programming Language > JAVA' 카테고리의 다른 글
| Effective java 3/E - study 시작 (0) | 2018.11.16 |
|---|---|
| Java) join 메서드 (0) | 2017.11.24 |
| Java) 하노이 탑, 중간 체크 (0) | 2017.03.25 |
| Java) Hanoi top 계획 (0) | 2017.03.25 |
| JAVA - 로또 번호 뽑기 (0) | 2017.03.17 |