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 |