JavaFX - طريقة إنشاء آلة حاسبة

JavaFX طريقة إنشاء آلة حاسبة

في هذا الدرس ستتعلم طريقة إنشاء آلة حاسبة بسيطة بإستخدام JavaFX.

In this lesson, you will learn how to create a Scientific Calculator using JavaFX.



خيارات التحميل

⇓ تحميل البرنامج ⇓ تحميل المشروع كاملاً


كود إنشاء آلة حاسبة بسيطة بإستخدام JavaFX.

Main.java
import java.text.DecimalFormat;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;

public class Main extends Application {

    // هنا قمنا بتعريف جميع الأشياء التي سنضعها في النافذة
    Button b1, b2, b3, b4, b5, b6, b7, b8, b9, b0, comma, plus, equal, minus, divide, multiple, clear, back;
    TextField textField;
    Label oldValueLabel, operandLabel;

    // لتخزين العدد الذي تم إدخاله قبل النقر على زر الجمع, الطرح, الضرب أو القسمة num سنستخدم المتغير
    double num;

    // لتخزين الناتج النهائي عند النقر على زر المساواة answer سنستخدم المتغير
    double answer;

    // ÷ × - + لتخزين ناتج جميع العمليات السابقة في كل مرة يتم فيها النقر على الأزرار oldAnswer سنستخدم المتغير
    double oldAnswer;

    // لتخزين رقم عادي يمثل نوع العملية التي سيتم إجراءها operation سنستخدم المتغير
    int operation;

    // لمعرفة إذا تم تغيير الرقم الظاهر في مربع النص أم لا isTextChanged سنستخدم المتغير
    boolean isTextChanged = false;

    // لمعرفة إذا تم النقر على أحد هذه الأزرار ÷ × - + أم لا noClickedOperator سنستخدم المتغير
    boolean noClickedOperator = true;

    // لمعرفة إذا تم النقر على الزر = أم لا isEqualClicked سنستخدم المتغير
    boolean isEqualClicked = false;

    // لإخفاء الأصفار التي لا حاجة إلى ظهورها format سنستخدم الكائن
    DecimalFormat format = new DecimalFormat("0.###############");

    // لتحديد نوع خط و حجم الأشياء التي سنضيفها في النافذة font سنستخدم الكائن
    Font font = Font.font("Calibri", FontWeight.NORMAL, 20);

    // ÷ × - + سنستخدم هذه الدالة لتخزين ناتج جميع العمليات السابقة في كل مرة يتم فيها النقر على الأزرار
    private void calculateOldAnswer() {
        switch (operation) {
            case 1:
                oldAnswer += num;
                break;
            case 2:
                if (!oldValueLabel.getText().isEmpty()) {
                    oldAnswer -= num;
                } else {
                    oldAnswer = num - oldAnswer;
                }
                break;
            case 3:
                oldAnswer *= num;
                break;
            case 4:
                oldAnswer /= num;
                break;
        }
    }


    @Override
    public void start(Stage stage) {

        // هنا قمنا بإنشاء جميع الأشياء التي سنضعها في النافذة
        b0 = new Button("0");
        b1 = new Button("1");
        b2 = new Button("2");
        b3 = new Button("3");
        b4 = new Button("4");
        b5 = new Button("5");
        b6 = new Button("6");
        b7 = new Button("7");
        b8 = new Button("8");
        b9 = new Button("9");
        comma = new Button(".");
        plus = new Button("+");
        minus = new Button("-");
        multiple = new Button("×");
        divide = new Button("÷");
        equal = new Button("=");
        clear = new Button("C");
        back = new Button("←");
        textField = new TextField("0");
        oldValueLabel = new Label("");
        operandLabel = new Label("");

		// يظهر ناحية اليمين textField و operandLabel ,oldValueLabel هنا قمنا بجعل نص الكائنات
		oldValueLabel.setAlignment(Pos.CENTER_RIGHT);
        operandLabel.setAlignment(Pos.CENTER_RIGHT);
        textField.setAlignment(Pos.CENTER_RIGHT);

		// بشكل يدوي textField هنا قمنا بجعل المستخدم غير قادر على تعديل نص الكائن
		textField.setEditable(false);

        // هنا قمنا بتحديد حجم و موقع كل شيء أضفناه في النافذة
        oldValueLabel.setPrefSize(214, 20);
        oldValueLabel.setTranslateX(11);
        oldValueLabel.setTranslateY(5);
        operandLabel.setPrefSize(15, 20);
        operandLabel.setTranslateX(225);
        operandLabel.setTranslateY(5);
        textField.setPrefSize(234, 47);
        textField.setTranslateX(11);
        textField.setTranslateY(25);
        b7.setPrefSize(45, 42);
        b7.setTranslateX(10);
        b7.setTranslateY(80);
        b8.setPrefSize(45, 42);
        b8.setTranslateX(58);
        b8.setTranslateY(80);
        b9.setPrefSize(45, 42);
        b9.setTranslateX(106);
        b9.setTranslateY(80);
        plus.setPrefSize(45, 42);
        plus.setTranslateX(154);
        plus.setTranslateY(80);
        clear.setPrefSize(45, 42);
        clear.setTranslateX(202);
        clear.setTranslateY(80);
        b4.setPrefSize(45, 42);
        b4.setTranslateX(10);
        b4.setTranslateY(126);
        b5.setPrefSize(45, 42);
        b5.setTranslateX(58);
        b5.setTranslateY(126);
        b6.setPrefSize(45, 42);
        b6.setTranslateX(106);
        b6.setTranslateY(126);
        minus.setPrefSize(45, 42);
        minus.setTranslateX(154);
        minus.setTranslateY(126);
        back.setPrefSize(45, 42);
        back.setTranslateX(202);
        back.setTranslateY(126);
        b1.setPrefSize(45, 42);
        b1.setTranslateX(10);
        b1.setTranslateY(172);
        b2.setPrefSize(45, 42);
        b2.setTranslateX(58);
        b2.setTranslateY(172);
        b3.setPrefSize(45, 42);
        b3.setTranslateX(106);
        b3.setTranslateY(172);
        multiple.setPrefSize(45, 42);
        multiple.setTranslateX(154);
        multiple.setTranslateY(172);
        equal.setPrefSize(45, 88);
        equal.setTranslateX(202);
        equal.setTranslateY(172);
        b0.setPrefSize(93, 42);
        b0.setTranslateX(10);
        b0.setTranslateY(218);
        comma.setPrefSize(45, 42);
        comma.setTranslateX(106);
        comma.setTranslateY(218);
        divide.setPrefSize(45, 42);
        divide.setTranslateX(154);
        divide.setTranslateY(218);

        // هنا قمنا بتحديد حجم و نوع خط كل شيء أضفناه في النافذة
        b0.setFont(font);
        b1.setFont(font);
        b2.setFont(font);
        b3.setFont(font);
        b4.setFont(font);
        b5.setFont(font);
        b6.setFont(font);
        b7.setFont(font);
        b8.setFont(font);
        b9.setFont(font);
        comma.setFont(font);
        equal.setFont(font);
        plus.setFont(font);
        minus.setFont(font);
        multiple.setFont(font);
        divide.setFont(font);
        clear.setFont(font);
        textField.setFont(Font.font("Monospaced", FontWeight.BOLD, 19));
        oldValueLabel.setFont(Font.font("Monospaced", FontWeight.BOLD, 17));
        operandLabel.setFont(Font.font("Monospaced", FontWeight.BOLD, 17));
        back.setFont(Font.font("Tahoma", FontWeight.BOLD, 18));

        // هنا قمنا بتحديد لون خط و خلفية كل شيء سنضيفه في النافذة
        oldValueLabel.setStyle("-fx-text-fill: cyan;");
        operandLabel.setStyle("-fx-text-fill: yellow;");
        b0.setStyle("-fx-text-fill: white; -fx-background-color: dimgray;");
        b1.setStyle("-fx-text-fill: white; -fx-background-color: dimgray;");
        b2.setStyle("-fx-text-fill: white; -fx-background-color: dimgray;");
        b3.setStyle("-fx-text-fill: white; -fx-background-color: dimgray;");
        b4.setStyle("-fx-text-fill: white; -fx-background-color: dimgray;");
        b5.setStyle("-fx-text-fill: white; -fx-background-color: dimgray;");
        b6.setStyle("-fx-text-fill: white; -fx-background-color: dimgray;");
        b7.setStyle("-fx-text-fill: white; -fx-background-color: dimgray;");
        b8.setStyle("-fx-text-fill: white; -fx-background-color: dimgray;");
        b9.setStyle("-fx-text-fill: white; -fx-background-color: dimgray;");
        comma.setStyle("-fx-text-fill: white; -fx-background-color: dimgray;");
        plus.setStyle("-fx-text-fill: white; -fx-background-color: darkslategray;");
        minus.setStyle("-fx-text-fill: white; -fx-background-color: darkslategray;");
        multiple.setStyle("-fx-text-fill: white; -fx-background-color: darkslategray;");
        divide.setStyle("-fx-text-fill: white; -fx-background-color: darkslategray;");
        equal.setStyle("-fx-text-fill: white; -fx-background-color: darkslategray;");
        clear.setStyle("-fx-text-fill: white; -fx-background-color: #E50101;");
        back.setStyle("-fx-text-fill: white; -fx-background-color: orangered;");

        // يمثل ما يحدث عند النقر بواسطة الفأرة على أي زر موضوع في البرنامج EventHandler هنا قمنا بتعريف كائن من الإنترفيس
        EventHandler eventHandler = (new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent e) {
                // عند النقر على الزر 0 سيتم إضافة 0 في مربع النص مع التأكد من عدم وجود أي صفر لا فائدة له من الناحية اليسرى
                if (e.getSource() == b0)
				{
                    if (isEqualClicked == true || textField.getText().equals("0"))
                        textField.setText("0");
                    else
                        textField.setText(textField.getText() + "0");

                    isEqualClicked = false;
                    isTextChanged = true;
                    noClickedOperator = true;
                }
				// عند النقر على الزر 1 سيتم إضافة 1 في مربع النص مع التأكد من عدم وجود أي صفر لا فائدة له من الناحية اليسرى
                else if (e.getSource() == b1)
				{
                    if (isEqualClicked == true || textField.getText().equals("0"))
                        textField.setText("1");
                    else
                        textField.setText(textField.getText() + "1");

                    isEqualClicked = false;
                    isTextChanged = true;
                    noClickedOperator = true;
                }
				// عند النقر على الزر 2 سيتم إضافة 2 في مربع النص مع التأكد من عدم وجود أي صفر لا فائدة له من الناحية اليسرى
                else if (e.getSource() == b2)
				{
                    if (isEqualClicked == true || textField.getText().equals("0"))
                        textField.setText("2");
                    else
                        textField.setText(textField.getText() + "2");

                    isEqualClicked = false;
                    isTextChanged = true;
                    noClickedOperator = true;
                }
				// عند النقر على الزر 3 سيتم إضافة 3 في مربع النص مع التأكد من عدم وجود أي صفر لا فائدة له من الناحية اليسرى
                else if (e.getSource() == b3)
				{
                    if (isEqualClicked == true || textField.getText().equals("0"))
                        textField.setText("3");
                    else
                        textField.setText(textField.getText() + "3");

                    isEqualClicked = false;
                    isTextChanged = true;
                    noClickedOperator = true;
                }
				// عند النقر على الزر 4 سيتم إضافة 4 في مربع النص مع التأكد من عدم وجود أي صفر لا فائدة له من الناحية اليسرى
                else if (e.getSource() == b4)
				{
                    if (isEqualClicked == true || textField.getText().equals("0"))
                        textField.setText("4");
                    else
                        textField.setText(textField.getText() + "4");

                    isEqualClicked = false;
                    isTextChanged = true;
                    noClickedOperator = true;
                }
				// عند النقر على الزر 5 سيتم إضافة 5 في مربع النص مع التأكد من عدم وجود أي صفر لا فائدة له من الناحية اليسرى
                else if (e.getSource() == b5)
				{
                    if (isEqualClicked == true || textField.getText().equals("0"))
                        textField.setText("5");
                    else
                        textField.setText(textField.getText() + "5");

                    isEqualClicked = false;
                    isTextChanged = true;
                    noClickedOperator = true;
                }
				// عند النقر على الزر 6 سيتم إضافة 6 في مربع النص مع التأكد من عدم وجود أي صفر لا فائدة له من الناحية اليسرى
                else if (e.getSource() == b6)
				{
                    if (isEqualClicked == true || textField.getText().equals("0"))
                        textField.setText("6");
                    else
                        textField.setText(textField.getText() + "6");

                    isEqualClicked = false;
                    isTextChanged = true;
                    noClickedOperator = true;
                }
				// عند النقر على الزر 7 سيتم إضافة 7 في مربع النص مع التأكد من عدم وجود أي صفر لا فائدة له من الناحية اليسرى
                else if (e.getSource() == b7)
				{
                    if (isEqualClicked == true || textField.getText().equals("0"))
                        textField.setText("7");
                    else
                        textField.setText(textField.getText() + "7");

                    isEqualClicked = false;
                    isTextChanged = true;
                    noClickedOperator = true;
                }
				// عند النقر على الزر 8 سيتم إضافة 8 في مربع النص مع التأكد من عدم وجود أي صفر لا فائدة له من الناحية اليسرى
                else if (e.getSource() == b8)
				{
                    if (isEqualClicked == true || textField.getText().equals("0"))
                        textField.setText("8");
                    else
                        textField.setText(textField.getText() + "8");

                    isEqualClicked = false;
                    isTextChanged = true;
                    noClickedOperator = true;
                }
				// عند النقر على الزر 9 سيتم إضافة 9 في مربع النص مع التأكد من عدم وجود أي صفر لا فائدة له من الناحية اليسرى
                else if (e.getSource() == b9)
				{
                    if (isEqualClicked == true || textField.getText().equals("0"))
                        textField.setText("9");
                    else
                        textField.setText(textField.getText() + "9");

                    isEqualClicked = false;
                    isTextChanged = true;
                    noClickedOperator = true;
                }
				// سيتم إضافة نقطة (أي فاصلة) عند النقر على زر النقطة في حال لم يكن هناك نقطة أصلاً
                else if (e.getSource() == comma)
				{
                    if (isEqualClicked == true || textField.getText().isEmpty())
                        textField.setText("0.");
                    else if (!textField.getText().contains("."))
                        textField.setText(textField.getText() + ".");

                    isEqualClicked = false;
                    isTextChanged = true;
                }
				// للإشارة إلى أنه يوجد عملية جمع operation و وضع القيمة 1 للمتغير num عند النقر على الزر + سيتم تخزين القيمة المدخلة في المتغير
                else if (e.getSource() == plus && noClickedOperator == true)
				{
                    // قبل أي شيء سيتم التأكد من أنه لا يوجد عملية قسمة سابقة لأي رقم على صفر, و إن وجدت سيتم عرض النص التالي في مربع النص
                    if (textField.getText().equals("0") && operandLabel.getText().equals("÷"))
					{
                        textField.setText("cannot divide by 0");
                    }
					// إذا كان هناك أي قيمة مدخلة في مربع النص أو كان هناك ناتج معروض لعملية سابقة فوق مربع النص سيتم تنفيذ التالي
                    else if (isTextChanged == true || oldValueLabel.getText().isEmpty())
					{
                        try {
                            // إذا لم يكن هناك قيمة مدخلة حالياً في مربع النص num سيتم وضع 0 في المتغير
                            if (textField.getText().isEmpty()) {
                                num = 0;
                            }
							// num إذا لم يكن مربع النص فارغاً سيتم وضع الرقم المدخل فيه في المتغير
                            else {
                                num = Double.parseDouble(textField.getText());
                            }

                            // حتى لا يؤثر على عملية الجمع oldAnswer إذا لم يكن هناك أي ناتج ظاهر لعملية سابقة فوق مربع النص, سيتم وضع 0 في المتغير
                            if (oldValueLabel.getText().isEmpty()) {
                                operation = 1;
                                oldAnswer = 0;
                            }
							// oldAnswer إذا كان يوجد ناتج ظاهر لعملية سابقة فوق مربع النص, سيتم تخزينه في المتغير
                            else {
                                oldAnswer = Double.parseDouble(oldValueLabel.getText());
                            }

                            // و مسح النص الذي كان موجوداً في مربع النص oldValueLabel بعدها سيتم وضع ناتج العملية السابقة كنص للكائن
                            calculateOldAnswer();
                            operandLabel.setText("+");
                            oldValueLabel.setText(format.format(oldAnswer));
                            textField.setText("");

                            // calculateOldAnswer() للإشارة إلى أنه يجب جمع القيم المدخلة عند أول إستدعاء للدالة operation بعدها سيتم وضع 1 في المتغير
                            operation = 1;
                        }
						catch (Exception ex) {
                            textField.setText("Error");
                        }
                    }
                    // في الأخير سيتم الإشارة إلى أنه تم النقر على إحدى الأزرار ÷ × - + و أن القيمة المدخلة في مربع النص قد تغيرت
                    isTextChanged = false;
                    noClickedOperator = false;
                }
				// للإشارة إلى أنه يوجد عملية طرح operation و وضع القيمة 2 للمتغير num عند النقر على الزر - سيتم تخزين القيمة المدخلة في المتغير
                else if (e.getSource() == minus && noClickedOperator == true)
				{
                    // قبل أي شيء سيتم التأكد من أنه لا يوجد عملية قسمة سابقة لأي رقم على صفر, و إن وجدت سيتم عرض النص التالي في مربع النص
                    if (textField.getText().equals("0") && operandLabel.getText().equals("÷"))
					{
                        textField.setText("cannot divide by 0");
                    }
					// إذا كان هناك أي قيمة مدخلة في مربع النص أو كان هناك ناتج معروض لعملية سابقة فوق مربع النص سيتم تنفيذ التالي
                    else if (isTextChanged == true || oldValueLabel.getText().isEmpty())
					{
                        try {
                            // إذا لم يكن هناك قيمة مدخلة حالياً في مربع النص num سيتم وضع 0 في المتغير
                            if (textField.getText().isEmpty()) {
                                num = 0;
                            }
							// num إذا لم يكن مربع النص فارغاً سيتم وضع الرقم المدخل فيه في المتغير
                            else {
                                num = Double.parseDouble(textField.getText());
                            }

                            // حتى لا يؤثر على عملية الطرح oldAnswer إذا لم يكن هناك أي ناتج ظاهر لعملية سابقة فوق مربع النص, سيتم وضع 0 في المتغير
                            if (oldValueLabel.getText().isEmpty()) {
                                operation = 2;
                                oldAnswer = 0;
                            }
							// oldAnswer إذا كان يوجد ناتج ظاهر لعملية سابقة فوق مربع النص, سيتم تخزينه في المتغير
                            else {
                                oldAnswer = Double.parseDouble(oldValueLabel.getText());
                            }

                            // و مسح النص الذي كان موجوداً في مربع النص oldValueLabel بعدها سيتم وضع ناتج العملية السابقة كنص للكائن
                            calculateOldAnswer();
                            operandLabel.setText("-");
                            oldValueLabel.setText(format.format(oldAnswer));
                            textField.setText("");

                            // calculateOldAnswer() للإشارة إلى أنه يجب طرح القيم المدخلة عند أول إستدعاء للدالة operation بعدها سيتم وضع 2 في المتغير
                            operation = 2;
                        }
						catch (Exception ex) {
                            textField.setText("Error");
                        }
                    }
                    // في الأخير سيتم الإشارة إلى أنه تم النقر على إحدى الأزرار ÷ × - + و أن القيمة المدخلة في مربع النص قد تغيرت
                    isTextChanged = false;
                    noClickedOperator = false;
                }
				// للإشارة إلى أنه يوجد عملية ضرب operation و وضع القيمة 3 للمتغير num عند النقر على الزر × سيتم تخزين القيمة المدخلة في المتغير
                else if (e.getSource() == multiple && noClickedOperator == true)
				{
                    // قبل أي شيء سيتم التأكد من أنه لا يوجد عملية قسمة سابقة لأي رقم على صفر, و إن وجدت سيتم عرض النص التالي في مربع النص
                    if (textField.getText().equals("0") && operandLabel.getText().equals("÷"))
					{
                        textField.setText("cannot divide by 0");
                    }
					// إذا كان هناك أي قيمة مدخلة في مربع النص أو كان هناك ناتج معروض لعملية سابقة فوق مربع النص سيتم تنفيذ التالي
                    else if (isTextChanged == true || oldValueLabel.getText().isEmpty())
					{
                        try {
                            // إذا لم يكن هناك قيمة مدخلة حالياً في مربع النص num سيتم وضع 1 في المتغير
                            if (textField.getText().isEmpty()) {
                                num = 1;
                            }
							// num إذا لم يكن مربع النص فارغاً سيتم وضع الرقم المدخل فيه في المتغير
                            else {
                                num = Double.parseDouble(textField.getText());
                            }

                            // حتى لا يؤثر على عملية الضرب oldAnswer إذا لم يكن هناك أي ناتج ظاهر لعملية سابقة فوق مربع النص, سيتم وضع 1 في المتغير
                            if (oldValueLabel.getText().isEmpty()) {
                                operation = 3;
                                oldAnswer = 1;
                            }
							// oldAnswer إذا كان يوجد ناتج ظاهر لعملية سابقة فوق مربع النص, سيتم تخزينه في المتغير
                            else {
                                oldAnswer = Double.parseDouble(oldValueLabel.getText());
                            }

                            // و مسح النص الذي كان موجوداً في مربع النص oldValueLabel بعدها سيتم وضع ناتج العملية السابقة كنص للكائن
                            calculateOldAnswer();
                            operandLabel.setText("×");
                            oldValueLabel.setText(format.format(oldAnswer));
                            textField.setText("");

                            // calculateOldAnswer() للإشارة إلى أنه يجب ضرب القيم المدخلة عند أول إستدعاء للدالة operation بعدها سيتم وضع 3 في المتغير
                            operation = 3;
                        }
						catch (Exception ex) {
                            textField.setText("Error");
                        }
                    }
                    // في الأخير سيتم الإشارة إلى أنه تم النقر على إحدى الأزرار ÷ × - + و أن القيمة المدخلة في مربع النص قد تغيرت
                    isTextChanged = false;
                    noClickedOperator = false;
                }
				// للإشارة إلى أنه يوجد عملية قسمة operation و وضع القيمة 4 للمتغير num عند النقر على الزر ÷ سيتم تخزين القيمة المدخلة في المتغير
                else if (e.getSource() == divide && noClickedOperator == true)
				{
                    // قبل أي شيء سيتم التأكد من أنه لا يوجد عملية قسمة سابقة لأي رقم على صفر, و إن وجدت سيتم عرض النص التالي في مربع النص
                    if (textField.getText().equals("0") && operandLabel.getText().equals("÷"))
					{
                        textField.setText("cannot divide by 0");
                    }
					// إذا كان هناك أي قيمة مدخلة في مربع النص أو كان هناك ناتج معروض لعملية سابقة فوق مربع النص سيتم تنفيذ التالي
                    else if (isTextChanged == true || oldValueLabel.getText().isEmpty())
					{
                        try {
                            // إذا لم يكن هناك قيمة مدخلة حالياً في مربع النص num سيتم وضع 1 في المتغير
                            if (textField.getText().isEmpty()) {
                                num = 1;
                            }
							// num إذا لم يكن مربع النص فارغاً سيتم وضع الرقم المدخل فيه في المتغير
                            else {
                                num = Double.parseDouble(textField.getText());
                            }

                            if (oldValueLabel.getText().isEmpty()) {
                                oldAnswer = num;
                            }
							else {
                                oldAnswer = Double.parseDouble(oldValueLabel.getText());
                                calculateOldAnswer();
                            }

                            // و مسح النص الذي كان موجوداً في مربع النص oldValueLabel بعدها سيتم وضع ناتج العملية السابقة كنص للكائن
                            operandLabel.setText("÷");
                            oldValueLabel.setText(format.format(oldAnswer));
                            textField.setText("");

                            // calculateOldAnswer() للإشارة إلى أنه يجب قسم القيم المدخلة عند أول إستدعاء للدالة operation بعدها سيتم وضع 4 في المتغير
                            operation = 4;
                        } catch (Exception ex) {
                            textField.setText("Error");
                        }
                    }
                    // في الأخير سيتم الإشارة إلى أنه تم النقر على إحدى الأزرار ÷ × - + و أن القيمة المدخلة في مربع النص قد تغيرت
                    isTextChanged = false;
                    noClickedOperator = false;
                }
				// = هنا قمنا بتحديد ما يحدث عند النقر على الزر
                else if (e.getSource() == equal)
				{
                    // إذا كان يوجد قيمة في مربع النص و قيمة سابقة ظاهرة فوقه سيتم حساب ناتجهم و عرض الناتج في مربع النص
                    if (!textField.getText().isEmpty() && !oldValueLabel.getText().isEmpty() && isEqualClicked == false)
					{
                        double a = Double.parseDouble(oldValueLabel.getText());
                        double b = Double.parseDouble(textField.getText());
                        char operand = operandLabel.getText().charAt(0);

                        switch (operand) {
                            case '+':
                                answer = a + b;
                                textField.setText(format.format(answer));
                                break;

                            case '-':
                                answer = a - b;
                                textField.setText(format.format(answer));
                                break;

                            case '×':
                                answer = a * b;
                                textField.setText(format.format(answer));
                                break;

                            case '÷':
                                if (b == 0) {
                                    textField.setText("cannot divide by 0");
                                } else {
                                    answer = a / b;
                                    textField.setText(format.format(answer));
                                }
                                break;
                        }
                    }
					// إذا لم تكن هناك قيمة في مربع النص و كانت هناك قيمة سابقة ظاهرة فوقه سيتم وضعها في مربع النص
                    else if (textField.getText().isEmpty() && !oldValueLabel.getText().isEmpty()) {
                        textField.setText(oldValueLabel.getText());
                    }

                    // في الأخير سيتم مسح قيمة العملية السابقة و العامل الموضوعين فوق مربع النص لإظهار النتيجة النهائية فقط
                    oldValueLabel.setText("");
                    operandLabel.setText("");

                    // = بالإضافة إلى الإشارة إلى أنه لم يتم النقر على إحدى الأزرار ÷ × - + و أنه تم النقر على الزر
                    isEqualClicked = true;
                    noClickedOperator = true;
                }
				// عند النقر على الزر ← سيتم مسح رقم واحد من مربع النص أو مسح أي خطأ ظاهر
                else if (e.getSource() == back)
				{
                    if (textField.getText().equals("Error") || textField.getText().equals("cannot divide by 0"))
					{
                        textField.setText("");
                    }
					else if (!textField.getText().isEmpty())
					{
                        textField.setText(textField.getText().substring(0, textField.getText().length() - 1));
                    }
                }
				// سيتم مسح كل شيء ظاهر و تصفير جميع القيم المخزنة للبدء من جديد C عند النقر على الزر
                else if (e.getSource() == clear)
				{
                    oldValueLabel.setText("");
                    textField.setText("");
                    operandLabel.setText("");
                    oldAnswer = 0;
                    num = 0;
                    noClickedOperator = true;
                }
            }
        });

        // الموجودة فيه كلما تم النقر على زر بواسطة الفأرة actionPerformed() حتى يتم إستدعاء الدالة eventHandler هنا قمنا بربط جميع الأزرار بالكائن
        b0.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        b1.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        b2.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        b3.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        b4.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        b5.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        b6.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        b7.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        b8.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        b9.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        comma.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        plus.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        multiple.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        divide.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        minus.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        equal.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        clear.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
        back.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
		
		
        // في النافذة Root Node و الذي ننوي جعله الـ Pane هنا قمنا بإنشاء كائن من الكلاس
        Pane root = new Pane();
		
		// أسود و هكذ سيظهر لون خلفية النافذة أسود root هنا قمنا بجعل لون خلفية الكائن
        root.setStyle("-fx-background-color: #222;");

        // هنا قمنا بإضافة جميع الأشياء التي قمنا بإنشائها في النافذة
        root.getChildren().add(b0);
        root.getChildren().add(b1);
        root.getChildren().add(b2);
        root.getChildren().add(b3);
        root.getChildren().add(b4);
        root.getChildren().add(b5);
        root.getChildren().add(b6);
        root.getChildren().add(b7);
        root.getChildren().add(b8);
        root.getChildren().add(b9);
        root.getChildren().add(comma);
        root.getChildren().add(equal);
        root.getChildren().add(plus);
        root.getChildren().add(multiple);
        root.getChildren().add(minus);
        root.getChildren().add(divide);
        root.getChildren().add(clear);
        root.getChildren().add(back);
        root.getChildren().add(textField);
        root.getChildren().add(oldValueLabel);
        root.getChildren().add(operandLabel);

        // فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن
        Scene scene = new Scene(root, 257, 270);
        // هنا وضعنا عنوان للنافذة
        stage.setTitle("Calculator");
        // أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ
        stage.setScene(scene);
        // هنا قمنا بإظهار النافذة
        stage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }

}
		

كورس تعلم javaFX