국비교육(22-23)

20일차(3)/java 퀴즈 : Frame객체로 계산기 만들기

서리/Seori 2022. 11. 2. 20:00

20일차(3)/java 퀴즈 : Swing 으로 계산기 만들기

 

Frame11

 

 

<내가 작성한 코드>

package frame11;

import java.awt.BorderLayout;
import java.awt.Color;
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.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class MyFrame extends JFrame {
   //필드
   JTextField tf_num1, tf_num2;
   JLabel label_result;
   
   
   //default  생성자
   public MyFrame() {
      //프레임의 레이아웃 법칙 설정하기 
      setLayout(new BorderLayout());
      
      //JPanel
      JPanel topPanel=new JPanel();
      topPanel.setBackground(Color.YELLOW);
      //Panel 을 북쪽에 배치하기 
      add(topPanel, BorderLayout.NORTH);
      
      //JTextField 객체를 만들에서 JPanel 에 추가하기 
      JTextField tf_num1=new JTextField(10);
      topPanel.add(tf_num1);
      //기능 버튼 객체를 만들어서 JPanel 에 추가하기
      JButton plusBtn=new JButton("+");
      JButton minusBtn=new JButton("-");
      JButton multiBtn=new JButton("*");
      JButton divideBtn=new JButton("/");
      topPanel.add(plusBtn);
      topPanel.add(minusBtn);
      topPanel.add(multiBtn);
      topPanel.add(divideBtn);
      //두번째 JTextField  만들어서 페널에 추가 하기 
      JTextField tf_num2=new JTextField(10);
      topPanel.add(tf_num2);
      //JLabel
      JLabel label1=new JLabel("=");
      JLabel label_result=new JLabel("0");
      //페널에 레이블 추가하기
      topPanel.add(label1);
      topPanel.add(label_result);
      
      //try:들어온 값이 숫자면=>계산, catch:숫자가 아니면=>알림창 띄우기
      try {
    	  plusBtn.addActionListener(new ActionListener() {		
    			@Override
    			public void actionPerformed(ActionEvent e) {
    				double num1=Double.parseDouble(tf_num1.getText());
    				double num2=Double.parseDouble(tf_num2.getText());    				
    				String plus=Double.toString(num1+num2);
    				label_result.setText(plus);
    			}
    	  });
    	  
    	  minusBtn.addActionListener(new ActionListener() {		
  			@Override
  			public void actionPerformed(ActionEvent e) {
  				double num1=Double.parseDouble(tf_num1.getText());
  				double num2=Double.parseDouble(tf_num2.getText());    				
  				String minus=Double.toString(num1-num2);
  				label_result.setText(minus);
  			}
    	  });
    	  
    	  multiBtn.addActionListener(new ActionListener() {		
    			@Override
    			public void actionPerformed(ActionEvent e) {
    				double num1=Double.parseDouble(tf_num1.getText());
    				double num2=Double.parseDouble(tf_num2.getText());    				
    				String multi=Double.toString(num1*num2);
    				label_result.setText(multi);
    			}
      	  });
    	  
    	  divideBtn.addActionListener(new ActionListener() {		
    			@Override
    			public void actionPerformed(ActionEvent e) {
    				double num1=Double.parseDouble(tf_num1.getText());
    				double num2=Double.parseDouble(tf_num2.getText());    				
    				String divide=Double.toString(num1/num2);
    				label_result.setText(divide);
    			}
      	  });    	
    	  
		
      } catch (NumberFormatException nfe) {
    	  JOptionPane.showMessageDialog(MyFrame.this,"숫자 형식으로 입력하세요.");
      }
      
   }
   
   public static void main(String[] args) {
      //MyFrame 클래스를 이용해서 객체 생성하고 참조값을 지역변수 frame 에 담기 
      MyFrame frame=new MyFrame();
      //프레임의 제목 설정
      frame.setTitle("계산기");
      //프레임을 닫으면 자동으로 프로세스가 종료 되도록 한다.
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setBounds(100, 100, 500, 500);
      frame.setVisible(true);
   }
}

 

- 계산은 되는데 오류처리가 안됨 ㅠㅠ

 

 

 

<다른 작성법>

package frame11;

import java.awt.BorderLayout;
import java.awt.Color;
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.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class MyFrame extends JFrame implements ActionListener{
   //필드
   JTextField tf_num1, tf_num2;
   JLabel label_result;
   
   
   //default  생성자
   public MyFrame() {
      //프레임의 레이아웃 법칙 설정하기 
      setLayout(new BorderLayout());
      
      //JPanel
      JPanel topPanel=new JPanel();
      topPanel.setBackground(Color.YELLOW);
      //Panel 을 북쪽에 배치하기 
      add(topPanel, BorderLayout.NORTH);
      
      //JTextField 객체를 만들에서 JPanel 에 추가하기 
      tf_num1=new JTextField(10);
      topPanel.add(tf_num1);
      //기능 버튼 객체를 만들어서 JPanel 에 추가하기
      JButton plusBtn=new JButton("+");
      JButton minusBtn=new JButton("-");
      JButton multiBtn=new JButton("*");
      JButton divideBtn=new JButton("/");
      topPanel.add(plusBtn);
      topPanel.add(minusBtn);
      topPanel.add(multiBtn);
      topPanel.add(divideBtn);
      //두번째 JTextField  만들어서 페널에 추가 하기 
      tf_num2=new JTextField(10);
      topPanel.add(tf_num2);
      //JLabel
      JLabel label1=new JLabel("=");
      label_result=new JLabel("0");
      //페널에 레이블 추가하기
      topPanel.add(label1);
      topPanel.add(label_result);
      
      //버튼에 리스너 등록하기
      plusBtn.addActionListener(this);
      minusBtn.addActionListener(this);
      multiBtn.addActionListener(this);
      divideBtn.addActionListener(this);
   }
   
   public static void main(String[] args) {
      //MyFrame 클래스를 이용해서 객체 생성하고 참조값을 지역변수 frame 에 담기 
      MyFrame frame=new MyFrame();
      //프레임의 제목 설정
      frame.setTitle("계산기");
      //프레임을 닫으면 자동으로 프로세스가 종료 되도록 한다.
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setBounds(100, 100, 500, 500);
      frame.setVisible(true);
   }
	
	@Override
	public void actionPerformed(ActionEvent e) {
		try {
			//1. 입력한 문자열을 읽어와서 숫자로 바꿔준다.
			double num1=Double.parseDouble(tf_num1.getText());
			double num2=Double.parseDouble(tf_num2.getText());
			//2. 어떤 버튼을 눌렀는지 알아내서 적절한 연산을 해서 결과를 얻어낸다.
			String command=e.getActionCommand(); //"+" "-" "*" "/"
			//연산의 결과를 담을 지역변수를 미리 만들어 놓는다.
			double result=0;
			if(command.equals("+")) {
				result=num1+num2;
			} else if (command.equals("-")){
				result=num1-num2;
			} else if (command.equals("*")){
				result=num1*num2;
			} else if (command.equals("/")){
				result=num1/num2;
			}
			
			//3. 연산의 결과를 출력한다.
			//연산의 결과를 문자열로 만든다.
			String resultNum=Double.toString(result);
			label_result.setText(resultNum);
		}catch(NumberFormatException nfe){
			JOptionPane.showMessageDialog(this, "숫자 형식으로 입력해주세요");
			tf_num1.setText("");
			tf_num2.setText("");
		}
		
	}
}

- 버튼마다 액션리스너를 만들게 아니라 액션리스너를 하나로 만들기.
→ ActionListener를 구현해서 frame이 ActionListener 기능을 하게 만든다.

@Override
public void actionPerformed(ActionEvent e) { }

- 구현하면 미완성 메소드의 override 필요.

- ActionEvent 객체를 전달받을 준비가 되어있는 actionPerformed 메소드를 완성해야 한다.

 

- tf_num1, tf_num2 /  label_result 를 지역변수가 아닌 필드에 넣는 것으로 수정하기. 

 

.parseDouble, .parseInteger, ... 

- 문자열 타입으로 되어있는 숫자를 실제 숫자로 바꾸어주는 메소드

 

 

 

- 디버그모드 실행하면 Frame 창이 뜨고, 값을 입력하면 그때 디버그모드가 작동한다.

 

- ActionCommand 를 따로 설정하지 않으면 버튼의 텍스트가 자동으로 ActionCommand가 된다.

 (여기서는 "+" . "-" , "*" , "/" )

 

if(command.equals("+")) {
    double result=num1+num2;
} else if (command.equals("-")){
    double result=num1-num2;
}else if (command.equals("*")){
    double result=num1*num2;
}else if (command.equals("/")){
    double result=num1/num2;
}

label_result.setText();

- .setText(); 는 문자열 타입밖에 받지 못하기 때문에, 결과값 숫자를 다시 문자로 바꾸어야 한다.

- 그리고 위와 같이 작성하면 result가 if문 안에 들어있는 변수여서 if문이 끝나면 사라지기 때문에,

  result 지역변수는 if문 밖에 미리 만들어두어야 한다.

- 연산의 결과를 담을 지역변수를 미리 만들어놓고 사용하기!

 

 

- 예외처리: 숫자가 아닐 때! NumberFormatException

 (double에서는 0으로 나누는 값은 예외로 나오지는 않는다. infinity라고 나옴)

- 문제가 생길 가능성이 있는 부분을 try{ } 안에 넣는다.

- catch{ } 안에는 창을 띄우는 showMessageDialog 코드를 작성

 

 

- 입력창을 지우는 메소드가 뒤에 있지만 아직 실행되지 않고 있다.

 안내 창의 확인을 누르기 전까지는 실행의 흐름은 멈춰있다. TextField에 입력도 되지 않는다.

 메시지 창에 잡혀있어서 더 이상 진행이 안되는것. 빠져나와야 다음 대응을 할 수 있다.

→ 이 프레임에는 실행의 흐름이 오직 한 줄기밖에 없다는 것을 알 수 있다.

 

ex) 카페에 갔는데 직원이 한명뿐이고, 다른사람의 주문을 받고있다.

    그 사람의 주문이 끝나야만 내 주문을 받을 수 있는 것!

 

- 원한다면 여러개의 실행의 흐름(스레드)을 만들 수도 있다.

 

- 코딩하며 다 완성되지 않았더라도 중간중간 run 해보기!

'국비교육(22-23)' 카테고리의 다른 글

21일차(2)/java(29) : Input, Output(1)  (0) 2022.11.04
21일차(1)/java(28) : Thread  (0) 2022.11.03
20일차(2)/java(27) : Frame(3)  (0) 2022.11.02
20일차(1)/java(26) : Frame(2)  (0) 2022.11.02
19일차(4)/java(25) : Frame(1)  (0) 2022.11.01