Mục lục:
1. Code ban đầu
2. Muốn textField sẽ hiển thị phép tính.
Ví dụ: ấn 4+2 thì khi ấn bằng textField hiển thị 4+2 = , còn display hiển thị kết quả là 6.
3. Sửa TextField hiển thị phép tính liên tiếp
Ví dụ: 2 + 3 = + 2 = + 2 = 9.0 thì nó sẽ hiển thị là 2 + 3 = 5; 5+ 2 = 7; 7+ 2 = 9.0
4. Lỗi dấu hiển thị nhiều lần
Ví dụ: 2 --- thì nó hiển thị là 2 - = 0.0 - = 0.0 - = 0.0 - trong khi tôi muốn nó hiển thị là 2-
5. Lỗi thực hiện phép tính liên tiếp
Ví dụ: Khi thực hiện xong 21.0 - 2 = 19.0, nhấn thêm phím 3 để thực hiện phép tính mới thì textField hiển thị là 21.0 - 2 = 19.03, tôi muốn textField chỉ hiển thị số 3 thôi.
6. Xử lí nút bấm √ và log
1.Code ban đầu :
package test;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.Font;
import javax.swing.DropMode;
import javax.swing.SwingConstants;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JPanel;
import java.awt.GridLayout;
import javax.swing.JTextField;
public class Calculator {
private JFrame frame;
private JTextField display;
// Biến để lưu trữ giá trị và phép tính
private double tempFirst = 0.0;
private String operator = "";
private boolean startNewNumber = true;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Calculator window = new Calculator();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Calculator() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 400, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout(0, 0));
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.NORTH);
panel.setLayout(new BorderLayout(0, 0));
display = new JTextField();
display.setHorizontalAlignment(SwingConstants.RIGHT);
display.setFont(new Font("Tahoma", Font.BOLD, 20));
display.setText("0");
panel.add(display, BorderLayout.CENTER);
display.setColumns(10);
textField = new JTextField();
panel.add(textField, BorderLayout.NORTH);
textField.setColumns(10);
JPanel panel_1 = new JPanel();
frame.getContentPane().add(panel_1, BorderLayout.CENTER);
panel_1.setLayout(new GridLayout(5, 4, 5, 5));
// Helper method to create buttons
String[] buttonLabels = {"7", "8", "9", "/",
"4", "5", "6", "*",
"1", "2", "3", "-",
"0", ".", "=", "+",
"C", "DEL"};
for (String label : buttonLabels) {
JButton button = new JButton(label);
button.setFont(new Font("Tahoma", Font.PLAIN, 20));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd.matches("\\d") || cmd.equals(".")) {
if (startNewNumber) {
display.setText(cmd);
startNewNumber = false;
} else {
display.setText(display.getText() + cmd);
}
} else if (cmd.equals("C")) {
display.setText("0");
tempFirst = 0.0;
operator = "";
startNewNumber = true;
} else if (cmd.equals("DEL")) {
String currentText = display.getText();
if (currentText.length() > 0) {
display.setText(currentText.substring(0, currentText.length() - 1));
}
if (display.getText().isEmpty()) {
display.setText("0");
}
} else if (cmd.equals("=")) {
if (!operator.isEmpty()) {
double tempSecond = Double.parseDouble(display.getText());
double result = calculate(tempFirst, tempSecond, operator);
display.setText(String.valueOf(result));
tempFirst = result;
operator = "";
}
startNewNumber = true;
} else {
tempFirst = Double.parseDouble(display.getText());
operator = cmd;
startNewNumber = true;
}
}
});
panel_1.add(button);
}
}
private double calculate(double a, double b, String operator) {
switch (operator) {
case "+": return a + b;
case "-": return a - b;
case "*": return a * b;
case "/":
if (b == 0) {
return 0; // Handle division by zero
}
return a / b;
default: return 0;
}
}
}
2. Muốn textField sẽ hiển thị phép tính.
Dưới đây là cách thực hiện:
1. Khi một số hoặc một phép tính được nhập, cập nhật textField để hiển thị phép tính hiện tại.
2. Khi kết quả được tính toán, cập nhật textField để hiển thị phép tính và kết quả.
3. Sửa TextField hiển thị phép tính liên tiếp
Dưới đây là cách thực hiện:
1. Thêm biến điều kiện newCalculation được sử dụng để xác định khi nào bắt đầu một phép toán mới.
2. Khi bắt đầu một phép toán mới sau dấu =, phép toán mới sẽ bắt đầu từ kết quả của phép toán trước đó.
4. Lỗi dấu hiển thị nhiều lần
4.1. Tại sao lại bị lỗi này?
Để hiểu rõ hơn về cách hoạt động của code này và tại sao nó lại hiển thị như vậy, chúng ta cần xem xét kỹ từng phần của mã nguồn và cách các sự kiện được xử lý. Dưới đây là giải thích từng bước của mã:
Giao diện người dùng (UI):
displaylà mộtJTextFieldđể hiển thị số hiện tại mà người dùng nhập.textFieldlà mộtJTextFieldkhác để hiển thị lịch sử của các phép tính.
Biến toàn cục:
tempFirst: lưu trữ số đầu tiên trong phép tính.operator: lưu trữ toán tử hiện tại (ví dụ: "+", "-", "*", "/").startNewNumber: đánh dấu khi nào bắt đầu nhập một số mới.newCalculation: đánh dấu khi nào bắt đầu một phép tính mới.
Hành vi của các nút:
- Số và dấu chấm ("."): Khi nhấn một số hoặc dấu chấm, nếu
startNewNumberlàtrue, nó sẽ đặt số đó vàodisplay. Nếu không, nó sẽ nối số đó vào cuối chuỗi hiện tại. - "C" (Clear): Đặt lại tất cả các biến và giao diện người dùng về trạng thái ban đầu.
- "DEL" (Delete): Xóa ký tự cuối cùng của
displayvàtextField. - "=": Khi nhấn nút "=":
- Nếu
operatorkhông trống, nó sẽ tính toán kết quả giữatempFirstvà số hiện tại trongdisplay, sau đó hiển thị kết quả.
- Nếu
- Toán tử: Khi nhấn một toán tử (ví dụ: "+", "-", "*", "/"):
- Nếu
newCalculationlàtrue, nó lưu giá trị hiện tại trongdisplayvàotempFirst. - Nếu
newCalculationlàfalse, nó tính toán kết quả giữatempFirstvà số hiện tại trongdisplay, sau đó hiển thị kết quả và lưu kết quả đó vàotempFirst.
- Nếu
- Số và dấu chấm ("."): Khi nhấn một số hoặc dấu chấm, nếu
Lỗi khi nhấn "2 ---": Khi bạn nhấn "2 ---", đây là các bước mà mã thực hiện:
Nhấn "2":
displayhiển thị "2".textFieldthêm "2".
Nhấn "-" lần đầu tiên:
tempFirstđược gán giá trị 2 (giá trị hiện tại củadisplay).operatorđược gán "-".textFieldthêm " - ".(*) newCalculationlàtrue,tempFirstđược đặt là giá trị củadisplay("2"),operatorđược đặt thành "-", vàtextFieldđược thêm "2 - ".(*) operatorđược đặt thành "-",startNewNumberđược đặt thànhtrue, vànewCalculationđược đặt thànhfalse.
Nhấn "-" lần thứ hai:
tempSecondđược gán giá trị 2 (giá trị hiện tại củadisplay).- Tính toán kết quả:
tempFirst - tempSecond = 2 - 2 = 0. textFieldhiển thị "2 - 2 = 0.0 - ".displayhiển thị "0.0".tempFirstđược gán giá trị 0.0.operatorđược gán "-".- (*) Vì
newCalculationlàfalse,tempSecondđược đặt là giá trị củadisplay("2"),resultđược tính bằngcalculate(tempFirst, tempSecond, operator): - (*) Phương thức
calculateđược gọi, thực hiện phép trừ:2.0 - 2.0 = 0.0.
Nhấn "-" lần thứ ba:
tempSecondđược gán giá trị 0.0 (giá trị hiện tại củadisplay).- Tính toán kết quả:
tempFirst - tempSecond = 0.0 - 0.0 = 0. textFieldhiển thị "2 - 2 = 0.0 - 0.0 = 0.0 - ".displayhiển thị "0.0".tempFirstđược gán giá trị 0.0.operatorđược gán "-".
Chúng ta sẽ thực hiện các thay đổi sau:
- Đảm bảo rằng phép tính chỉ được thực hiện khi có hai số (khi nhấn dấu
=). - Chỉ cập nhật
textFieldkhi nhấn vào các nút phép toán (chứ không phải thực hiện tính toán ngay).
Dưới đây là mã để xử lý vấn đề này:
Giải thích :
Dưới đây là chi tiết từng bước khi nhấn nút "-" hai lần liên tiếp.
Giả sử display hiện tại hiển thị "2":
Lần nhấn nút "-" đầu tiên
Khi nhấn nút "-", điều kiện kiểm tra sẽ là:
if (!startNewNumber) { if (!operator.isEmpty()) { double tempSecond = Double.parseDouble(display.getText()); double result = calculate(tempFirst, tempSecond, operator); textField.setText(textField.getText() + " = " + result); display.setText(String.valueOf(result)); tempFirst = result; } else { tempFirst = Double.parseDouble(display.getText()); } } else if (newCalculation) { tempFirst = Double.parseDouble(display.getText()); newCalculation = false; } operator = cmd; textField.setText(display.getText() + " " + cmd + " "); startNewNumber = true;Với
startNewNumberban đầu làtrue,newCalculationcũng làtrue, nên đoạn mã:else if (newCalculation) { tempFirst = Double.parseDouble(display.getText()); newCalculation = false; }sẽ được thực thi:
tempFirstsẽ được đặt thành giá trị củadisplay, tức là 2.0.newCalculationđược đặt thànhfalse.
Sau đó, các dòng mã:
operator = cmd; textField.setText(display.getText() + " " + cmd + " "); startNewNumber = true;sẽ thực thi:
operatorđược đặt thành"-".textFieldđược cập nhật thành "2 - ".startNewNumberđược đặt thànhtrue.
Lần nhấn nút "-" thứ hai
startNewNumber là true, nó không thực hiện vào khối if (!startNewNumber) và else if (newCalculation). Do đó, chương trình tiếp tục vào khối else.else, operator sẽ được cập nhật và textField sẽ được cập nhật để hiển thị toán tử mới:operator = cmd; textField.setText(display.getText() + " " + cmd + " "); startNewNumber = true;operatorđược đặt thành "-".textFieldcập nhật thành "2 - ".startNewNumberđược đặt thànhtrue.
Vậy nên, sau khi nhấn nút "-" lần thứ hai, textField sẽ hiển thị "2 - ".
5. Lỗi thực hiện phép tính liên tiếp
Để thực hiện điều này, ta cần textField và display khởi động lại để bắt đầu một phép tính mới sau khi hoàn tất một phép tính trước đó. Để giải quyết vấn đề này, chúng ta cần đảm bảo rằng sau khi nhấn =, khi người dùng nhấn một phím số mới, textField sẽ bắt đầu lại từ đầu.
Chúng ta sẽ thêm một biến trạng thái khác để theo dõi xem kết quả vừa được hiển thị hay không và thiết lập lại textField khi người dùng nhập một số mới sau khi đã nhấn =. Dưới đây là các thay đổi cần thiết trong mã nguồn của bạn:
- Thêm một biến boolean
resultDisplayedđể theo dõi xem kết quả có đang được hiển thị hay không. - Khi một số mới được nhập sau khi đã nhấn
=, thiết lập lạitextFieldvàdisplay.
6. Xử lí nút bấm √ và log
Phần xử lí được để ngay trong code dẫn tới việc phải ấn số trước khi ấn nút.
Để chỉnh sửa lỗi này, ta sẽ thực hiện như sau:

Không có nhận xét nào:
Đăng nhận xét