Learn Typing Programming Basics SQL HTML CSS JavaScript Python C++ Java JavaFX Swing Computer Fundamentals English English Conversations Problem Solving

JavaFXطريقة إنشاء برنامج لحساب الأعمار

في هذا الدرس ستتعلم طريقة إنشاء برنامجين لحساب الأعمار ( Age Calculator ) و باستخدام JavaFX.


مميزات كلا البرنامجين

  • يمكن إستخدام أي برنامج منهما لحساب عمر الشخص الحي أو المدة التي عاشها الشخص المتوفي.
  • لحساب عمر الشخص الحي, ضع فقط تاريخ ميلاده.
  • لحساب المدة التي عاشها الشخص المتوفي, ضع تاريخ ميلاده و تاريخ وفاته.


البرنامج الأول

تحميل كود برنامج حساب الأعمار في جافا

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


كود البرنامج

Main.java
import java.time.LocalDate;
import java.time.Period;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application {
// هنا قمنا بتعريف الأشياء التي سيتم وضعها في النافذة
Label birthDateLabel, resultLabel;
CheckBox deathDateCheckBox;
Button calculateAgeButton;
ComboBox dayOfBirth, monthOfBirth, yearOfBirth, dayOfDeath, monthOfDeath, yearOfDeath;
// سنستخدم هذه المتغيرات لتخزين التواريخ التي إختارها المستخدم من النافذة بشكل مؤقت
int d1, d2, m1, m2, y1, y2;
// لتخزين تاريخ وفاته endDate لتخزين تاريخ ميلاد الشخص, و الكائن startDate سنستخدم الكائن
LocalDate startDate, endDate;
// سنستخدم هذه المتغيرات لعرض الفارق النهائي بين تاريخ الميلاد و التاريخ الحالي أو تاريخ الوفاة
long daysCounter, monthsCounter, yearsCounter;
// مفعلاً أو غير مفعل (deathDatePicker) قمنا ببناء هذه الدالة لتحديد متى سيكون الكائن الذي يمثل تاريخ الوفاة
public void toggleDeathDatePicker() {
// deathDatePicker يوجد عليه علامة صح, سيتم تفعيل الكائن deathDateCheckBox إذا كان الكائن
if (deathDateCheckBox.isSelected()) {
dayOfDeath.setDisable(false);
monthOfDeath.setDisable(false);
yearOfDeath.setDisable(false);
} // deathDatePicker لا يوجد عليه علامة صح, سيتم إلغاء تفعيل الكائن deathDateCheckBox إذا كان الكائن
else {
dayOfDeath.setDisable(true);
monthOfDeath.setDisable(true);
yearOfDeath.setDisable(true);
}
}
// قمنا ببناء هذه الدالة لحساب و عرض العمر سواء كان المستخدم يريد حساب عمر شخص على قيد الحياة أو شخص ميت
public void displayAge() {
// سنستخدم هذا المتغير لتخزين نص النتيجة التي ستظهر
String text = "";
// هنا قمنا بتخزين تاريخ الميلاد الذي إختاره المستخدم في المتغيرات التالية
y1 = Integer.parseInt(yearOfBirth.getSelectionModel().getSelectedItem().toString());
m1 = monthOfBirth.getSelectionModel().getSelectedIndex() + 1;
d1 = Integer.parseInt(dayOfBirth.getSelectionModel().getSelectedItem().toString());
// إذا كان خيار تحديد تاريخ الوفاة مفعل, سيتم تخزين التاريخ المحدد في المتغيرات التالية
if (deathDateCheckBox.isSelected()) {
y2 = Integer.parseInt(yearOfDeath.getSelectionModel().getSelectedItem().toString());
m2 = monthOfDeath.getSelectionModel().getSelectedIndex() + 1;
d2 = Integer.parseInt(dayOfDeath.getSelectionModel().getSelectedItem().toString());
} // إذا كان خيار تحديد تاريخ الوفاة غير مفعل, سيتم تخزين التاريخ الحالي في المتغيرات التالية
else {
y2 = LocalDate.now().getYear();
m2 = LocalDate.now().getMonthValue();
d2 = LocalDate.now().getDayOfMonth();
}
// endDate و تاريخ الوفاة في الكائن startDate هنا قمنا بوضع تاريخ الميلاد الذي حدده المستخدم في الكائن
startDate = LocalDate.of(y1, m1, d1);
endDate = LocalDate.of(y2, m2, d2);
// هنا قمنا بتخزين الفارق بين التواريخ في المتغيرات التالية
yearsCounter = Period.between(startDate, endDate).getYears();
monthsCounter = Period.between(startDate, endDate).getMonths();
daysCounter = Period.between(startDate, endDate).getDays();
// هنا قلنا إذا كان التاريخين متواسيين سيتم إظهار التنبيه التالي
if (yearsCounter == 0 && monthsCounter == 0 && daysCounter == 0) {
resultLabel.setTextFill(Color.RED);
resultLabel.setText("Cannot compare same date!");
} // هنا قلنا أنه إذا كانت التواريخ المحددة هي منطقياً صحيحة سيتم إظهار العمر
else if (!Period.between(startDate, endDate).isNegative()) {
if (yearsCounter == 1) {
text += yearsCounter + " year ";
} else if (yearsCounter > 1) {
text += yearsCounter + " years ";
}
if (monthsCounter == 1) {
if (yearsCounter > 0 && daysCounter > 0) {
text += ", " + monthsCounter + " month ";
} else if (yearsCounter > 0 && daysCounter == 0) {
text += "and " + monthsCounter + " month ";
} else {
text += monthsCounter + " month ";
}
}
if (monthsCounter > 1) {
if (yearsCounter > 0 && daysCounter > 0) {
text += ", " + monthsCounter + " months ";
} else if (yearsCounter > 0 && daysCounter == 0) {
text += "and " + monthsCounter + " months ";
} else {
text += monthsCounter + " months ";
}
}
if (daysCounter == 1) {
if (yearsCounter == 0 && monthsCounter == 0) {
text += daysCounter + " day";
} else {
text += "and " + daysCounter + " day";
}
}
if (daysCounter > 1) {
if (yearsCounter == 0 && monthsCounter == 0) {
text += daysCounter + " days";
} else {
text += "and " + daysCounter + " days";
}
}
resultLabel.setTextFill(Color.BLACK);
resultLabel.setText(text);
} // هنا قلنا أنه إذا كانت التواريخ المحددة هي منطقياً غير مقبولة سيتم إظهار التنبيه التالي
else {
resultLabel.setTextFill(Color.RED);
resultLabel.setText("Logic order of Dates is wrong!");
}
}
@Override
public void start(Stage stage) {
// هنا وضعنا أسماء الأشهر التي سنظهرها في قائمة الأشهر
String[] months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
// هنا وضعنا أرقام الأيام التي سنظهرها في قائمة الأيام
Integer[] days = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
// currentYear هنا قمنا بتخزين رقم السنة الحالية في المتغير
int currentYear = LocalDate.now().getYear();
// هنا قمنا بإنشاء مصفوفة, عدد عناصرها يساوي رقم السنة الحالية
Integer[] years = new Integer[currentYear];
// هنا قمنا بتخزين أرقام السنين من 1 إلى رقم السنة الحالية بشكل عكسي
for (int i = 0; i < currentYear; i++)
years[currentYear-i-1] = i + 1;
// هنا قمنا بإنشاء جميع الأشياء التي سنضيفها في النافذة
birthDateLabel = new Label("Birth Date");
deathDateCheckBox = new CheckBox("Death Date");
resultLabel = new Label();
calculateAgeButton = new Button("Calculate Age");
dayOfBirth = new ComboBox(FXCollections.observableArrayList(days));
monthOfBirth = new ComboBox(FXCollections.observableArrayList(months));
yearOfBirth = new ComboBox(FXCollections.observableArrayList(years));
dayOfDeath = new ComboBox(FXCollections.observableArrayList(days));
monthOfDeath = new ComboBox(FXCollections.observableArrayList(months));
yearOfDeath = new ComboBox(FXCollections.observableArrayList(years));
// هنا قما بتعديل حجم جميع الأشياء التي سنضيفها في النافذة
birthDateLabel.setPrefSize(150, 30);
deathDateCheckBox.setPrefSize(150, 30);
dayOfBirth.setPrefSize(65, 30);
monthOfBirth.setPrefSize(65, 30);
yearOfBirth.setPrefSize(70, 30);
dayOfDeath.setPrefSize(65, 30);
monthOfDeath.setPrefSize(65, 30);
yearOfDeath.setPrefSize(70, 30);
calculateAgeButton.setPrefSize(215, 50);
resultLabel.setPrefSize(430, 30);
// هنا قمنا بتحديد مكان ظهور كل شيء سيتم إضافته في الحاوية الرئيسية التي سنضعها في النافذة
birthDateLabel.setTranslateX(174);
birthDateLabel.setTranslateY(40);
dayOfBirth.setTranslateX(110);
dayOfBirth.setTranslateY(80);
monthOfBirth.setTranslateX(182.5);
monthOfBirth.setTranslateY(80);
yearOfBirth.setTranslateX(255);
yearOfBirth.setTranslateY(80);
deathDateCheckBox.setTranslateX(150);
deathDateCheckBox.setTranslateY(150);
dayOfDeath.setTranslateX(110);
dayOfDeath.setTranslateY(190);
monthOfDeath.setTranslateX(182.5);
monthOfDeath.setTranslateY(190);
yearOfDeath.setTranslateX(255);
yearOfDeath.setTranslateY(190);
calculateAgeButton.setTranslateX(110);
calculateAgeButton.setTranslateY(260);
resultLabel.setTranslateX(0);
resultLabel.setTranslateY(340);
// يظهر جهة الوسط resultLabel هنا جعلنا نص الكائن
resultLabel.setAlignment(Pos.CENTER);
dayOfBirth.getSelectionModel().selectFirst();
monthOfBirth.getSelectionModel().selectFirst();
yearOfBirth.getSelectionModel().select(0);
dayOfDeath.getSelectionModel().selectFirst();
monthOfDeath.getSelectionModel().selectFirst();
yearOfDeath.getSelectionModel().select(0);
// هنا قما بتعديل حجم و سمك خط جميع الأشياء التي سنضيفها في النافذة
birthDateLabel.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;");
deathDateCheckBox.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;");
resultLabel.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;");
calculateAgeButton.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;");
// في النافذة لأننا ننوي ترتيب العناصر فيه بشكل يدويRoot Node و الذي ننوي جعله الـ Group هنا قمنا بإنشاء كائن من الكلاس
Group root = new Group();
// هنا قمنا بإضافة جميع الأشياء التي قمنا بإنشائها في النافذة
root.getChildren().add(birthDateLabel);
root.getChildren().add(deathDateCheckBox);
root.getChildren().add(resultLabel);
root.getChildren().add(calculateAgeButton);
root.getChildren().add(dayOfBirth);
root.getChildren().add(monthOfBirth);
root.getChildren().add(yearOfBirth);
root.getChildren().add(dayOfDeath);
root.getChildren().add(monthOfDeath);
root.getChildren().add(yearOfDeath);
// فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن
Scene scene = new Scene(root, 430, 420);
// هنا وضعنا عنوان للنافذة
stage.setTitle("Age Calculator");
// أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ
stage.setScene(scene);
// هنا قمنا بإظهار النافذة
stage.show();
// هنا جعلنا المستخدم غير قادر على تكبير أو تصغير حجم النافذة بنفسه
stage.setResizable(false);
// calculateAgeButton هنا قمنا بتحديد ماذا سيحدث عند النقر على الكائن
// حتى تحسب و تعرض العمر displayAge() فعلياً سيتم إستدعاء الدالة
calculateAgeButton.setOnAction((Action) -> {
displayAge();
});
// deathDateCheckBox هنا قمنا بتحديد ماذا سيحدث عند النقر على الكائن
// deathDatePicker لتفعيل أو إلغاء تفعيل الكائن toggleDeathDatePicker() فعلياً سيتم إستدعاء الدالة
deathDateCheckBox.selectedProperty().addListener(
(ObservableValue<? extends Boolean> ov, Boolean old_val, Boolean new_val) -> {
toggleDeathDatePicker();
}
);
// غير مفعل بشكل إفتراضي عند تشغيل البرنامج toggleDeathDatePicker لجعل الكائن toggleDeathDatePicker() هنا قمنا باستدعاء الدالة
toggleDeathDatePicker();
}
// هنا قمنا بتشغيل التطبيق
public static void main(String[] args) {
launch(args);
}
}
import java.time.LocalDate; import java.time.Period; import javafx.application.Application; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.geometry.Pos; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.paint.Color; import javafx.stage.Stage; public class Main extends Application { // هنا قمنا بتعريف الأشياء التي سيتم وضعها في النافذة Label birthDateLabel, resultLabel; CheckBox deathDateCheckBox; Button calculateAgeButton; ComboBox dayOfBirth, monthOfBirth, yearOfBirth, dayOfDeath, monthOfDeath, yearOfDeath; // سنستخدم هذه المتغيرات لتخزين التواريخ التي إختارها المستخدم من النافذة بشكل مؤقت int d1, d2, m1, m2, y1, y2; // لتخزين تاريخ وفاته endDate لتخزين تاريخ ميلاد الشخص, و الكائن startDate سنستخدم الكائن LocalDate startDate, endDate; // سنستخدم هذه المتغيرات لعرض الفارق النهائي بين تاريخ الميلاد و التاريخ الحالي أو تاريخ الوفاة long daysCounter, monthsCounter, yearsCounter; // مفعلاً أو غير مفعل (deathDatePicker) قمنا ببناء هذه الدالة لتحديد متى سيكون الكائن الذي يمثل تاريخ الوفاة public void toggleDeathDatePicker() { // deathDatePicker يوجد عليه علامة صح, سيتم تفعيل الكائن deathDateCheckBox إذا كان الكائن if (deathDateCheckBox.isSelected()) { dayOfDeath.setDisable(false); monthOfDeath.setDisable(false); yearOfDeath.setDisable(false); } // deathDatePicker لا يوجد عليه علامة صح, سيتم إلغاء تفعيل الكائن deathDateCheckBox إذا كان الكائن else { dayOfDeath.setDisable(true); monthOfDeath.setDisable(true); yearOfDeath.setDisable(true); } } // قمنا ببناء هذه الدالة لحساب و عرض العمر سواء كان المستخدم يريد حساب عمر شخص على قيد الحياة أو شخص ميت public void displayAge() { // سنستخدم هذا المتغير لتخزين نص النتيجة التي ستظهر String text = ""; // هنا قمنا بتخزين تاريخ الميلاد الذي إختاره المستخدم في المتغيرات التالية y1 = Integer.parseInt(yearOfBirth.getSelectionModel().getSelectedItem().toString()); m1 = monthOfBirth.getSelectionModel().getSelectedIndex() + 1; d1 = Integer.parseInt(dayOfBirth.getSelectionModel().getSelectedItem().toString()); // إذا كان خيار تحديد تاريخ الوفاة مفعل, سيتم تخزين التاريخ المحدد في المتغيرات التالية if (deathDateCheckBox.isSelected()) { y2 = Integer.parseInt(yearOfDeath.getSelectionModel().getSelectedItem().toString()); m2 = monthOfDeath.getSelectionModel().getSelectedIndex() + 1; d2 = Integer.parseInt(dayOfDeath.getSelectionModel().getSelectedItem().toString()); } // إذا كان خيار تحديد تاريخ الوفاة غير مفعل, سيتم تخزين التاريخ الحالي في المتغيرات التالية else { y2 = LocalDate.now().getYear(); m2 = LocalDate.now().getMonthValue(); d2 = LocalDate.now().getDayOfMonth(); } // endDate و تاريخ الوفاة في الكائن startDate هنا قمنا بوضع تاريخ الميلاد الذي حدده المستخدم في الكائن startDate = LocalDate.of(y1, m1, d1); endDate = LocalDate.of(y2, m2, d2); // هنا قمنا بتخزين الفارق بين التواريخ في المتغيرات التالية yearsCounter = Period.between(startDate, endDate).getYears(); monthsCounter = Period.between(startDate, endDate).getMonths(); daysCounter = Period.between(startDate, endDate).getDays(); // هنا قلنا إذا كان التاريخين متواسيين سيتم إظهار التنبيه التالي if (yearsCounter == 0 && monthsCounter == 0 && daysCounter == 0) { resultLabel.setTextFill(Color.RED); resultLabel.setText("Cannot compare same date!"); } // هنا قلنا أنه إذا كانت التواريخ المحددة هي منطقياً صحيحة سيتم إظهار العمر else if (!Period.between(startDate, endDate).isNegative()) { if (yearsCounter == 1) { text += yearsCounter + " year "; } else if (yearsCounter > 1) { text += yearsCounter + " years "; } if (monthsCounter == 1) { if (yearsCounter > 0 && daysCounter > 0) { text += ", " + monthsCounter + " month "; } else if (yearsCounter > 0 && daysCounter == 0) { text += "and " + monthsCounter + " month "; } else { text += monthsCounter + " month "; } } if (monthsCounter > 1) { if (yearsCounter > 0 && daysCounter > 0) { text += ", " + monthsCounter + " months "; } else if (yearsCounter > 0 && daysCounter == 0) { text += "and " + monthsCounter + " months "; } else { text += monthsCounter + " months "; } } if (daysCounter == 1) { if (yearsCounter == 0 && monthsCounter == 0) { text += daysCounter + " day"; } else { text += "and " + daysCounter + " day"; } } if (daysCounter > 1) { if (yearsCounter == 0 && monthsCounter == 0) { text += daysCounter + " days"; } else { text += "and " + daysCounter + " days"; } } resultLabel.setTextFill(Color.BLACK); resultLabel.setText(text); } // هنا قلنا أنه إذا كانت التواريخ المحددة هي منطقياً غير مقبولة سيتم إظهار التنبيه التالي else { resultLabel.setTextFill(Color.RED); resultLabel.setText("Logic order of Dates is wrong!"); } } @Override public void start(Stage stage) { // هنا وضعنا أسماء الأشهر التي سنظهرها في قائمة الأشهر String[] months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; // هنا وضعنا أرقام الأيام التي سنظهرها في قائمة الأيام Integer[] days = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; // currentYear هنا قمنا بتخزين رقم السنة الحالية في المتغير int currentYear = LocalDate.now().getYear(); // هنا قمنا بإنشاء مصفوفة, عدد عناصرها يساوي رقم السنة الحالية Integer[] years = new Integer[currentYear]; // هنا قمنا بتخزين أرقام السنين من 1 إلى رقم السنة الحالية بشكل عكسي for (int i = 0; i < currentYear; i++) years[currentYear-i-1] = i + 1; // هنا قمنا بإنشاء جميع الأشياء التي سنضيفها في النافذة birthDateLabel = new Label("Birth Date"); deathDateCheckBox = new CheckBox("Death Date"); resultLabel = new Label(); calculateAgeButton = new Button("Calculate Age"); dayOfBirth = new ComboBox(FXCollections.observableArrayList(days)); monthOfBirth = new ComboBox(FXCollections.observableArrayList(months)); yearOfBirth = new ComboBox(FXCollections.observableArrayList(years)); dayOfDeath = new ComboBox(FXCollections.observableArrayList(days)); monthOfDeath = new ComboBox(FXCollections.observableArrayList(months)); yearOfDeath = new ComboBox(FXCollections.observableArrayList(years)); // هنا قما بتعديل حجم جميع الأشياء التي سنضيفها في النافذة birthDateLabel.setPrefSize(150, 30); deathDateCheckBox.setPrefSize(150, 30); dayOfBirth.setPrefSize(65, 30); monthOfBirth.setPrefSize(65, 30); yearOfBirth.setPrefSize(70, 30); dayOfDeath.setPrefSize(65, 30); monthOfDeath.setPrefSize(65, 30); yearOfDeath.setPrefSize(70, 30); calculateAgeButton.setPrefSize(215, 50); resultLabel.setPrefSize(430, 30); // هنا قمنا بتحديد مكان ظهور كل شيء سيتم إضافته في الحاوية الرئيسية التي سنضعها في النافذة birthDateLabel.setTranslateX(174); birthDateLabel.setTranslateY(40); dayOfBirth.setTranslateX(110); dayOfBirth.setTranslateY(80); monthOfBirth.setTranslateX(182.5); monthOfBirth.setTranslateY(80); yearOfBirth.setTranslateX(255); yearOfBirth.setTranslateY(80); deathDateCheckBox.setTranslateX(150); deathDateCheckBox.setTranslateY(150); dayOfDeath.setTranslateX(110); dayOfDeath.setTranslateY(190); monthOfDeath.setTranslateX(182.5); monthOfDeath.setTranslateY(190); yearOfDeath.setTranslateX(255); yearOfDeath.setTranslateY(190); calculateAgeButton.setTranslateX(110); calculateAgeButton.setTranslateY(260); resultLabel.setTranslateX(0); resultLabel.setTranslateY(340); // يظهر جهة الوسط resultLabel هنا جعلنا نص الكائن resultLabel.setAlignment(Pos.CENTER); dayOfBirth.getSelectionModel().selectFirst(); monthOfBirth.getSelectionModel().selectFirst(); yearOfBirth.getSelectionModel().select(0); dayOfDeath.getSelectionModel().selectFirst(); monthOfDeath.getSelectionModel().selectFirst(); yearOfDeath.getSelectionModel().select(0); // هنا قما بتعديل حجم و سمك خط جميع الأشياء التي سنضيفها في النافذة birthDateLabel.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;"); deathDateCheckBox.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;"); resultLabel.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;"); calculateAgeButton.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;"); // في النافذة لأننا ننوي ترتيب العناصر فيه بشكل يدويRoot Node و الذي ننوي جعله الـ Group هنا قمنا بإنشاء كائن من الكلاس Group root = new Group(); // هنا قمنا بإضافة جميع الأشياء التي قمنا بإنشائها في النافذة root.getChildren().add(birthDateLabel); root.getChildren().add(deathDateCheckBox); root.getChildren().add(resultLabel); root.getChildren().add(calculateAgeButton); root.getChildren().add(dayOfBirth); root.getChildren().add(monthOfBirth); root.getChildren().add(yearOfBirth); root.getChildren().add(dayOfDeath); root.getChildren().add(monthOfDeath); root.getChildren().add(yearOfDeath); // فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن Scene scene = new Scene(root, 430, 420); // هنا وضعنا عنوان للنافذة stage.setTitle("Age Calculator"); // أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ stage.setScene(scene); // هنا قمنا بإظهار النافذة stage.show(); // هنا جعلنا المستخدم غير قادر على تكبير أو تصغير حجم النافذة بنفسه stage.setResizable(false); // calculateAgeButton هنا قمنا بتحديد ماذا سيحدث عند النقر على الكائن // حتى تحسب و تعرض العمر displayAge() فعلياً سيتم إستدعاء الدالة calculateAgeButton.setOnAction((Action) -> { displayAge(); }); // deathDateCheckBox هنا قمنا بتحديد ماذا سيحدث عند النقر على الكائن // deathDatePicker لتفعيل أو إلغاء تفعيل الكائن toggleDeathDatePicker() فعلياً سيتم إستدعاء الدالة deathDateCheckBox.selectedProperty().addListener( (ObservableValue<? extends Boolean> ov, Boolean old_val, Boolean new_val) -> { toggleDeathDatePicker(); } ); // غير مفعل بشكل إفتراضي عند تشغيل البرنامج toggleDeathDatePicker لجعل الكائن toggleDeathDatePicker() هنا قمنا باستدعاء الدالة toggleDeathDatePicker(); } // هنا قمنا بتشغيل التطبيق public static void main(String[] args) { launch(args); } }


البرنامج الثاني

تحميل كود برنامج حساب الأعمار في جافا

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


كود البرنامج

Main.java
import java.time.LocalDate;
import java.time.Period;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application {
// هنا قمنا بتعريف الأشياء التي سيتم وضعها في النافذة
Label birthDateLabel, resultLabel;
CheckBox deathDateCheckBox;
Button calculateAgeButton;
DatePicker birthDatePicker, deathDatePicker;
// سنستخدم هذه المتغيرات لتخزين التواريخ التي إختارها المستخدم من النافذة بشكل مؤقت
int d1, d2, m1, m2, y1, y2;
// لتخزين تاريخ وفاته endDate لتخزين تاريخ ميلاد الشخص, و الكائن startDate سنستخدم الكائن
LocalDate startDate, endDate;
// سنستخدم هذه المتغيرات لعرض الفارق النهائي بين تاريخ الميلاد و التاريخ الحالي أو تاريخ الوفاة
long daysCounter, monthsCounter, yearsCounter;
// مفعلاً أو غير مفعل (deathDatePicker) قمنا ببناء هذه الدالة لتحديد متى سيكون الكائن الذي يمثل تاريخ الوفاة
public void toggleDeathDatePicker() {
// deathDatePicker يوجد عليه علامة صح, سيتم تفعيل الكائن deathDateCheckBox إذا كان الكائن
if (deathDateCheckBox.isSelected()) {
deathDatePicker.setDisable(false);
} // deathDatePicker لا يوجد عليه علامة صح, سيتم إلغاء تفعيل الكائن deathDateCheckBox إذا كان الكائن
else {
deathDatePicker.setDisable(true);
}
}
// قمنا ببناء هذه الدالة لحساب و عرض العمر سواء كان المستخدم يريد حساب عمر شخص على قيد الحياة أو شخص ميت
public void displayAge() {
// سنستخدم هذا المتغير لتخزين نص النتيجة التي ستظهر
String text = "";
// هنا قمنا بتخزين تاريخ الميلاد الذي إختاره المستخدم في المتغيرات التالية
y1 = birthDatePicker.getValue().getYear();
m1 = birthDatePicker.getValue().getMonthValue();
d1 = birthDatePicker.getValue().getDayOfMonth();
// إذا كان خيار تحديد تاريخ الوفات مفعل, سيتم تخزين التاريخ المحدد في المتغيرات التالية
if (deathDateCheckBox.isSelected()) {
y2 = deathDatePicker.getValue().getYear();
m2 = deathDatePicker.getValue().getMonthValue();
d2 = deathDatePicker.getValue().getDayOfMonth();
} // إذا كان خيار تحديد تاريخ الوفات غير مفعل, سيتم تخزين التاريخ الحالي في المتغيرات التالية
else {
y2 = LocalDate.now().getYear();
m2 = LocalDate.now().getMonthValue();
d2 = LocalDate.now().getDayOfMonth();
}
// endDate و تاريخ الوفاة في الكائن startDate هنا قمنا بوضع تاريخ الميلاد الذي حدده المستخدم في الكائن
startDate = LocalDate.of(y1, m1, d1);
endDate = LocalDate.of(y2, m2, d2);
// هنا قمنا بتخزين الفارق بين التواريخ في المتغيرات التالية
yearsCounter = Period.between(startDate, endDate).getYears();
monthsCounter = Period.between(startDate, endDate).getMonths();
daysCounter = Period.between(startDate, endDate).getDays();
// هنا قلنا إذا كان التاريخين متواسيين سيتم إظهار التنبيه التالي
if (yearsCounter == 0 && monthsCounter == 0 && daysCounter == 0) {
resultLabel.setTextFill(Color.RED);
resultLabel.setText("Cannot compare same date!");
} // هنا قلنا أنه إذا كانت التواريخ المحددة هي منطقياً صحيحة سيتم إظهار العمر
else if (!Period.between(startDate, endDate).isNegative()) {
if (yearsCounter == 1) {
text += yearsCounter + " year ";
} else if (yearsCounter > 1) {
text += yearsCounter + " years ";
}
if (monthsCounter == 1) {
if (yearsCounter > 0 && daysCounter > 0) {
text += ", " + monthsCounter + " month ";
} else if (yearsCounter > 0 && daysCounter == 0) {
text += "and " + monthsCounter + " month ";
} else {
text += monthsCounter + " month ";
}
}
if (monthsCounter > 1) {
if (yearsCounter > 0 && daysCounter > 0) {
text += ", " + monthsCounter + " months ";
} else if (yearsCounter > 0 && daysCounter == 0) {
text += "and " + monthsCounter + " months ";
} else {
text += monthsCounter + " months ";
}
}
if (daysCounter == 1) {
if (yearsCounter == 0 && monthsCounter == 0) {
text += daysCounter + " day";
} else {
text += "and " + daysCounter + " day";
}
}
if (daysCounter > 1) {
if (yearsCounter == 0 && monthsCounter == 0) {
text += daysCounter + " days";
} else {
text += "and " + daysCounter + " days";
}
}
resultLabel.setTextFill(Color.BLACK);
resultLabel.setText(text);
} // هنا قلنا أنه إذا كانت التواريخ المحددة هي منطقياً غير مقبولة سيتم إظهار التنبيه التالي
else {
resultLabel.setTextFill(Color.RED);
resultLabel.setText("Logic order of Dates is wrong!");
}
}
@Override
public void start(Stage stage) {
// هنا قمنا بإنشاء جميع الأشياء التي سنضيفها في النافذة
birthDateLabel = new Label("Birth Date");
deathDateCheckBox = new CheckBox("Death Date");
resultLabel = new Label();
calculateAgeButton = new Button("Calculate Age");
birthDatePicker = new DatePicker(LocalDate.of(2000, 1, 1));
deathDatePicker = new DatePicker(LocalDate.now());
// هنا قما بتعديل حجم و سمك خط جميع الأشياء التي سنضيفها في النافذة
birthDateLabel.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;");
deathDateCheckBox.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;");
resultLabel.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;");
calculateAgeButton.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;");
birthDatePicker.setStyle("-fx-font-size: 14px;");
deathDatePicker.setStyle("-fx-font-size: 14px;");
// هنا قما بتعديل حجم جميع الأشياء التي سنضيفها في النافذة
// لم نحدد حجمه لأنه لا داعي لذلك و سنتركه يظهر في وسط النافذة مهما كان حجمه resultLabel ملاحظة: الكائن
birthDateLabel.setPrefSize(200, 30);
deathDateCheckBox.setPrefSize(200, 30);
birthDatePicker.setPrefSize(200, 30);
deathDatePicker.setPrefSize(200, 30);
calculateAgeButton.setPrefSize(200, 50);
// في النافذة لأننا ننوي ترتيب العناصر فيه بشكل عامودي Root Node و الذي ننوي جعله الـ VBox هنا قمنا بإنشاء كائن من الكلاس
VBox root = new VBox();
// حتى يظهر محتواه في وسط النافذة مع إضافة مسافة فارغة بمقدار 20 بيكسل حوله من كل الجهات root هنا قمنا بتعديل خصائص الكائن
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(20));
// هنا قمنا بإضافة جميع الأشياء التي قمنا بإنشائها في النافذة
root.getChildren().add(birthDateLabel);
root.getChildren().add(birthDatePicker);
root.getChildren().add(deathDateCheckBox);
root.getChildren().add(deathDatePicker);
root.getChildren().add(calculateAgeButton);
root.getChildren().add(resultLabel);
// هنا قمنا بإضافة مسافة فارغة حول كل شيء أضفناه في النافذة
VBox.setMargin(birthDatePicker, new Insets(10, 0, 35, 0));
VBox.setMargin(deathDateCheckBox, new Insets(10, 0, 0, 0));
VBox.setMargin(deathDatePicker, new Insets(10, 0, 35, 0));
VBox.setMargin(calculateAgeButton, new Insets(10, 0, 25, 0));
VBox.setMargin(resultLabel, new Insets(10, 0, 0, 0));
// فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن
Scene scene = new Scene(root, 430, 420);
// هنا وضعنا عنوان للنافذة
stage.setTitle("Age Calculator");
// أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ
stage.setScene(scene);
// هنا قمنا بإظهار النافذة
stage.show();
// calculateAgeButton هنا قمنا بتحديد ماذا سيحدث عند النقر على الكائن
// حتى تحسب و تعرض العمر displayAge() فعلياً سيتم إستدعاء الدالة
calculateAgeButton.setOnAction((Action) -> {
displayAge();
});
// deathDateCheckBox هنا قمنا بتحديد ماذا سيحدث عند النقر على الكائن
// deathDatePicker لتفعيل أو إلغاء تفعيل الكائن toggleDeathDatePicker() فعلياً سيتم إستدعاء الدالة
deathDateCheckBox.selectedProperty().addListener(
(ObservableValue<? extends Boolean> ov, Boolean old_val, Boolean new_val) -> {
toggleDeathDatePicker();
}
);
// غير مفعل بشكل إفتراضي عند تشغيل البرنامج toggleDeathDatePicker لجعل الكائن toggleDeathDatePicker() هنا قمنا باستدعاء الدالة
toggleDeathDatePicker();
}
// هنا قمنا بتشغيل التطبيق
public static void main(String[] args) {
launch(args);
}
}
import java.time.LocalDate; import java.time.Period; import javafx.application.Application; import javafx.beans.value.ObservableValue; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.DatePicker; import javafx.scene.control.Label; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.stage.Stage; public class Main extends Application { // هنا قمنا بتعريف الأشياء التي سيتم وضعها في النافذة Label birthDateLabel, resultLabel; CheckBox deathDateCheckBox; Button calculateAgeButton; DatePicker birthDatePicker, deathDatePicker; // سنستخدم هذه المتغيرات لتخزين التواريخ التي إختارها المستخدم من النافذة بشكل مؤقت int d1, d2, m1, m2, y1, y2; // لتخزين تاريخ وفاته endDate لتخزين تاريخ ميلاد الشخص, و الكائن startDate سنستخدم الكائن LocalDate startDate, endDate; // سنستخدم هذه المتغيرات لعرض الفارق النهائي بين تاريخ الميلاد و التاريخ الحالي أو تاريخ الوفاة long daysCounter, monthsCounter, yearsCounter; // مفعلاً أو غير مفعل (deathDatePicker) قمنا ببناء هذه الدالة لتحديد متى سيكون الكائن الذي يمثل تاريخ الوفاة public void toggleDeathDatePicker() { // deathDatePicker يوجد عليه علامة صح, سيتم تفعيل الكائن deathDateCheckBox إذا كان الكائن if (deathDateCheckBox.isSelected()) { deathDatePicker.setDisable(false); } // deathDatePicker لا يوجد عليه علامة صح, سيتم إلغاء تفعيل الكائن deathDateCheckBox إذا كان الكائن else { deathDatePicker.setDisable(true); } } // قمنا ببناء هذه الدالة لحساب و عرض العمر سواء كان المستخدم يريد حساب عمر شخص على قيد الحياة أو شخص ميت public void displayAge() { // سنستخدم هذا المتغير لتخزين نص النتيجة التي ستظهر String text = ""; // هنا قمنا بتخزين تاريخ الميلاد الذي إختاره المستخدم في المتغيرات التالية y1 = birthDatePicker.getValue().getYear(); m1 = birthDatePicker.getValue().getMonthValue(); d1 = birthDatePicker.getValue().getDayOfMonth(); // إذا كان خيار تحديد تاريخ الوفات مفعل, سيتم تخزين التاريخ المحدد في المتغيرات التالية if (deathDateCheckBox.isSelected()) { y2 = deathDatePicker.getValue().getYear(); m2 = deathDatePicker.getValue().getMonthValue(); d2 = deathDatePicker.getValue().getDayOfMonth(); } // إذا كان خيار تحديد تاريخ الوفات غير مفعل, سيتم تخزين التاريخ الحالي في المتغيرات التالية else { y2 = LocalDate.now().getYear(); m2 = LocalDate.now().getMonthValue(); d2 = LocalDate.now().getDayOfMonth(); } // endDate و تاريخ الوفاة في الكائن startDate هنا قمنا بوضع تاريخ الميلاد الذي حدده المستخدم في الكائن startDate = LocalDate.of(y1, m1, d1); endDate = LocalDate.of(y2, m2, d2); // هنا قمنا بتخزين الفارق بين التواريخ في المتغيرات التالية yearsCounter = Period.between(startDate, endDate).getYears(); monthsCounter = Period.between(startDate, endDate).getMonths(); daysCounter = Period.between(startDate, endDate).getDays(); // هنا قلنا إذا كان التاريخين متواسيين سيتم إظهار التنبيه التالي if (yearsCounter == 0 && monthsCounter == 0 && daysCounter == 0) { resultLabel.setTextFill(Color.RED); resultLabel.setText("Cannot compare same date!"); } // هنا قلنا أنه إذا كانت التواريخ المحددة هي منطقياً صحيحة سيتم إظهار العمر else if (!Period.between(startDate, endDate).isNegative()) { if (yearsCounter == 1) { text += yearsCounter + " year "; } else if (yearsCounter > 1) { text += yearsCounter + " years "; } if (monthsCounter == 1) { if (yearsCounter > 0 && daysCounter > 0) { text += ", " + monthsCounter + " month "; } else if (yearsCounter > 0 && daysCounter == 0) { text += "and " + monthsCounter + " month "; } else { text += monthsCounter + " month "; } } if (monthsCounter > 1) { if (yearsCounter > 0 && daysCounter > 0) { text += ", " + monthsCounter + " months "; } else if (yearsCounter > 0 && daysCounter == 0) { text += "and " + monthsCounter + " months "; } else { text += monthsCounter + " months "; } } if (daysCounter == 1) { if (yearsCounter == 0 && monthsCounter == 0) { text += daysCounter + " day"; } else { text += "and " + daysCounter + " day"; } } if (daysCounter > 1) { if (yearsCounter == 0 && monthsCounter == 0) { text += daysCounter + " days"; } else { text += "and " + daysCounter + " days"; } } resultLabel.setTextFill(Color.BLACK); resultLabel.setText(text); } // هنا قلنا أنه إذا كانت التواريخ المحددة هي منطقياً غير مقبولة سيتم إظهار التنبيه التالي else { resultLabel.setTextFill(Color.RED); resultLabel.setText("Logic order of Dates is wrong!"); } } @Override public void start(Stage stage) { // هنا قمنا بإنشاء جميع الأشياء التي سنضيفها في النافذة birthDateLabel = new Label("Birth Date"); deathDateCheckBox = new CheckBox("Death Date"); resultLabel = new Label(); calculateAgeButton = new Button("Calculate Age"); birthDatePicker = new DatePicker(LocalDate.of(2000, 1, 1)); deathDatePicker = new DatePicker(LocalDate.now()); // هنا قما بتعديل حجم و سمك خط جميع الأشياء التي سنضيفها في النافذة birthDateLabel.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;"); deathDateCheckBox.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;"); resultLabel.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;"); calculateAgeButton.setStyle("-fx-font-size: 17px; -fx-font-weight: bold;"); birthDatePicker.setStyle("-fx-font-size: 14px;"); deathDatePicker.setStyle("-fx-font-size: 14px;"); // هنا قما بتعديل حجم جميع الأشياء التي سنضيفها في النافذة // لم نحدد حجمه لأنه لا داعي لذلك و سنتركه يظهر في وسط النافذة مهما كان حجمه resultLabel ملاحظة: الكائن birthDateLabel.setPrefSize(200, 30); deathDateCheckBox.setPrefSize(200, 30); birthDatePicker.setPrefSize(200, 30); deathDatePicker.setPrefSize(200, 30); calculateAgeButton.setPrefSize(200, 50); // في النافذة لأننا ننوي ترتيب العناصر فيه بشكل عامودي Root Node و الذي ننوي جعله الـ VBox هنا قمنا بإنشاء كائن من الكلاس VBox root = new VBox(); // حتى يظهر محتواه في وسط النافذة مع إضافة مسافة فارغة بمقدار 20 بيكسل حوله من كل الجهات root هنا قمنا بتعديل خصائص الكائن root.setAlignment(Pos.CENTER); root.setPadding(new Insets(20)); // هنا قمنا بإضافة جميع الأشياء التي قمنا بإنشائها في النافذة root.getChildren().add(birthDateLabel); root.getChildren().add(birthDatePicker); root.getChildren().add(deathDateCheckBox); root.getChildren().add(deathDatePicker); root.getChildren().add(calculateAgeButton); root.getChildren().add(resultLabel); // هنا قمنا بإضافة مسافة فارغة حول كل شيء أضفناه في النافذة VBox.setMargin(birthDatePicker, new Insets(10, 0, 35, 0)); VBox.setMargin(deathDateCheckBox, new Insets(10, 0, 0, 0)); VBox.setMargin(deathDatePicker, new Insets(10, 0, 35, 0)); VBox.setMargin(calculateAgeButton, new Insets(10, 0, 25, 0)); VBox.setMargin(resultLabel, new Insets(10, 0, 0, 0)); // فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن Scene scene = new Scene(root, 430, 420); // هنا وضعنا عنوان للنافذة stage.setTitle("Age Calculator"); // أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ stage.setScene(scene); // هنا قمنا بإظهار النافذة stage.show(); // calculateAgeButton هنا قمنا بتحديد ماذا سيحدث عند النقر على الكائن // حتى تحسب و تعرض العمر displayAge() فعلياً سيتم إستدعاء الدالة calculateAgeButton.setOnAction((Action) -> { displayAge(); }); // deathDateCheckBox هنا قمنا بتحديد ماذا سيحدث عند النقر على الكائن // deathDatePicker لتفعيل أو إلغاء تفعيل الكائن toggleDeathDatePicker() فعلياً سيتم إستدعاء الدالة deathDateCheckBox.selectedProperty().addListener( (ObservableValue<? extends Boolean> ov, Boolean old_val, Boolean new_val) -> { toggleDeathDatePicker(); } ); // غير مفعل بشكل إفتراضي عند تشغيل البرنامج toggleDeathDatePicker لجعل الكائن toggleDeathDatePicker() هنا قمنا باستدعاء الدالة toggleDeathDatePicker(); } // هنا قمنا بتشغيل التطبيق public static void main(String[] args) { launch(args); } }

الدورات

أدوات مساعدة

أقسام الموقع

دورات
مقالات كتب مشاريع أسئلة