프로그래밍/Java
[JAVA/자바] 공학용계산기 만들기
자바조아!
2021. 1. 14. 00:41
1. 소스코드 |
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javax.swing.*;
import java.text.DecimalFormat;
import java.util.*;
public class MyApp extends Application {
// 연산스택
Stack<String> stack = new Stack<>();
// 결과
List<String> result = new ArrayList<>();
// 출력
List<String> output = new ArrayList<>();
// 계산 화면
TextArea txtA;
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("19m3283");
primaryStage.setWidth(270);
primaryStage.setHeight(410);
MenuBar mBar = new MenuBar();
Menu mFile = new Menu("ファイル");
MenuItem miOpen = new MenuItem("開く");
MenuItem miExit = new MenuItem("終了");
mFile.getItems().add(miOpen);
mFile.getItems().add(miExit);
mBar.getMenus().add(mFile);
BorderPane root = new BorderPane();
root.setTop(mBar);
VBox vbox = new VBox();
txtA = new TextArea("");
txtA.setPrefHeight(100);
VBox.setMargin(txtA, new Insets(3,3, 0, 3));
HBox hbox = new HBox();
Button bt = new Button("sin");
bt.setPrefSize(60, 35);
HBox.setMargin(bt, new Insets(3,3, 3, 3));
Button bt1 = new Button("cos");
bt1.setPrefSize(60, 35);
HBox.setMargin(bt1, new Insets(3, 0, 3, 0));
Button bt2 = new Button("tan");
bt2.setPrefSize(60, 35);
HBox.setMargin(bt2, new Insets(3, 3, 3, 3));
Button bt3 = new Button("削除");
bt3.setPrefSize(60, 35);
HBox.setMargin(bt3, new Insets(3, 3, 3, 0));
root.setBottom(hbox);
hbox.getChildren().addAll(bt,bt1,bt2,bt3);
HBox hbox1 = new HBox();
Button bt4 = new Button("指数");
bt4.setPrefSize(60, 35);
HBox.setMargin(bt4, new Insets(0, 3,3, 3));
Button bt5 = new Button("log");
bt5.setPrefSize(60, 35);
HBox.setMargin(bt5, new Insets(0, 0, 3, 0));
Button bt6 = new Button("剰余");
bt6.setPrefSize(60, 35);
HBox.setMargin(bt6, new Insets(0, 3, 3, 3));
Button bt7 = new Button("√");
bt7.setPrefSize(60, 35);
HBox.setMargin(bt7, new Insets(0, 3, 3, 0));
root.setBottom(hbox1);
hbox1.getChildren().addAll(bt4,bt5,bt6,bt7);
HBox hbox2 = new HBox();
Button bt8 = new Button("1/X");
bt8.setPrefSize(60, 35);
HBox.setMargin(bt8, new Insets(0, 3,3, 3));
Button bt9 = new Button("CE");
bt9.setPrefSize(60, 35);
HBox.setMargin(bt9, new Insets(0, 0,3, 0));
Button bt10 = new Button("C");
bt10.setPrefSize(60, 35);
HBox.setMargin(bt10, new Insets(0, 0,3, 3));
Button bt11 = new Button("/");
bt11.setPrefSize(60, 35);
HBox.setMargin(bt11, new Insets(0, 3,3, 3));
root.setBottom(hbox2);
hbox2.getChildren().addAll(bt8,bt9,bt10,bt11);
HBox hbox3 = new HBox();
Button bt12 = new Button("1");
bt12.setPrefSize(60, 35);
bt12.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt12, new Insets(0, 3,3, 3));
Button bt13 = new Button("2");
bt13.setPrefSize(60, 35);
bt13.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt13, new Insets(0, 3,3, 0));
Button bt14 = new Button("3");
bt14.setPrefSize(60, 35);
bt14.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt14, new Insets(0, 3,3, 0));
Button bt15 = new Button("x");
bt15.setPrefSize(60, 35);
HBox.setMargin(bt15, new Insets(0, 3,3, 0));
root.setBottom(hbox3);
hbox3.getChildren().addAll(bt12,bt13,bt14,bt15);
HBox hbox4 = new HBox();
Button bt16 = new Button("4");
bt16.setPrefSize(60, 35);
bt16.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt16, new Insets(0, 3,3, 3));
Button bt17 = new Button("5");
bt17.setPrefSize(60, 35);
bt17.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt17, new Insets(0, 0,3, 0));
Button bt18 = new Button("6");
bt18.setPrefSize(60, 35);
bt18.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt18, new Insets(0, 0,3, 3));
Button bt19 = new Button("ㅡ");
bt19.setPrefSize(60, 35);
HBox.setMargin(bt19, new Insets(0, 0,3, 3));
root.setBottom(hbox4);
hbox4.getChildren().addAll(bt16,bt17,bt18,bt19);
HBox hbox5 = new HBox();
Button bt20 = new Button("7");
bt20.setPrefSize(60, 35);
bt20.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt20, new Insets(0, 3,3, 3));
Button bt21 = new Button("8");
bt21.setPrefSize(60, 35);
bt21.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt21, new Insets(0, 3,3, 0));
Button bt22 = new Button("9");
bt22.setPrefSize(60, 35);
bt22.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt22, new Insets(0, 3,3, 0));
Button bt23 = new Button("+");
bt23.setPrefSize(60, 35);
HBox.setMargin(bt23, new Insets(0, 3,3, 0));
root.setBottom(hbox5);
hbox5.getChildren().addAll(bt20,bt21,bt22,bt23);
HBox hbox6 = new HBox();
Button bt24 = new Button("+/ㅡ");
bt24.setPrefSize(60, 35);
bt24.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt24, new Insets(0, 0,3, 3));
Button bt25 = new Button("0");
bt25.setPrefSize(60, 35);
bt25.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt25, new Insets(0, 0,3, 3));
Button bt26 = new Button(".");
bt26.setPrefSize(60, 35);
bt26.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE");
HBox.setMargin(bt26, new Insets(0, 0,3, 3));
Button bt27 = new Button("=");
bt27.setPrefSize(60, 35);
HBox.setMargin(bt27, new Insets(0, 0,3, 3));
root.setBottom(hbox6);
hbox6.getChildren().addAll(bt24,bt25,bt26,bt27);
root.setCenter(vbox);
vbox.getChildren().addAll(txtA,hbox,hbox1,hbox2,hbox3,hbox4,hbox5,hbox6);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
//Stack 내에 있을 때 연산자 우선순위 : 낮->높
HashMap<String, Integer> inP = new HashMap<String, Integer>();
inP.put("(", 0); // 왼쪽 괄호는 스택 내에 있을 땐 우선순위 제일 낮음
inP.put("+", 1); // 따라서 어떤 연산자든 위에 쌓일 수 있음
inP.put("-", 1);
inP.put("*", 2);
inP.put("/", 2);
//Stack 밖에서의 연산자 우선순위 : 낮->높
HashMap<String, Integer> outP = new HashMap<String, Integer>();
outP.put("+", 1);
outP.put("-", 1);
outP.put("*", 2);
outP.put("/", 2);
outP.put("(", 3);
// [C]
bt10.setOnAction(event -> {
txtA.setText("");
});
// [CE]
bt9.setOnAction(event -> {
String v = txtA.getText();
if( v .length() != 0){
txtA.setText(v.substring(0, v.length() - 1));
}
});
// [/]
bt11.setOnAction(event -> {
txtA.setText(txtA.getText() + "/");
});
// [1]
bt12.setOnAction(event -> {
txtA.setText(txtA.getText() + "1");
});
// [2]
bt13.setOnAction(event -> {
txtA.setText(txtA.getText() + "2");
});
// [3]
bt14.setOnAction(event -> {
txtA.setText(txtA.getText() + "3");
});
// [*]
bt15.setOnAction(event -> {
txtA.setText(txtA.getText() + "*");
});
// [4]
bt16.setOnAction(event -> {
txtA.setText(txtA.getText() + "4");
});
// [5]
bt17.setOnAction(event -> {
txtA.setText(txtA.getText() + "5");
});
// [6]
bt18.setOnAction(event -> {
txtA.setText(txtA.getText() + "6");
});
// [-]
bt19.setOnAction(event -> {
txtA.setText(txtA.getText() + "-");
});
// [7]
bt20.setOnAction(event -> {
txtA.setText(txtA.getText() + "7");
});
// [8]
bt21.setOnAction(event -> {
txtA.setText(txtA.getText() + "8");
});
// [9]
bt22.setOnAction(event -> {
txtA.setText(txtA.getText() + "9");
});
// [+]
bt23.setOnAction(event -> {
txtA.setText(txtA.getText() + "+");
});
// [0]
bt25.setOnAction(event -> {
txtA.setText(txtA.getText() + "0");
});
// [.]
bt26.setOnAction(event -> {
txtA.setText(txtA.getText() + ".");
});
// [sin]
bt.setOnAction(event -> {
txtA.setText(txtA.getText() + "sin");
});
// [tan]
bt2.setOnAction(event -> {
txtA.setText(txtA.getText() + "tan");
});
// [cos]
bt1.setOnAction(event -> {
txtA.setText(txtA.getText() + "cos");
});
// [削除] 삭제
bt3.setOnAction(event -> {
String v = txtA.getText();
if( v .length() != 0){
txtA.setText(v.substring(0, v.length() - 1));
}
});
// [指数] 지수
bt4.setOnAction(event -> {
txtA.setText(txtA.getText() + "e^");
});
// [剰余] 거듭제곱
bt6.setOnAction(event -> {
txtA.setText(txtA.getText() + "^");
});
// [√] 루트
bt7.setOnAction(event -> {
txtA.setText(txtA.getText() + "√");
});
// [1/X] 역수
bt8.setOnAction(event -> {
String v = txtA.getText();
txtA.setText("1/("+ v +")");
});
// [+/-] 루트
bt24.setOnAction(event -> {
String v = txtA.getText();
txtA.setText("-1*("+ v +")");
});
// [=]
bt27.setOnAction(event -> {
try {
result.clear();
output.clear();
StringBuffer buffer = new StringBuffer();
String expression = txtA.getText();
for( int i = 0; i < expression.length() ; i++) {
String c = String.valueOf(expression.charAt(i));
if ("+".equals(c) || "-".equals(c) || "*".equals(c) || "/".equals(c)) {
String v = Calculate(buffer.toString());
result.add(v);
result.add(c);
buffer.setLength(0);
} else if ("(".equals(c) || ")".equals(c)){
result.add(c);
}else{
buffer.append(c);
}
}
if( buffer.length() != 0 ) {
String v = Calculate(buffer.toString());
result.add(v);
buffer.setLength(0);
}
StringTokenizer st = new StringTokenizer(String.join(" ", result));
while(st.hasMoreTokens()) {
String token = st.nextToken();
if(token.equals("(") || token.equals("/") || token.equals("*") || token.equals("-") || token.equals("+")) {
//스택이 비어있으면
if(stack.isEmpty()) {
stack.push(token);
//스택 비어있지 않으면
}else {
// 우선순위 : top < token
if(inP.get(stack.peek()) < outP.get(token)) {
stack.push(token);
}else {
// 우선순위 : top > token
while(true) {
if(inP.get(stack.peek()) <= outP.get(token)) {
stack.push(token);
break;
} // 우선순위 : top < token 될때까지 Stack pop
output.add(stack.pop());
}
}
}
// 토큰이 오른쪽 괄호
} else if(token.equals(")")) {
while(true) {
if(stack.peek().equals("(")) {
stack.pop();
break;
}
output.add(stack.pop());
}
// 토큰이 숫자
} else {
output.add(token);
}
}
if(!st.hasMoreTokens()) {
while(true) {
if(stack.isEmpty()) {
break;
}
output.add(stack.pop());
}
}
int len = output.size();
Stack<Double> sum = new Stack<Double>();
int i=0;
while(i<len) {
if(output.get(i).equals("+")) {
double p; double q;
q = sum.pop();
p = sum.pop();
sum.add(p+q);
}else if(output.get(i).equals("-")) {
double p; double q;
if( sum.size() == 1){
q = sum.pop();
sum.add(-1*q);
}else{
q = sum.pop();
p = sum.pop();
sum.add(p-q);
}
}else if(output.get(i).equals("*")) {
double p; double q;
q = sum.pop();
p = sum.pop();
sum.add(p*q);
}else if(output.get(i).equals("/")) {
double p; double q;
q = sum.pop();
p = sum.pop();
sum.add(p/q);
}else {
sum.add(Double.parseDouble(output.get(i)));
}
i++;
}
Double s = sum.pop();
DecimalFormat df=new DecimalFormat("#.###############");
txtA.setText(df.format(s));
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "수식이 올바른지 확인해주세요.");
e.printStackTrace();
}
});
}
private String Calculate(String v) {
if( v.contains("sin")){
String n = v.substring(0, v.indexOf("sin"));
String m = v.substring(v.indexOf("sin") + 3, v.length());
if( n.length() == 0){
v = String.valueOf(Math.sin(Double.parseDouble(m)));
}else{
v = String.valueOf(Math.sin(Double.parseDouble(m)) * Double.parseDouble(n));
}
}else if( v.contains("cos")){
String n = v.substring(0, v.indexOf("cos"));
String m = v.substring(v.indexOf("cos") + 3, v.length());
if( n.length() == 0){
v = String.valueOf(Math.cos(Double.parseDouble(m)));
}else{
v = String.valueOf(Math.cos(Double.parseDouble(m)) * Double.parseDouble(n));
}
}else if( v.contains("tan")){
String n = v.substring(0, v.indexOf("tan"));
String m = v.substring(v.indexOf("tan") + 3, v.length());
if( n.length() == 0){
v = String.valueOf(Math.tan(Double.parseDouble(m)));
}else{
v = String.valueOf(Math.tan(Double.parseDouble(m)) * Double.parseDouble(n));
}
}else if( v.contains("e^")){
String n = v.substring(0, v.indexOf("e^"));
String m = v.substring(v.indexOf("e^") + 2, v.length());
if( n.length() == 0){
v = String.valueOf(Math.exp(Double.parseDouble(m)));
}else{
v = String.valueOf(Math.pow( 2.71828 * Double.parseDouble(n), Double.parseDouble(m)));
}
}else if( v.contains("^")){
String n = v.substring(0, v.indexOf("^"));
String m = v.substring(v.indexOf("^") + 1, v.length());
v = String.valueOf(Math.pow(Double.parseDouble(n), Double.parseDouble(m)));
}else if( v.contains("√")){
String n = v.substring(0, v.indexOf("√"));
String m = v.substring(v.indexOf("√") + 1, v.length());
if( n.length() == 0){
v = String.valueOf(Math.sqrt(Double.parseDouble(m)));
}else{
v = String.valueOf(Math.sqrt(Double.parseDouble(m)) * Double.parseDouble(n));
}
}
return v;
}
public static void main(String[] args) {
launch(args);
}
}
2. 결과 |