مشروع شامل

هذا الدرس هو المشروع النهائي لدورة Java، يطبق جميع نقاط المعرفة.

نظرة عامة على المشروع

بناء تطبيق قائمة مهام يدعم:

نموذج البيانات

JAVA
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Todo implements Serializable {
    private static final long serialVersionUID = 1L;
    
    public enum Priority { LOW, MEDIUM, HIGH }
    public enum Status { PENDING, COMPLETED }
    
    private int id;
    private String title;
    private String description;
    private Priority priority;
    private Status status;
    private LocalDateTime createdAt;
    private LocalDateTime completedAt;
    
    public Todo(int id, String title, String description, Priority priority) {
        this.id = id;
        this.title = title;
        this.description = description;
        this.priority = priority;
        this.status = Status.PENDING;
        this.createdAt = LocalDateTime.now();
    }
    
    // Getters/Setters
    public int getId() { return id; }
    public String getTitle() { return title; }
    public String getDescription() { return description; }
    public Priority getPriority() { return priority; }
    public Status getStatus() { return status; }
    public LocalDateTime getCreatedAt() { return createdAt; }
    public LocalDateTime getCompletedAt() { return completedAt; }
    
    public void setStatus(Status status) {
        this.status = status;
        if (status == Status.COMPLETED) {
            this.completedAt = LocalDateTime.now();
        }
    }
    
    public boolean isCompleted() {
        return status == Status.COMPLETED;
    }
    
    @Override
    public String toString() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        String statusIcon = isCompleted() ? "✅" : "⬜";
        String priorityIcon;
        switch (priority) {
            case HIGH: priorityIcon = "🔴"; break;
            case MEDIUM: priorityIcon = "🟡"; break;
            default: priorityIcon = "🟢"; break;
        }
        return String.format("%s %s [%d] %s (%s)", 
            statusIcon, priorityIcon, id, title, createdAt.format(formatter));
    }
}

فئة المدير

JAVA
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

public class TodoManager {
    private List<Todo> todos;
    private int nextId;
    private static final String FILE_NAME = "todos.dat";
    
    public TodoManager() {
        this.todos = new ArrayList<>();
        this.nextId = 1;
        loadFromFile();
    }
    
    // إضافة مهمة
    public Todo addTodo(String title, String description, Todo.Priority priority) {
        Todo todo = new Todo(nextId++, title, description, priority);
        todos.add(todo);
        saveToFile();
        return todo;
    }
    
    // إكمال مهمة
    public boolean completeTodo(int id) {
        Todo todo = findById(id);
        if (todo != null && !todo.isCompleted()) {
            todo.setStatus(Todo.Status.COMPLETED);
            saveToFile();
            return true;
        }
        return false;
    }
    
    // حذف مهمة
    public boolean deleteTodo(int id) {
        Todo todo = findById(id);
        if (todo != null) {
            todos.remove(todo);
            saveToFile();
            return true;
        }
        return false;
    }
    
    // إيجاد مهمة
    public Todo findById(int id) {
        return todos.stream()
            .filter(t -> t.getId() == id)
            .findFirst()
            .orElse(null);
    }
    
    // الحصول على جميع المهام
    public List<Todo> getAllTodos() {
        return new ArrayList<>(todos);
    }
    
    // الحصول على المهام المعلقة
    public List<Todo> getPendingTodos() {
        return todos.stream()
            .filter(t -> !t.isCompleted())
            .collect(Collectors.toList());
    }
    
    // الحصول على المهام المكتملة
    public List<Todo> getCompletedTodos() {
        return todos.stream()
            .filter(Todo::isCompleted)
            .collect(Collectors.toList());
    }
    
    // ترتيب حسب الأولوية
    public List<Todo> sortByPriority() {
        return todos.stream()
            .sorted((a, b) -> {
                int cmp = b.getPriority().compareTo(a.getPriority());
                return cmp != 0 ? cmp : a.getId() - b.getId();
            })
            .collect(Collectors.toList());
    }
    
    // ترتيب حسب تاريخ الإنشاء
    public List<Todo> sortByDate() {
        return todos.stream()
            .sorted(Comparator.comparing(Todo::getCreatedAt))
            .collect(Collectors.toList());
    }
    
    // إحصائيات
    public int getTotal() { return todos.size(); }
    public int getPendingCount() { return (int) todos.stream().filter(t -> !t.isCompleted()).count(); }
    public int getCompletedCount() { return (int) todos.stream().filter(Todo::isCompleted).count(); }
    
    // حفظ في ملف
    private void saveToFile() {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_NAME))) {
            oos.writeObject(todos);
            oos.writeInt(nextId);
        } catch (IOException e) {
            System.out.println("فشل الحفظ: " + e.getMessage());
        }
    }
    
    // تحميل من ملف
    @SuppressWarnings("unchecked")
    private void loadFromFile() {
        File file = new File(FILE_NAME);
        if (!file.exists()) return;
        
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME))) {
            todos = (List<Todo>) ois.readObject();
            nextId = ois.readInt();
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("فشل التحميل: " + e.getMessage());
        }
    }
}

البرنامج الرئيسي

JAVA
import java.util.List;
import java.util.Scanner;

public class TodoApp {
    private static TodoManager manager = new TodoManager();
    private static Scanner scanner = new Scanner(System.in);
    
    public static void main(String[] args) {
        System.out.println("=== قائمة المهام ===");
        
        int choice;
        do {
            showMenu();
            choice = getIntInput("أدخل اختيارك: ");
            
            switch (choice) {
                case 1: addTodo(); break;
                case 2: listTodos(); break;
                case 3: completeTodo(); break;
                case 4: deleteTodo(); break;
                case 5: showStatistics(); break;
                case 6: listByPriority(); break;
                case 0: System.out.println("شكراً!"); break;
                default: System.out.println("خيار غير صالح");
            }
        } while (choice != 0);
        
        scanner.close();
    }
    
    private static void showMenu() {
        System.out.println("\n--- القائمة ---");
        System.out.println("1. إضافة مهمة");
        System.out.println("2. عرض جميع المهام");
        System.out.println("3. وضع علامة مكتمل");
        System.out.println("4. حذف مهمة");
        System.out.println("5. إحصائيات");
        System.out.println("6. ترتيب حسب الأولوية");
        System.out.println("0. خروج");
    }
    
    private static void addTodo() {
        System.out.print("العنوان: ");
        String title = scanner.nextLine().trim();
        if (title.isEmpty()) {
            System.out.println("العنوان لا يمكن أن يكون فارغاً");
            return;
        }
        
        System.out.print("الوصف: ");
        String desc = scanner.nextLine().trim();
        
        System.out.println("الأولوية: 1-منخفضة 2-متوسطة 3-عالية");
        int p = getIntInput("الاختيار: ");
        Todo.Priority priority;
        switch (p) {
            case 1: priority = Todo.Priority.LOW; break;
            case 3: priority = Todo.Priority.HIGH; break;
            default: priority = Todo.Priority.MEDIUM;
        }
        
        Todo todo = manager.addTodo(title, desc, priority);
        System.out.println("أضيف: " + todo);
    }
    
    private static void listTodos() {
        List<Todo> todos = manager.getAllTodos();
        if (todos.isEmpty()) {
            System.out.println("لا توجد مهام");
            return;
        }
        
        System.out.println("\n--- قائمة المهام ---");
        for (Todo todo : todos) {
            System.out.println(todo);
        }
        System.out.printf("المجموع: %d (معلقة: %d، مكتملة: %d)%n", 
            manager.getTotal(), manager.getPendingCount(), manager.getCompletedCount());
    }
    
    private static void completeTodo() {
        listTodos();
        int id = getIntInput("أدخل المعرف للإكمال: ");
        if (manager.completeTodo(id)) {
            System.out.println("تم وضع علامة مكتمل");
        } else {
            System.out.println("معرف غير صالح أو مكتمل بالفعل");
        }
    }
    
    private static void deleteTodo() {
        listTodos();
        int id = getIntInput("أدخل المعرف للحذف: ");
        if (manager.deleteTodo(id)) {
            System.out.println("تم الحذف");
        } else {
            System.out.println("معرف غير صالح");
        }
    }
    
    private static void showStatistics() {
        System.out.println("\n=== إحصائيات ===");
        System.out.println("المجموع: " + manager.getTotal());
        System.out.println("معلقة: " + manager.getPendingCount());
        System.out.println("مكتملة: " + manager.getCompletedCount());
        double rate = manager.getTotal() > 0 ? 
            (double) manager.getCompletedCount() / manager.getTotal() * 100 : 0;
        System.out.printf("نسبة الإكمال: %.1f%%%n", rate);
    }
    
    private static void listByPriority() {
        List<Todo> todos = manager.sortByPriority();
        System.out.println("\n--- مرتبة حسب الأولوية ---");
        for (Todo todo : todos) {
            System.out.println(todo);
        }
    }
    
    private static int getIntInput(String prompt) {
        System.out.print(prompt);
        while (!scanner.hasNextInt()) {
            System.out.print("أدخل رقماً: ");
            scanner.next();
        }
        int value = scanner.nextInt();
        scanner.nextLine();  // استهلاك سطر جديد
        return value;
    }
}

مثال الناتج

TEXT
=== قائمة المهام ===

--- القائمة ---
1. إضافة مهمة
2. عرض جميع المهام
3. وضع علامة مكتمل
4. حذف مهمة
5. إحصائيات
6. ترتيب حسب الأولوية
0. خروج
أدخل اختيارك: 1
العنوان: تعلم Java
الوصف: إكمال درس 32 من دورة Java
الأولوية: 1-منخفضة 2-متوسطة 3-عالية
الاختيار: 3
أضيف: ⬜ 🔴 [1] تعلم Java (2026-06-25 14:30)

أدخل اختيارك: 2

--- قائمة المهام ---
⬜ 🔴 [1] تعلم Java (2026-06-25 14:30)
المجموع: 1 (معلقة: 1، مكتملة: 0)

ملخص المعرفة

المعرفة التطبيق
فئات وكائنات تصميم فئات Todo و TodoManager
التغليف حقول خاصة، getters/setters
Enums Priority، Status
Collections List للمهام، Stream
معالجة الاستثناءات معالجة أخطاء IO
File IO التسلسل للحفظ/التحميل
التاريخ/الوقت LocalDateTime للتواريخ
Lambda ترتيب، تصفية بال Stream
Generics List أمان النوع

ميزات موسعة

1. تصفية حسب التاريخ

JAVA
public List<Todo> getTodayTodos() {
    LocalDate today = LocalDate.now();
    return todos.stream()
        .filter(t -> t.getCreatedAt().toLocalDate().equals(today))
        .collect(Collectors.toList());
}

2. وظيفة البحث

JAVA
public List<Todo> search(String keyword) {
    String lower = keyword.toLowerCase();
    return todos.stream()
        .filter(t -> t.getTitle().toLowerCase().contains(lower) ||
                     t.getDescription().toLowerCase().contains(lower))
        .collect(Collectors.toList());
}

3. التصدير إلى نص

JAVA
public void exportToText(String filename) throws IOException {
    try (PrintWriter writer = new PrintWriter(new FileWriter(filename))) {
        writer.println("=== تصدير قائمة المهام ===");
        writer.println("وقت التصدير: " + LocalDateTime.now());
        writer.println();
        
        for (Todo todo : todos) {
            writer.println(todo);
            if (!todo.getDescription().isEmpty()) {
                writer.println("  " + todo.getDescription());
            }
            writer.println();
        }
    }
}

❓ أسئلة شائعة

س كيف أوسع لتطبيق GUI؟
ج استخدم JavaFX أو Swing لتنفيذ واجهة رسومية.
س كيف أدعم عدة مستخدمين؟
ج كل مستخدم يحصل على ملف خاص به، أو استخدم قاعدة بيانات.
س كيف أضيف وظيفة التذكير؟
ج استخدم Timer/ScheduledExecutorService للتحقق من المهام المستحقة.

📖 ملخص

📝 تمارين

  1. توسيع: أضف البحث والتصفية حسب التاريخ
  2. تصدير: ادعم التصدير بصيغة CSV
  3. GUI: نفذ واجهة رسومية بـ JavaFX

🎉 مبروك لإكمال دورة Java!

خلال 32 درس، لقد أتقنت:

الخطوات التالية للتعلم:

100%