1. GUI
- 하나의 JPanel을 Container을 사용하듯이 사용했고 메인 JPanel에다가 서브 JPanel을 추가하면서 UI구성.
2. 변수
- ArrayList<String> postfix은 계산하기 편하게 하기위 후위표기법으로 수식을 저장한다.
- Stack<String> opStack은 연산자를 저장하고 후위 표기법 규칙에 따라 postfix에 넣는다.
- StringBuilder sb은 숫자 버튼을 누르면서 숫자를 저장하는 변수
3. 알고리즘
- 1. 숫자버튼을 클릭할 때마다 event처리로 StringBuilder 변수 sb에 append로 숫자 저장
- 2. 연산자가 나올경우 저장된 숫자를 postfix에 저장 후 sb = ""로 초기화한다.
- 3. 연산자는 opStack이 비어있으면 추가.
- 4. 이미 opStack에 연산자가 있을경우, 버튼이 눌린 연산자 vs Stack의 연산자와 비교
- 5. 버튼이 눌린 연산자가 더 우선순위가 높을경우 opStack에 저장
- 6. 버튼이 눌린 연산자가 같거나 더 낮을경우 opStack 연산자를 postfix에 추가, 눌린 연산자는 opStack에 추가
- 7. (1~6)을 반복하고 calculate()로 후위표기식 계산하기
4. 후위 표기법 만들기 예시
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
5. 후위 표기법 계산하기
- 3 2 4 * 1- + 이라는 식이 있다고 가정해본다.
- 푸는법은 간단하다 숫자는 numStack에 저장하고 연산자가 나오면 숫자 2개를 꺼내 연산한다.
- num2 = 4 , num1= 2 연산자 = * 4*2 = 8 ------> postfix = 3 2 4 * 1 - + ----> 3 8 1 - +
- 그 다음 마찬가지로 -가 나왔으므로 8-1 = 7 ------> postfix = 3 7 + -----> postfix = 10
- 최종으로 남은값이 끝이다.
6. 코드
import java.awt.BorderLayout;
import java.awt.ComponentOrientation;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Stack;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
public class Cal_interface extends JFrame implements ActionListener {
Font font = new Font("Bold", Font.BOLD, 35);
JButton oneButton;
JButton twoButton;
JButton threeButton;
JButton fourButton;
JButton fiveButton;
JButton sixButton;
JButton sevenButton;
JButton eightButton;
JButton nineButton;
JButton zeroButton;
JButton emptyButton1;
JButton emptyButton2;
JButton resetButton;
JButton convertSignButton;
JButton decimalButton;
JButton plusButton;
JButton minusButton;
JButton divButton;
JButton mulButton;
JButton equalButton;
JTextArea display;
StringBuilder sb = new StringBuilder();
ArrayList<String> postfix = new ArrayList<>();
Stack<String> opStack = new Stack<>(); // 연산자
Stack<Float> numStack = new Stack<>();
float result = 0; // 중간값의 연산을 위해 calculate()함수에서 사용
public Cal_interface() {
super("계산기");
JPanel gui = new JPanel(new BorderLayout(5, 5));
gui.setBorder(new EmptyBorder(4, 4, 4, 4));
display = new JTextArea();
display.setText("");
display.setFont(font);
gui.add(display, BorderLayout.NORTH);
JPanel panelButtons = new JPanel(new GridLayout(5, 4, 5, 5));
emptyButton1 = new JButton("");
panelButtons.add(emptyButton1);
emptyButton2 = new JButton("");
panelButtons.add(emptyButton2);
resetButton = new JButton("C");
resetButton.setFont(font);
panelButtons.add(resetButton);
divButton = new JButton("/");
divButton.setFont(font);
panelButtons.add(divButton);
sevenButton = new JButton("7");
sevenButton.setFont(font);
panelButtons.add(sevenButton);
eightButton = new JButton("8");
eightButton.setFont(font);
panelButtons.add(eightButton);
nineButton = new JButton("9");
nineButton.setFont(font);
panelButtons.add(nineButton);
mulButton = new JButton("*");
mulButton.setFont(font);
panelButtons.add(mulButton);
fourButton = new JButton("4");
fourButton.setFont(font);
panelButtons.add(fourButton);
fiveButton = new JButton("5");
fiveButton.setFont(font);
panelButtons.add(fiveButton);
sixButton = new JButton("6");
sixButton.setFont(font);
panelButtons.add(sixButton);
minusButton = new JButton("-");
minusButton.setFont(font);
panelButtons.add(minusButton);
oneButton = new JButton("1");
oneButton.setFont(font);
panelButtons.add(oneButton);
twoButton = new JButton("2");
twoButton.setFont(font);
panelButtons.add(twoButton);
threeButton = new JButton("3");
threeButton.setFont(font);
panelButtons.add(threeButton);
plusButton = new JButton("+");
plusButton.setFont(font);
panelButtons.add(plusButton);
convertSignButton = new JButton("Negative");
panelButtons.add(convertSignButton);
zeroButton = new JButton("0");
zeroButton.setFont(font);
panelButtons.add(zeroButton);
decimalButton = new JButton(".");
decimalButton.setFont(font);
panelButtons.add(decimalButton);
equalButton = new JButton("=");
equalButton.setFont(font);
panelButtons.add(equalButton);
oneButton.addActionListener(this);
twoButton.addActionListener(this);
threeButton.addActionListener(this);
fourButton.addActionListener(this);
fiveButton.addActionListener(this);
sixButton.addActionListener(this);
sevenButton.addActionListener(this);
eightButton.addActionListener(this);
nineButton.addActionListener(this);
zeroButton.addActionListener(this);
decimalButton.addActionListener(this);
mulButton.addActionListener(this);
divButton.addActionListener(this);
minusButton.addActionListener(this);
plusButton.addActionListener(this);
equalButton.addActionListener(this);
resetButton.addActionListener(this);
convertSignButton.addActionListener(this);
gui.add(panelButtons, BorderLayout.CENTER);
setBounds(50, 50, 500, 700);
setContentPane(gui);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
// 이벤트 리스너 메소드
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(oneButton)) {
sb.append("1");
display.append("1");
}
else if (e.getSource().equals(twoButton)) {
sb.append("2");
display.append("2");
} else if (e.getSource().equals(threeButton)) {
sb.append("3");
display.append("3");
} else if (e.getSource().equals(fourButton)) {
sb.append("4");
display.append("4");
} else if (e.getSource().equals(fiveButton)) {
sb.append("5");
display.append("5");
} else if (e.getSource().equals(sixButton)) {
sb.append("6");
display.append("6");
} else if (e.getSource().equals(sevenButton)) {
sb.append("7");
display.append("7");
} else if (e.getSource().equals(eightButton)) {
sb.append("8");
display.append("8");
} else if (e.getSource().equals(nineButton)) {
sb.append("9");
display.append("9");
} else if (e.getSource().equals(zeroButton)) {
sb.append("0");
display.append("0");
}
else if (e.getSource().equals(resetButton)) {
sb.setLength(0);
postfix.clear();
opStack.removeAllElements();
numStack.clear();
display.setText("");
}
// +++++++++++++++++++++++++++++++++
else if (e.getSource().equals(plusButton)) { // -<<<
addNumToPostfix();
handleOperator("+");
display.append("+");
} // plus
else if (e.getSource().equals(minusButton)) {
addNumToPostfix();
handleOperator("-");
display.append("-");
} // minusMethod
else if (e.getSource().equals(mulButton)) {
addNumToPostfix();
handleOperator("*");
display.append("*");
} // mulMeThod
else if (e.getSource().equals(divButton)) {
addNumToPostfix();
handleOperator("/");
display.append("/");
} // divMeThod
else if (e.getSource().equals(convertSignButton)) {
sb.append("-");
display.append("-");
}
else if (e.getSource().equals(equalButton)) {
postfix.add(sb.toString());
sb.setLength(0);
while (!opStack.empty()) {
postfix.add(opStack.pop());
}
display.setText(Float.toString(calculate()));
}
else if (e.getSource().equals(decimalButton)) {
sb.append(".");
display.append(".");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Cal_interface ci = new Cal_interface();
}
public int priorityCheck(String op) {
switch (op) {
case ("+"):
return 1;
case ("-"):
return 1;
case ("*"):
return 2;
case ("/"):
return 2;
default:
return -1;
}
}// priorityCheck
public float calculate() {
float num1, num2;
for (int i = 0; i < postfix.size(); i++) {
if (postfix.get(i) == "+") {
System.out.println(numStack.size() + "사이즈" + numStack.peek());
num2 = numStack.pop();
num1 = numStack.pop();
result = num1 + num2;
numStack.push(result);
} else if (postfix.get(i) == "*") {
num2 = numStack.pop();
num1 = numStack.pop();
result = num1 * num2;
numStack.push(result);
} else if (postfix.get(i) == "-") {
num2 = numStack.pop();
num1 = numStack.pop();
result = num1 - num2;
numStack.push(result);
} else if (postfix.get(i) == "/") {
num2 = numStack.pop();
num1 = numStack.pop();
result = num1 / num2;
numStack.push(result);
}
else {
numStack.push(Float.parseFloat(postfix.get(i)));
}
}
postfix.clear();
return numStack.peek();
}// calculateMethod
public void addNumToPostfix() {
if (sb.length() != 0) {
postfix.add(sb.toString());
sb.setLength(0);
}
}// addNumtoPostFix Method
public void handleOperator(String op) {
if (opStack.empty()) {
opStack.add(op);
} else {
if (priorityCheck(opStack.peek()) < priorityCheck(op)) {
opStack.add(op);
} else {
postfix.add(opStack.pop());
opStack.add(op);
}
}
}
}
'JAVA' 카테고리의 다른 글
[JAVA] CardLayout 패널 화면 쉽게 바꾸기 (0) | 2022.04.20 |
---|---|
[Java] 자바로 그림판 만들기(펜, 도형, 파일 읽기 쓰기, 색깔, 굵기) (0) | 2022.04.18 |
[Java] 이클립스와 Mysql 8.0 연동하기 (JDBC 연결) (1) | 2022.04.16 |
[Java] 버튼의 이벤트 처리로 선 그리기 (0) | 2022.04.15 |
[Java] Swing을 이용한 간단한 JFrame 화면 만들기 (0) | 2022.04.14 |