JavaFXطريقة إنشاء آلة حاسبة
في هذا الدرس ستتعلم طريقة إنشاء آلة حاسبة بسيطة بإستخدام JavaFX.
خيارات التحميل
⇓ تحميل البرنامج ⇓ تحميل المشروع كاملاً
كود البرنامج
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);
}
}
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);
}
}