본문 바로가기
PROJECT

[JAVA] 자바 계산기 만들기 (클래스 및 메소드 분리)

by 아이엠제니 2024. 4. 17.


 

 

 

 

[JAVA] Make a calculator 계산기 만들기

유튜버 '동현'님 유튜브 참고해서 제작 1~4 https://youtu.be/zFAPpiL17ow '자바'로 계산기 만들기 찾다가! 유튜브에서 '동현'님 영상을 보게 되어, 참고해서 만들었다. 동현님 제작 계산기 / 내가 제작한

devje.tistory.com

2022년에 유튜브를 보고 따라 만들었던 계산기.

따라서 만들다 보니, 이전에는 한 클래스 안에 또 다른 클래스와 메소드 그리고 메인 메소드까지 길게 있었다.

언젠가 클래스랑 메소드를 분리해보고 싶다는 생각을 했었는데, 드디어 분리를 해봤다.

 

 

 

기존에 `Calculator` 클래스로 되어있던 것을 이렇게 3개의 클래스로 분리를 했다.

  • `Main` 클래스는 호출만 함
  • `Calculator`는 패널과 관련된 부분
  • `PadActionListener`은 계산 관련 

 

 

 


 

👉 Main.java

public class Main {
    public static void main(String[] args) {
        new Calculator();
    }
}

 

 

 

👉 Calculator.java

import javax.swing.*; // 운영체제에 상관없이 자바에서 제공하는 기능을 받아옴
import java.awt.*; // 운영체제에 따른 화면구성 도와줌

public class Calculator extends JFrame { // JFrame 상속

    public Calculator() {
        setLayout(null); // 기본 레이아웃 관리자 제거

        // 라벨
        JLabel userNameInfo = new JLabel("USER : ");
        userNameInfo.setFont(new Font("나눔고딕", Font.BOLD, 15)); // 폰트
        userNameInfo.setBounds(10, 15, 80, 30); //위치


        // 네임 입력
        JLabel userNameInput = new JLabel("JeLog"); //데이터베이스 연결할 자리
        userNameInput.setHorizontalAlignment(userNameInput.LEFT); // 정렬
        userNameInput.setFont(new Font("나눔고딕", Font.BOLD, 15)); // 폰트
        userNameInput.setBounds(85, 15, 80, 30); //위치

        // 계산 창
        PadActionListener padActionListener = new PadActionListener();
        JTextField jTextField = new JTextField();// instance
        jTextField.setEditable(false); // 편집 불가능
        jTextField.setBackground(Color.WHITE); // 배경색
        jTextField.setHorizontalAlignment(JTextField.RIGHT); // 정렬
        jTextField.setFont(new Font("나눔고딕", Font.BOLD, 35)); // 폰트
        jTextField.setBounds(8, 55, 270, 50); // x:8 y:10 위치, 270*70 크기 의미
        padActionListener.setInputSpace(jTextField);

        // 버튼 담을 패널
        JPanel buttonPanel = new JPanel(); // 버튼 담음
        buttonPanel.setLayout(new GridLayout(4, 4, 10, 10)); // 가로 칸수, 세로 칸수, 좌우 간격, 상하 간격 => 격자 형태 배치
        buttonPanel.setBounds(8, 115, 270, 235); // 위치

        // 버튼 정보 입력
        String[] button_names = {"7", "8", "9", "÷", "4", "5", "6", "×", "1", "2", "3", "-", "C", "0", "=", "+"}; //계산기 버튼 글자 배열 (16)
        JButton[] buttons = new JButton[button_names.length]; //버튼 배열

        // 버튼 생성
        for (int i = 0; i < button_names.length; i++) {
            buttons[i] = new JButton(button_names[i]);
            buttons[i].setFont(new Font("나눔고딕", Font.BOLD, 20));

            // 배열 0~3 4~7 8~11 12~15
            if (button_names[i].equals("C")) {
                buttons[i].setBackground(Color.blue); // 배경색
                buttons[i].setForeground(Color.white); //글자색
            } else if ((i >= 0 && i <= 2) || (i >= 4 && i <= 6) || (i >= 8 && i <= 10) || i == 13) {
                buttons[i].setBackground(Color.white); // 배경색
            } else {
                buttons[i].setForeground(Color.white); //글자색
                buttons[i].setBackground(Color.gray);
            }
            buttons[i].setBorderPainted(false); //테두리 제거
            buttons[i].addActionListener(padActionListener); // 액션리스너 버튼에 추가
            buttonPanel.add(buttons[i]);
        }

        // 패널에 추가
        add(padActionListener.getInputSpace());
        add(buttonPanel);
        add(userNameInfo);
        add(userNameInput);

        // 창 제목, 창 보이기, 창 사이즈 등
        setTitle("계산기"); //제목
        setVisible(true); //프레임 보이기
        setSize(300, 400);
        setLocationRelativeTo(null); // 화면 가운데
        setResizable(false); // 사이즈 조절 불가
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 창 닫을 때 실행 중인 프로그램도 종료
    }
}

 

 

 

👉 PadActionListener.java

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

public class PadActionListener implements ActionListener {
    private JTextField inputSpace;
    private String num = ""; // 계산식의 숫자를 담음
    private String prevOperation = ""; // 작동 기억하도록 변수 하나 생성
    private ArrayList<String> equation = new ArrayList<>(); // 숫자와 연산 기호를 구분해서 담음

//    getActionCommand() 이벤트가 발생한 객체의 텍스트가 리턴
//    getSource() 이벤트가 발생한 객체의 해시코드가 리턴
//    getModifiers() 이벤트가 발생했을 때 같이 누른 조합키(Alt, Ctrl, Shift) 값이 리턴

    public JTextField getInputSpace() {
        return inputSpace;
    }

    public void setInputSpace(JTextField inputSpace) {
        this.inputSpace = inputSpace;
    }

    @Override
    public void actionPerformed(ActionEvent e) { // 이벤트 처리
        String operation = e.getActionCommand(); //어떤 버튼 눌렸는지 받아옴

        if (operation.equals("C")) { //만약 C버튼이라면 계산식 내용을 지워줌
            inputSpace.setText("");
        } else if (operation.equals("=")) { //만약 =이라면 입력된 식을 계산해 계산값이 나오도록 함
            String result = Double.toString(calculate(inputSpace.getText())); //계산 기능
            inputSpace.setText("" + result);
            num = "";
        } else if (operation.equals("+") || operation.equals("-") || operation.equals("÷") || operation.equals("×")) {
            if (inputSpace.getText().equals("") && operation.equals("-")) { //음수
                inputSpace.setText(inputSpace.getText() + e.getActionCommand());
            } else if (!inputSpace.getText().equals("") && !prevOperation.equals("+") && !prevOperation.equals("-") && !prevOperation.equals("÷") && !prevOperation.equals("×")) {
                inputSpace.setText(inputSpace.getText() + e.getActionCommand());
            }
        } else { //나머지 버튼 눌렀을 경우 계산식에 추가되도록 함
            inputSpace.setText(inputSpace.getText() + e.getActionCommand());
        }
        prevOperation = e.getActionCommand(); //마지막으로 누른 버튼 기억
    }

    // 숫자 & 연산자
    private void fullTextParsing(String inputText) {
        equation.clear();

        for (int i = 0; i < inputText.length(); i++) { //계산식의 글자를 하나하나 거쳐감
            char ch = inputText.charAt(i);

            if (ch == '-' || ch == '+' || ch == '÷' || ch == '×') {
                equation.add(num);
                num = "";
                equation.add(ch + ""); //num 초기화하고, 연산 기호를 ArrayList에 추가
            } else {
                num = num + ch; //나머지 숫자의 경우 num문자에 더해줌
            }
        }
        equation.add(num);
        equation.remove("");
    }

    //    계산기능
    public double calculate(String inputText) {
        fullTextParsing(inputText);

        double prev = 0;
        double current = 0;
        String mode = ""; // 연산 기호에 대한 처리

        for (int i = 0; i < equation.size(); i++) {
            String s = equation.get(i);

            if (s.equals("+")) {
                mode = "add";
            } else if (s.equals("÷")) {
                mode = "div";
            } else if (s.equals("×")) {
                mode = "mul";
            } else { //숫자 double로 형 변환
                if ((mode.equals("mul") || mode.equals("div")) && (!s.equals("+") && !s.equals("-") && !s.equals("÷") && !s.equals("×"))) {
                    Double one = Double.parseDouble(equation.get(i - 2));
                    Double two = Double.parseDouble(equation.get(i));
                    Double result = 0.0;

                    if (mode.equals("mul")) {
                        result = one * two;
                    } else if (mode.equals("div")) {
                        result = one / two;
                    }
                    equation.add(i + 1, Double.toString(result));

                    for (int j = 0; j < 3; j++) {
                        equation.remove(i - 2);
                    }
                    i -= 2; //결과값이 생긴 인덱스로 이동
                }
            }
        } //곱셈 나눗셈을 먼저 계산한다

        for (String s : equation) {
            if (s.equals("+")) {
                mode = "add";
            } else if (s.equals("-")) {
                mode = "sub";
            } else {
                current = Double.parseDouble(s);
                if (mode.equals("add")) {
                    prev += current;
                } else if (mode.equals("sub")) {
                    prev -= current;
                } else {
                    prev = current;
                }
            }
            prev = Math.round(prev * 100000) / 100000.0; //소수점 자리 제한
        }
        return prev;
    }
}

 

 


 

 

Java Swing

  • 자바에서 GUI를 만들기 위한 툴킷
  • 다양한 GUI 컴포넌트와 이벤트 처리 기능을 제공함
  • `JFrame`, `JButton`, `JTextField` 등 Swing의 클래스와 인터페이스를 사용하려면 이러한 패키지를 가져와야 함

 

AWT

  • Abstract Window Toolkit의 일부를 가져옴
  • AWT는 자바의 초기 GUI 툴킷 중 하나임
  • 자바의 기본 GUI 컴포넌트와 이벤트 모델을 제공함
  • 여기서는 Font, Color, GridLayout 사용으로 해당 툴킷 사용

 


 

구 / 신

왼쪽이 과거에 만들었던 파스텔톤 계산기.

그리고 이번에 클래스랑 메소드를 분리하면서 리뉴얼 한 계산기.

 

 

 

덧셈

 

 

 

뺄셈

 

 

 

곱셈

 

 

 

나눗셈

 

이전에 마이너스 관련해서, 의문이 들었던 게 있었는데?

여전히 의문이다.

일단 그 부분은 아예 빼버렸다.

그 부분에 대한 해결과 기능 추가가 있을 경우 다시 돌아와서 글을 쓰도록 해야겠다.

 

 

 

참고
'동현' 유튜브 <자바(Java)로 계산기 만들기> 참고 후 제작

 

 

 

300x250