diff --git a/src/Calc/App.java b/src/Calc/App.java index 4101058..a2cd664 100644 --- a/src/Calc/App.java +++ b/src/Calc/App.java @@ -1,14 +1,18 @@ package Calc; -/** - * - * @author youcefhmd - */ - public class App { - public static void main(String[] args) { - new Calculator().setVisible(true); - } + javax.swing.SwingUtilities.invokeLater(() -> { + + CalculatorFacade calcFacade = new CalculatorFacade(); + // بدل ما نستدعي Calculator مباشرة: + calcFacade.showCalculator(); + + // مثال تشغيل: + float result = calcFacade.performOperation("+", 5, 3); + System.out.println("Result = " + result); + }); + } } + diff --git a/src/Calc/Calculator.java b/src/Calc/Calculator.java index 7e2a37c..c2cdc17 100644 --- a/src/Calc/Calculator.java +++ b/src/Calc/Calculator.java @@ -13,16 +13,146 @@ public final class Calculator extends javax.swing.JFrame { private String currentOperand; private String previousOperand; private String operation; - private int x, y; + + // --- Singleton Method --- + private static Calculator INSTANCE; - public Calculator() { - initComponents(); - getContentPane().setSize(400, 700); - this.clear(); - this.addEvents(); + public static Calculator getInstance() { + if (INSTANCE == null) { + INSTANCE = new Calculator(); + } + return INSTANCE; + } + + // --- Factory Method --- + public interface Operation { + float apply(float a, float b); + } + + + + + + + // --- Decorator Pattern (History) --- + +// 1) Abstract Decorator +private abstract static class OperationDecorator implements Operation { + protected Operation decoratedOperation; + + public OperationDecorator(Operation decoratedOperation) { + this.decoratedOperation = decoratedOperation; + } + + @Override + public float apply(float a, float b) { + return decoratedOperation.apply(a, b); + } +} + +// 2) Concrete Decorator - History +public static class HistoryOperation extends OperationDecorator { + + private static final java.util.List history = new java.util.ArrayList<>(); + + public HistoryOperation(Operation decoratedOperation) { + super(decoratedOperation); + } + + @Override + public float apply(float a, float b) { + float result = super.apply(a, b); + history.add(a + " " + getSymbol(decoratedOperation) + " " + b + " = " + result); + return result; } +private String getSymbol(Operation op) { + if (op instanceof AddOperation) return "+"; + if (op instanceof SubOperation) return "-"; + if (op instanceof MultOperation) return "*"; + if (op instanceof DivOperation) return "/"; + return "?"; +} + + public static java.util.List getHistory() { + return history; + } +} + + + +// concrete Decorator – Logging +private static class LoggingOperation extends OperationDecorator { + + public LoggingOperation(Operation decoratedOperation) { + super(decoratedOperation); + } + + @Override + public float apply(float a, float b) { + float result = super.apply(a, b); + System.out.println("[LOG] " + a + " " + getSymbol(decoratedOperation) + " " + b + " = " + result); + return result; + } + + private String getSymbol(Operation op) { + if (op instanceof AddOperation) return "+"; + if (op instanceof SubOperation) return "-"; + if (op instanceof MultOperation) return "*"; + if (op instanceof DivOperation) return "/"; + return "?"; + } +} + + + + private static class AddOperation implements Operation { + @Override + public float apply(float a,float b){ + return a+b;} +} + + private static class SubOperation implements Operation { + @Override + public float apply(float a,float b){ + return a-b;} + } + + private static class MultOperation implements Operation { + @Override + public float apply(float a,float b){ + return a*b;} + } + + private static class DivOperation implements Operation { + @Override + public float apply(float a,float b){ + if (b == 0f) { + throw new ArithmeticException("Error! Division by zero is not accepted"); + } + return a/b;} + } + + public static class OperationFactory { + static Operation getOperation(String op) { + switch (op) { + case "+": return new AddOperation(); + case "-": return new SubOperation(); + case "×": return new MultOperation(); + case "÷": return new DivOperation(); + default: throw new IllegalArgumentException("Unknown operation: " + op); + } + } + } + +private Calculator() { + initComponents(); + getContentPane().setSize(400, 700); + this.clear(); + this.addEvents(); +} + public void addEvents() { JButton[] btns = { btn0, btn1, btn2, btn3, btn4, @@ -61,7 +191,7 @@ public void mouseExited(MouseEvent e) { } }); } - } + } public void clear() { this.currentOperand = ""; @@ -108,43 +238,40 @@ public void chooseOperation(String operation) { this.updateDisplay(); } - public void compute() { - float computation; - if (this.currentOperand.equals("") || this.previousOperand.equals("")) { - return; - } +public void compute() { + + if (this.currentOperand.equals("") || this.previousOperand.equals("")) { + return; + } + try { float curr = Float.parseFloat(this.currentOperand); float prev = Float.parseFloat(this.previousOperand); - if (Float.isNaN(curr) || Float.isNaN(prev)) { - return; - } - switch (this.operation) { - case "+" -> - computation = prev + curr; - case "-" -> - computation = prev - curr; - case "×" -> - computation = prev * curr; - case "÷" -> { - if (curr == 0) { - this.clear(); - this.currentOperand = "Error"; - return; - } - computation = prev / curr; - } - default -> { - return; - } - } + // نجيب العملية الأساسية من الفاكتوري + Operation op = OperationFactory.getOperation(this.operation); - this.currentOperand = (computation - (int) computation) != 0 ? Float.toString(computation) : Integer.toString((int) computation); - this.previousOperand = ""; - this.operation = ""; + // نغلفها بـ History + Logging (Decorator Pattern) + op = new HistoryOperation(op); + op = new LoggingOperation(op); + + float result = op.apply(prev, curr); + + this.currentOperand = (result - (int) result) != 0 + ? Float.toString(result ) + : Integer.toString((int) result ); + + } catch (IllegalArgumentException | ArithmeticException ex) { + this.clear(); + this.currentOperand = "Error"; + return; } + this.previousOperand = ""; + this.operation = ""; +} + + public void updateDisplay() { current.setText(this.currentOperand); previous.setText(previousOperand + " " + this.operation); @@ -610,6 +737,23 @@ private void btnDivActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST: private void btnEqualActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEqualActionPerformed this.compute(); this.updateDisplay(); + + + + + System.out.println("---- History ----"); +for (String h : HistoryOperation.getHistory()) { + System.out.println(h); +} + + + + + + + + + if (this.currentOperand.equals("Error")) this.currentOperand = ""; }//GEN-LAST:event_btnEqualActionPerformed diff --git a/src/Calc/CalculatorFacade.java b/src/Calc/CalculatorFacade.java new file mode 100644 index 0000000..027afd8 --- /dev/null +++ b/src/Calc/CalculatorFacade.java @@ -0,0 +1,34 @@ +package Calc; + +public class CalculatorFacade { + + private Calculator calculator; + + public CalculatorFacade() { + calculator = Calculator.getInstance(); // Singleton + } + + // تفتح واجهة الآلة الحاسبة + public void showCalculator() { + calculator.setVisible(true); + } + + // تنفّذ عملية رياضية وتُرجع الناتج + public float performOperation(String operation, float a, float b) { + Calculator.Operation op = Calculator.OperationFactory.getOperation(operation); + if (op == null) { + throw new IllegalArgumentException("Invalid operation: " + operation); + } + return op.apply(a, b); + } + + // تمسح كل شي من الشاشة (Clear) + public void clearCalculator() { + calculator.clear(); + } + + // تعرض الـ History (من Decorator) + public java.util.List getHistory() { + return Calculator.HistoryOperation.getHistory(); + } +}