diff --git a/src/CalculatorGUI.java b/src/CalculatorGUI.java new file mode 100644 index 0000000..e2c1529 --- /dev/null +++ b/src/CalculatorGUI.java @@ -0,0 +1,205 @@ +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; + +public class CalculatorGUI extends JFrame implements ActionListener { + private JTextArea displayArea; + private JTextField inputField; + private ArrayList history; + private JTextArea historyArea; + + public CalculatorGUI() { + history = new ArrayList<>(); + + // Set up the frame + setTitle("Calculator"); + setSize(400, 500); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setLayout(new BorderLayout()); + + // Display area + JPanel displayPanel = new JPanel(new GridLayout(1, 2)); + inputField = new JTextField(); + inputField.setEditable(false); + displayPanel.add(inputField); + historyArea = new JTextArea(); + JScrollPane scrollPane = new JScrollPane(historyArea); + displayPanel.add(scrollPane); + add(displayPanel, BorderLayout.NORTH); + + // Buttons + JPanel buttonPanel = new JPanel(new GridLayout(4, 4)); + String[] buttonLabels = {"7", "8", "9", "/", + "4", "5", "6", "*", + "1", "2", "3", "-", + "C", "0", "=", "+"}; + for (String label : buttonLabels) { + JButton button = new JButton(label); + button.addActionListener(this); + buttonPanel.add(button); + } + add(buttonPanel, BorderLayout.CENTER); + + // Save, Copy, Clear buttons + JPanel controlPanel = new JPanel(new FlowLayout()); + JButton saveButton = new JButton("Save"); + saveButton.addActionListener(new SaveListener()); + JButton copyButton = new JButton("Copy"); + copyButton.addActionListener(new CopyListener()); + JButton clearButton = new JButton("Clear"); + clearButton.addActionListener(new ClearListener()); + controlPanel.add(saveButton); + controlPanel.add(copyButton); + controlPanel.add(clearButton); + add(controlPanel, BorderLayout.SOUTH); + + setVisible(true); + } + + @Override + public void actionPerformed(ActionEvent e) { + String command = e.getActionCommand(); + switch (command) { + case "C": + inputField.setText(""); + break; + case "=": + calculate(); + break; + default: + inputField.setText(inputField.getText() + command); + } + } + + private void calculate() { + String expression = inputField.getText(); + try { + String result = String.valueOf(eval(expression)); + history.add(expression + " = " + result); + displayHistory(); + inputField.setText(result); + } catch (NumberFormatException | ArithmeticException e) { + inputField.setText("Error"); + } + } + + private double eval(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("Unexpected: " + (char) ch); + return x; + } + + double parseExpression() { + double x = parseTerm(); + for (; ; ) { + if (eat('+')) x += parseTerm(); // Addition + else if (eat('-')) x -= parseTerm(); // Subtraction + else return x; + } + } + + double parseTerm() { + double x = parseFactor(); + for (; ; ) { + if (eat('*')) x *= parseFactor(); // Multiplication + else if (eat('/')) x /= parseFactor(); // Division + else return x; + } + } + + double parseFactor() { + if (eat('+')) return parseFactor(); // Unary plus + if (eat('-')) return -parseFactor(); // Unary minus + + double x; + int startPos = this.pos; + if (eat('(')) { // Parentheses + x = parseExpression(); + eat(')'); + } else if ((ch >= '0' && ch <= '9') || ch == '.') { // Numbers + while ((ch >= '0' && ch <= '9') || ch == '.') nextChar(); + x = Double.parseDouble(expression.substring(startPos, this.pos)); + } else { + throw new RuntimeException("Unexpected: " + (char) ch); + } + + return x; + } + }.parse(); + } + + private void displayHistory() { + StringBuilder sb = new StringBuilder(); + for (String entry : history) { + sb.append(entry).append("\n"); + } + historyArea.setText(sb.toString()); + } + + private class SaveListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + try { + File file = new File("calculator_history.txt"); + FileWriter writer = new FileWriter(file); + for (String entry : history) { + writer.write(entry + "\n"); + } + writer.close(); + JOptionPane.showMessageDialog(CalculatorGUI.this, "History saved successfully"); + } catch (IOException ex) { + ex.printStackTrace(); + JOptionPane.showMessageDialog(CalculatorGUI.this, "Error saving history"); + } + } + } + + private class CopyListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + String selectedText = historyArea.getSelectedText(); + if (selectedText != null) { + StringSelection selection = new StringSelection(selectedText); + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(selection, null); + } + } + } + + private class ClearListener implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + history.clear(); + historyArea.setText(""); + } + } + + public static void main(String[] args) { + new CalculatorGUI(); + } +} diff --git a/src/c1.java b/src/c1.java deleted file mode 100644 index 167d3a4..0000000 --- a/src/c1.java +++ /dev/null @@ -1,167 +0,0 @@ -import javax.swing.*; -import java.awt.*; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; -import java.awt.event.*; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -public class C1 extends JFrame implements ActionListener { - private JTextField displayField; - private JTextArea historyArea; - private List historyList; - - private double num1, num2; - private String operator; - - public C1() { - super("Calculator"); - - historyList = new ArrayList<>(); - - // 设置布局 - setLayout(new BorderLayout()); - - // 显示区域 - JPanel displayPanel = new JPanel(new GridLayout(1, 2)); - displayField = new JTextField(); - displayField.setEditable(false); - historyArea = new JTextArea(); - historyArea.setEditable(false); - JScrollPane historyScrollPane = new JScrollPane(historyArea); - - displayPanel.add(displayField); - displayPanel.add(historyScrollPane); - - add(displayPanel, BorderLayout.NORTH); - - // 按钮区域 - JPanel buttonPanel = new JPanel(new GridLayout(4, 4)); - String[] buttonLabels = { - "7", "8", "9", "/", - "4", "5", "6", "*", - "1", "2", "3", "-", - "0", ".", "=", "+" - }; - - for (String label : buttonLabels) { - JButton button = new JButton(label); - button.addActionListener(this); - buttonPanel.add(button); - } - - JButton saveButton = new JButton("保存"); - saveButton.addActionListener(this); - JButton copyButton = new JButton("复制"); - copyButton.addActionListener(this); - JButton clearButton = new JButton("清除"); - clearButton.addActionListener(this); - - buttonPanel.add(saveButton); - buttonPanel.add(copyButton); - buttonPanel.add(clearButton); - - add(buttonPanel, BorderLayout.CENTER); - - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setSize(300, 400); - setVisible(true); - } - - @Override - public void actionPerformed(ActionEvent e) { - String command = e.getActionCommand(); - - if (command.equals("保存")) { - saveHistoryToFile(); - } else if (command.equals("复制")) { - copyToClipboard(); - } else if (command.equals("清除")) { - clearHistory(); - } else if (Character.isDigit(command.charAt(0)) || command.equals(".")) { - displayField.setText(displayField.getText() + command); - } else if (command.equals("=")) { - calculate(); - } else { - // 运算符 - num1 = Double.parseDouble(displayField.getText()); - operator = command; - displayField.setText(""); - } - } - - private void calculate() { - num2 = Double.parseDouble(displayField.getText()); - double result = 0; - - switch (operator) { - case "+": - result = num1 + num2; - break; - case "-": - result = num1 - num2; - break; - case "*": - result = num1 * num2; - break; - case "/": - if (num2 != 0) { - result = num1 / num2; - } else { - displayField.setText("Error"); - return; - } - break; - } - - displayField.setText(Double.toString(result)); - - String historyEntry = num1 + " " + operator + " " + num2 + " = " + result; - historyList.add(historyEntry); - updateHistoryArea(); - } - - private void updateHistoryArea() { - historyArea.setText(""); - for (String entry : historyList) { - historyArea.append(entry + "\n"); - } - } - - private void saveHistoryToFile() { - JFileChooser fileChooser = new JFileChooser(); - int result = fileChooser.showSaveDialog(this); - if (result == JFileChooser.APPROVE_OPTION) { - File file = fileChooser.getSelectedFile(); - try (FileWriter writer = new FileWriter(file)) { - for (String entry : historyList) { - writer.write(entry + "\n"); - } - writer.flush(); - JOptionPane.showMessageDialog(this, "保存成功"); - } catch (IOException e) { - JOptionPane.showMessageDialog(this, "保存失败: " + e.getMessage()); - } - } - } - - private void copyToClipboard() { - String selectedText = historyArea.getSelectedText(); - if (selectedText != null && !selectedText.isEmpty()) { - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - clipboard.setContents(new StringSelection(selectedText), null); - } - } - - private void clearHistory() { - historyList.clear(); - updateHistoryArea(); - } - - public static void main(String[] args) { - SwingUtilities.invokeLater(() -> new C1()); - } -}