package ll;
public class CalculatorModel {
public double calculate(String expression) {
return evaluateExpression(expression);
}
private double evaluateExpression(String expression) {
return new Object() {
int pos = -1, ch;
void nextChar() {
ch = (++pos < expression.length()) ? expression.charAt(pos) : -1;
}
boolean eat(int charToEat) {
while (ch == ' ') nextChar();
if (ch == charToEat) {
nextChar();
return true;
}
return false;
}
double parse() {
nextChar();
double x = parseExpression();
if (pos < expression.length()) throw new RuntimeException("Lỗi: Biểu thức không hợp lệ");
return x;
}
double parseExpression() {
double x = parseTerm();
for (;;) {
if (eat('+')) x += parseTerm();
else if (eat('-')) x -= parseTerm();
else return x;
}
}
double parseTerm() {
double x = parseFactor();
for (;;) {
if (eat('*')) x *= parseFactor();
else if (eat('/')) x /= parseFactor();
// else if (eat('%')) x %= parseFactor(); // Thêm phép chia lấy dư
else return x;
}
}
private double parseFactor() {
// Xử lý các toán tử một ngôi (+,-,√) trước
if (eat('+')) return parseFactor();
if (eat('-')) return -parseFactor();
if (eat('√')) return Math.sqrt(parseFactor());
double x;
int startPos = this.pos;
if (eat('(')) {
x = parseExpression();
eat(')');
} else if ((ch >= '0' && ch <= '9') || ch == '.') {
while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
x = Double.parseDouble(expression.substring(startPos, this.pos));
// Xử lý % ngay sau số
if (eat('%')) {
x = x / 100.0;
}
} else {
throw new RuntimeException("Lỗi: Ký tự không hợp lệ");
}
// Xử lý toán tử mũ SAU khi có toán hạng đầu tiên
if (eat('^')) {
x = Math.pow(x, parseFactor());
}
return x;
}
}.parse();
}
}
package ll; import javax.swing.*; import java.awt.*; import java.awt.event.ActionListener; public class CalculatorView extends JFrame { private JTextField displayExpression; // Hiển thị biểu thức private JTextField displayResult; // Hiển thị kết quả private JButton[] buttons; // Mảng chứa các nút public CalculatorView() { // Thiết lập cửa sổ chính setTitle("Calculator"); setSize(300, 400); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); // Tạo panel chính với BorderLayout JPanel mainPanel = new JPanel(new BorderLayout()); // Tạo panel hiển thị JPanel displayPanel = new JPanel(new GridLayout(2, 1)); displayExpression = new JTextField(); displayExpression.setEditable(false); displayExpression.setFont(new Font("Arial", Font.PLAIN, 18)); displayExpression.setHorizontalAlignment(JTextField.RIGHT); displayResult = new JTextField(); displayResult.setEditable(false); displayResult.setFont(new Font("Arial", Font.BOLD, 24)); displayResult.setHorizontalAlignment(JTextField.RIGHT); displayPanel.add(displayExpression); displayPanel.add(displayResult); // Tạo panel bàn phím JPanel buttonPanel = new JPanel(new GridLayout(6, 4, 5, 5)); // Thêm hàng cho nút "C" // Các nút số và phép toán String[] buttonTexts = { "√", "^", "%", "C", "H", "(", ")", "←", "7", "8", "9", "/", "4", "5", "6", "*", "1", "2", "3", "-", "0", ".", "=", "+" }; buttons = new JButton[buttonTexts.length]; // Khởi tạo mảng nút for (int i = 0; i < buttonTexts.length; i++) { buttons[i] = new JButton(buttonTexts[i]); buttons[i].setFont(new Font("Arial", Font.BOLD, 18)); buttonPanel.add(buttons[i]); // Thêm nút vào giao diện } // Thêm các panel vào cửa sổ chính mainPanel.add(displayPanel, BorderLayout.NORTH); mainPanel.add(buttonPanel, BorderLayout.CENTER); add(mainPanel); } // Getter public JTextField getDisplayExpression() { return displayExpression; } public JTextField getDisplayResult() { return displayResult; } // Thêm ActionListener cho tất cả các nút public void addButtonListener(ActionListener listener) { for (JButton button : buttons) { button.addActionListener(listener); } } }
package ll;
import javax.swing.SwingUtilities;
public class CalculatorApp {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
CalculatorModel model = new CalculatorModel();
CalculatorView view = new CalculatorView();
new CalculatorController(model, view);
view.setVisible(true);
});
}
}
