Skip to content
20 changes: 12 additions & 8 deletions src/Calc/App.java
Original file line number Diff line number Diff line change
@@ -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);
});
}
}

218 changes: 181 additions & 37 deletions src/Calc/Calculator.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> 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<String> 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,
Expand Down Expand Up @@ -61,7 +191,7 @@ public void mouseExited(MouseEvent e) {
}
});
}
}
}

public void clear() {
this.currentOperand = "";
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
34 changes: 34 additions & 0 deletions src/Calc/CalculatorFacade.java
Original file line number Diff line number Diff line change
@@ -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<String> getHistory() {
return Calculator.HistoryOperation.getHistory();
}
}