كود برنامج الة حاسبة مكتوب بلغة الجافا مفتوح المصدر | calculator project java code

 

برنامج الة حاسبة مكتوب بلغة الجافا مفتوح المصدر


برنامج الة حاسبة مكتوب بلغة الجافا مفتوح المصدر

متابعي موقعنا الاعزاء مرحبا بكم في مقالة جديدة وفي مقالة سوف نتعرف على برنامج مفتوح المصدر مكتوب بالجافا يمكن التعديل عليه وهو برنامج الالة الحاسبة حيث تم تنفيذ التصميم باستخدام إطار الـ Swing ونحن في هذا الموقع نحاول توفير لكم جميع الاكواد وايضا مشاريع مفتوحة المصدر لمحبي البرمجة وللامانة هذا الكود منقوول .


ينصح بي تعليم البرمجة للاطفال بالعربي والبدء بلغة java لان مبرمج جافا يكون قادر على برمجة تطبيقات سطح المكتب وايضا تطوير تطبيقات الاندرويد فالغة الجافا مهمة جدا وننصح اي مبتدئ في هذا المجال يس صغيرا فقط ان يبدء بها لانها لغة مهمة ف مبرمج جافا يكون قوي عكس لغات اخرى بمعنى ان الجافا اصعب من كوتلن و بايثون ودارت واللغه الجديدة وبدايتك بالصعب وانتقالك للسهل بعدها اسفل من البدء بالسهل وايضا نحن نقدم لكم دورة جافا مجانية في بداية قسم جافا يمكنك الاطلاع عليها و لغة جافا اكثر لغة برمجية لها اكواد في موقنا سواء اكواد لبناء تطبيقات الاندرويد او غيرها فنحن نركز بشكل كبير على Java ولذلك قد تجد اغلب الشروحات تكون جافا .


ايضا تستطيع تعليم البرمجة للاطفال مجانا عن طريق موقعنا و دورة جافا الصغيرة التي قدمناها لكم في بداية قسم لغة جافا ويمكنك بعد التطوير فيها البحث عن شركة تطوير تطبيقات الجوال والعمل بها او حتى العمل كعامل حر او بمعنى اخر " freelance " وهو عباره عن اشخاص يبحثون عن خدمة وشخص يكون قادر على تأدية هذة الخدمة لهم ومواقع الfreelance كثيرة جدا منها العربيه و الانجليزي سواء كنت تهتم بمجال برمجة تطبيقات سطح المكتب او تطوير تطبيقات الموبايل فستجد هناك وظائف واعمال والامر لا يقتصر فقط على البرمجة بل يوجد اعمال كثيرة اخرى يمكنك تصفح المواقع لتفهم اكثر حولها .


افضل البرنامج و المحررات للكتابة بالجافا ؟

يوجد مقالة سابقة عن تحميل افضل البرنامج التي تساعدك في كتابة اكواد بلغة الجافا بسهولة ومن تلك البرامج وافضلها للمبتدئين netbeans يمكنك بناء و عمل برامج كبيرة عن طريق عن البرنامج البسيط ، ارجع الى المصدر وهو ( java compiler ) لتجد مجموعة منوعة من البرامج اللازمة  مع ذكر عيوب و مميزات كل برنامج ملاحظة هذة البرامج تعمل على جهاز الكمبيوتر  ، أو يتم استخدام مواقع اونلاين لكتابة ألاكواد عن طريق هذة المقالة ( java online compiler ) وستجد افضل محرر بداخل هذة المقالة ، ويوجد تطبيق او مجموعة تطبيقات للهاتف المحمول للاندرويد والايفون للكتابة بالجافا و يمكنك صناعه و تنفيذ من خلالها program يعمل على جهازك 


اين يكتب الكود بداخل المحرر ؟

الاكواد المكتوبة بلغة الجافا او اي لغة نقوم بكتابتها داخل class ويمكنك ربط مجموعة methods داخل الكلاس و تعمل مع بعضها البعض عند استدعائها ملاحظة : عند استدعاء اي شيئ في الجافا يجب ان تستخدم او تقوم بي إنشاء مكتبة مخصصة ( معينة ) لهذا الشيئ مثل Scanner نستدعي المكتبة المخصصة لة لعدم حدوث مشاكل والمكتبة عبارة عن مجموعة من النصوص وهذة من قواعد الجافا ، اذا كان المحرر الذي تعمل علية بسيط لا يوجد بة مكتبات سوف تجدة لا يقبل اي عملية داخلة ويجب عليك ان تقوم بعمل تنزيل الواجهات المخصصة لكل مكتبة في المحرر ليعمل وهذة المكتبات يمكنك تحميلها مجانا وانصحك بقراءة الجزء الاعلى والذي اقدم لكم فية افضل برامج لكتابة الاكواد ، اذا حدث معك مشكلة او ظهر Error في مشروع الجافا الذي تعمل علية يمكنك ترجمة الكلام ومحاولة حله ليعمل البرنامج في بيئة متكاملة بدون اخطاء 


المتطلبات التي يحتاج ان تكتب في كل كود جافا

يجب ان يحتوي كل كود مكتوب ببرمجة جافا الى مجموعة أدوات معرفة داخل البرنامج لكي يعمل معك بدون اي مشاكل ، ليس الا ان تقم بكتابة الاوامر التالية :

قبل جملة

package ###;

### : هو اسم الباكج الذي قمت بانشاه

ضغط هذا الكود

import java.util.Scanner;

فقط كل ما عليك هو تغيير

GC الى اسم الباكج الذي قمت بانشاه


كود الالة الحاسبة مفتوح المصدر


import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import java.text.DecimalFormat;
 
 
// و بالتالي أصبح إنشاء كائن منه يمثل إنشاء نافذة JFrame يرث من الكلاس Calculator هنا جعلنا الكلاس
public class Main extends JFrame implements ActionListener, KeyListener {
 
    // هنا قمنا بتعريف القائمة و جميع الأزرار التي سنضعها فيها
    JMenuBar menuBar;
    JMenu view, edit, help;
    JCheckBoxMenuItem history;
    JMenuItem copy, paste, copyHistory, clearHistory, keyboardShortcuts, about;
 
    // هنا قمنا بتعريف الحاوية التي سنضع فيها جميع أزرار الآلة الحاسبة و مربع النص
    JPanel panel;
 
    // هنا قمنا بتعريف مربع النص الذي سنضعه في أعلى الحاوية
    JTextField textField;
 
    // هنا قمنا بتعريف جميع الأزرار التي سنضعها في الحاوية
    JButton b1, b2, b3, b4, b5, b6, b7, b8, b9, b0, comma, plus, minus,
            divide, multiple, cos, sin, tan, sqrt, clear, back, equal,
            parentesesLeft, parentesesRight, power, modulo, exponential, pi;
 
    // هنا قمنا بتعريف مربع النص الذي سنخزن فيه جميع العمليات السابقة كلما تم النقر على زر المساواة
    JTextArea historyText;
    JScrollPane historyScroller;
 
    // لإخفاء الأصفار التي لا حاجة إلى ظهورها format سنستخدم الكائن
    DecimalFormat format = new DecimalFormat("0.###############");
 
    // لتحديد نوع خط و حجم الأشياء التي سنضيفها في النافذة font سنستخدم الكائنات
    Font font1 = new Font("Arial", Font.BOLD, 17);
    Font font2 = new Font("Arial", Font.BOLD, 9);
    Font font3 = new Font("Arial", Font.BOLD, 12);
 
 
    // سيتم إستدعاء هذه الدالة في كل مرة قبل إدخال أي رقم, حرف أو رمز لتعديل نص المعادلة بشكل تلقائي عند الحاجة
    // و هي تقوم بمقارنة آخر حرف مدخل في مربع النص مع الشيء الذي سيقوم المستخدم بإدخاله
    private void autoAddOrRemove(String button) {
 
        // lastCharacter إذا لم يكن مربع النص فارغاً سيتم تخزين آخر رقم, رمز أو حرف ظاهر في مربع النص في الكائن
        if (!textField.getText().isEmpty()) {
            Character lastCharacter = textField.getText().charAt(textField.getText().length() - 1);
 
            switch (button) {
 
                // هو أحد الإحتمالات التالية, سيتم إضافة ×, ×0 أو ) بعدهlastCharacter إذا تم النقر على رمز و كان الشيء المخزن في الكائن
                case "symbol":
                    switch (lastCharacter) {
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                        case '8':
                        case '9':
                        case 'e':
                        case 'π':
                            textField.setText(textField.getText() + "×");
                            break;
                        case '.':
                            textField.setText(textField.getText() + "0×");
                            break;
                    }
                    break;
 
                // سيتم إضافة الرمز × بعده ,π أو e هو lastCharacter إذا تم النقر على رقم و كان الشيء المخزن في الكائن
                // عبارة عن 0 لا حاجة له سيتم مسحه فقط lastCharacter و إذا تم النقر على رقم و كان آخر رقم مخزن في الكائن
                case "number":
                    switch (lastCharacter) {
                        case 'e':
                        case 'π':
                            textField.setText(textField.getText() + "×");
                            break;
                        case '0':
                            String str = textField.getText();
                            if ( str.equals("0") ||
                                 str.endsWith("+0") ||
                                 str.endsWith("-0") ||
                                 str.endsWith("×0") ||
                                 str.endsWith("÷0") ||
                                 str.endsWith("%0") ||
                                 str.endsWith("^0") ||
                                 str.endsWith("√0") ||
                                 str.endsWith("(0") ||
                                 str.endsWith("cos0") ||
                                 str.endsWith("sin0") ||
                                 str.endsWith("tan0") )
                                textField.setText(textField.getText().substring(0, textField.getText().length()-1));
                        break;
                    }
                break;
 
                // هو أحد العوامل التالية أو نقطة سيتم مسحه lastCharacter إذا تم النقر على عامل و كان الشيء المخزن في الكائن
                // بهذه الطريقة لن يستطيع المستخدم وضع أكثر من عاملين وراء بعض أو وضع عامل مباشرةً بعد نقطة
                case "operand":
                    switch (lastCharacter) {
                        case '+':
                        case '-':
                        case '×':
                        case '÷':
                        case '%':
                        case '.':
                        textField.setText(textField.getText().substring(0, textField.getText().length()-1));
                        break;
                    }
                break;
 
                // هو أحد الإحتمالات التالية lastCharacter إذا تم النقر على النقطة و كان الشيء المخزن في الكائن
                // سيتم إضافة 0 أو 0× بعدها, أو مسح النقطة لضمان عدم وجود نقطتين وراء بعض
                case "point":
                    switch (lastCharacter) {
                        case '+':
                        case '-':
                        case '×':
                        case '÷':
                        case '%':
                        case '(':
                        case '√':
                        case 'π':
                        case 's':
                        case 'n':
                        case '^':
                            textField.setText(textField.getText() + "0");
                            break;
                        case ')':
                            textField.setText(textField.getText() + "×0");
                            break;
                        case '.':
                            textField.setText(textField.getText().substring(0, textField.getText().length()-1));
                            break;
                    }
                break;
 
            }
        }
    }
 
 
    // double هذه الدالة ترجع ناتج المعادلة المدخلة في مربع النص كـ
    // فعلياً تقوم بتجزئة المعادلة على حسب العوامل و الرموز الموجودة فيها و كل جزئين تم إكتشاف قيمتهما يتحولان إلى جزء واحد
    // و هي تستمر على هذه الحال حتى تصبح كل الأجزاء تساوي رقماً واحداً, و عندها تقوم بإرجاعه
    private double calculate(String str) {
 
        return new Object() {
            int pos = -1, ch;
 
            void nextChar() {
                ch = (++pos < str.length()) ? str.charAt(pos) : -1;
            }
 
            boolean eat(int charToEat) {
                while (ch == ' ') {
                    nextChar();
                }
                if (ch == charToEat) {
                    nextChar();
                    return true;
                }
                return false;
            }
 
            double parse() {
                nextChar();
                double x = parseExpression();
                if (pos < str.length()) {
                    throw new RuntimeException("Unexpected: " + (char) ch);
                }
                return x;
            }
 
            double parseExpression() {
                double x = parseTerm();
                for (;;) {
                    if (eat('+')) {
                        x += parseTerm();
                    }
                    else if (eat('-')) {
                        x -= parseTerm();
                    }
                    else {
                        return x;
                    }
                }
            }
 
            double parseTerm() {
                double x = parseFactor();
                for (;;) {
                    if (eat('×')) {
                        x *= parseFactor();
                    }
                    else if (eat('÷')) {
                        x /= parseFactor();
                    }
                    else if (eat('%')) {
                        x %= parseFactor();
                    }
                    else {
                        return x;
                    }
                }
            }
 
            double parseFactor() {
                if (eat('+')) {
                    return parseFactor();
                }
                if (eat('-')) {
                    return -parseFactor();
                }
                double x;
                int startPos = this.pos;
                if (eat('(')) {
                    x = parseExpression();
                    eat(')');
                }
                else if (eat('e')) {
                    x = Math.E;
                }
                else if (eat('π')) {
                    x = Math.PI;
                }
                else if ((ch >= '0' && ch <= '9') || ch == '.') {
                    while ((ch >= '0' && ch <= '9') || ch == '.') {
                        nextChar();
                    }
                    x = Double.parseDouble(str.substring(startPos, this.pos));
                }
                else if (ch >= 'a' && ch <= 'z' || ch == '√') {
                    while (ch >= 'a' && ch <= 'z' || ch == '√') {
                        nextChar();
                    }
                    String func = str.substring(startPos, this.pos);
                    x = parseFactor();
                    switch (func) {
                        case "√":
                            x = Math.sqrt(x);
                            break;
                        case "sin":
                            x = Math.sin(Math.toRadians(x));
                            break;
                        case "cos":
                            x = Math.cos(Math.toRadians(x));
                            break;
                        case "tan":
                            x = Math.tan(Math.toRadians(x));
                            break;
                        default:
                            throw new RuntimeException("Unknown function: " + func);
                    }
                }
                else {
                    throw new RuntimeException("Unexpected: " + (char) ch);
                }
                if (eat('^')) {
                    x = Math.pow(x, parseFactor());
                }
                return x;
 
            }
 
        }.parse();
    }
 
 
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //   تم تجهيز جميع هذه الدوال للتأكد قبل إدخال أي حرف, رقم أو رمز
    //   ملاحظة سيتم إستدعاء هذه الدوال في حال قام المستخدم بالنقر على الأزرار الموجودة في النافذة أو من لوحة المفاتيح
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
    // عند النقر على الزر 0 سيتم إضافة 0 في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void b0_isClicked(){
        autoAddOrRemove("number");
        textField.setText(textField.getText() + "0");
    }
 
    // عند النقر على الزر 1 سيتم إضافة 1 في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void b1_isClicked(){
        autoAddOrRemove("number");
        textField.setText(textField.getText() + "1");
    }
 
    // عند النقر على الزر 2 سيتم إضافة 2 في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void b2_isClicked(){
        autoAddOrRemove("number");
        textField.setText(textField.getText() + "2");
    }
 
    // عند النقر على الزر 3 سيتم إضافة 3 في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void b3_isClicked(){
        autoAddOrRemove("number");
        textField.setText(textField.getText() + "3");
    }
 
    // عند النقر على الزر 4 سيتم إضافة 4 في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void b4_isClicked(){
        autoAddOrRemove("number");
        textField.setText(textField.getText() + "4");
    }
 
    // عند النقر على الزر 5 سيتم إضافة 5 في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void b5_isClicked(){
        autoAddOrRemove("number");
        textField.setText(textField.getText() + "5");
    }
 
    // عند النقر على الزر 6 سيتم إضافة 6 في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void b6_isClicked(){
        autoAddOrRemove("number");
        textField.setText(textField.getText() + "6");
    }
 
    // عند النقر على الزر 7 سيتم إضافة 7 في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void b7_isClicked(){
        autoAddOrRemove("number");
        textField.setText(textField.getText() + "7");
    }
 
    // عند النقر على الزر 8 سيتم إضافة 8 في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void b8_isClicked(){
        autoAddOrRemove("number");
        textField.setText(textField.getText() + "8");
    }
 
    // عند النقر على الزر 9 سيتم إضافة 9 في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void b9_isClicked(){
        autoAddOrRemove("number");
        textField.setText(textField.getText() + "9");
    }
 
    // في مربع النص مع إضافةالعامل × قبلها إذا دعت الحاجة sin سيتم إضافة الكلمة sin عند النقر على الزر
    private void sin_isClicked(){
        autoAddOrRemove("symbol");
        textField.setText(textField.getText() + "sin");
    }
 
    // في مربع النص مع إضافةالعامل × قبلها إذا دعت الحاجة cos سيتم إضافة الكلمة cos عند النقر على الزر
    private void cos_isClicked(){
        autoAddOrRemove("symbol");
        textField.setText(textField.getText() + "cos");
    }
 
    // في مربع النص مع إضافةالعامل × قبلها إذا دعت الحاجة tan سيتم إضافة الكلمة tan عند النقر على الزر
    private void tan_isClicked(){
        autoAddOrRemove("symbol");
        textField.setText(textField.getText() + "tan");
    }
 
    // عند النقر على الزر √ سيتم إضافة √ في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void sqrt_isClicked(){
        autoAddOrRemove("symbol");
        textField.setText(textField.getText() + "√");
    }
 
    // في مربع النص مع إضافةالعامل × قبله إذا دعت الحاجة e سيتم إضافة e عند النقر على الزر
    private void exponential_isClicked(){
        autoAddOrRemove("symbol");
        textField.setText(textField.getText() + "e");
    }
 
    // في مربع النص مع إضافةالعامل × قبله إذا دعت الحاجة π سيتم إضافة π عند النقر على الزر
    private void pi_isClicked(){
        autoAddOrRemove("symbol");
        textField.setText(textField.getText() + "π");
    }
 
    // عند النقر على الزر + سيتم إضافة + في مربع النص
    private void plus_isClicked(){
        autoAddOrRemove("operand");
        textField.setText(textField.getText() + "+");
    }
 
    // عند النقر على الزر - سيتم إضافة - في مربع النص
    private void minus_isClicked(){
        autoAddOrRemove("operand");
        textField.setText(textField.getText() + "-");
    }
 
    // عند النقر على الزر × سيتم إضافة × في مربع النص
    private void multiple_isClicked(){
        if (!textField.getText().isEmpty()) {
            autoAddOrRemove("operand");
            textField.setText(textField.getText() + "×");
        }
    }
 
    // عند النقر على الزر ÷ سيتم إضافة ÷ في مربع النص
    private void divide_isClicked(){
        if (!textField.getText().isEmpty()) {
            autoAddOrRemove("operand");
            textField.setText(textField.getText() + "÷");
        }
    }
 
    // عند النقر على الزر % سيتم إضافة % في مربع النص
    private void modulo_isClicked(){
        if (!textField.getText().isEmpty()) {
            autoAddOrRemove("operand");
            textField.setText(textField.getText() + "%");
        }
    }
 
    // π أو e, عند النقر على الزر ^ سيتم إضافة ^ في مربع النص في حال كان آخر حرف فيه عبارة عن رقم
    private void power_isClicked(){
        if (textField.getText().matches(".*[0-9eπ)]$"))
            textField.setText(textField.getText() + "^");
    }
 
    // n أو s ,√ ,( عند النقر على الزر ( سيتم إضافة ( في مربع النص في حال لم يكن مربع نص فارغاً و في حال لم يكن آخر حرف فيه عبارة عن
    private void parentesesRight_isClicked(){
        if (textField.getText().matches(".*[^ns√(]$")) {
            int leftParentesesCounter = 0, rightParentesesCounter = 0;
            for(char c: textField.getText().toCharArray()) {
                if( c == '(' )
                    leftParentesesCounter++;
                else if( c == ')' )
                    rightParentesesCounter++;
            }
            if (leftParentesesCounter > rightParentesesCounter)
                textField.setText(textField.getText() + ")");
        }
    }
 
    // عند النقر على الزر ) سيتم إضافة ) في مربع النص مع إضافة العامل × قبله إذا دعت الحاجة
    private void parentesesLeft_isClicked(){
        autoAddOrRemove("symbol");
        textField.setText(textField.getText() + "(");
    }
 
    // عند النقر على زر النقطة ( أي الفاصلة ) سيتم إضافة نقطة في مربع النص مع إضافة 0 قبلها في حال كان مربع النص فارغاً
    private void comma_isClicked(){
        String str = textField.getText();
        if (textField.getText().isEmpty()) {
            textField.setText("0.");
        }
        else {
            int lastPointIndex = str.lastIndexOf(".");
            int lastPlusIndex = str.lastIndexOf("+");
            int lastMinusIndex = str.lastIndexOf("-");
            int lastMultipleIndex = str.lastIndexOf("×");
            int lastDivideIndex = str.lastIndexOf("÷");
            int lastModuloIndex = str.lastIndexOf("%");
 
            if (lastPointIndex <= lastPlusIndex ||
                lastPointIndex <= lastMinusIndex ||
                lastPointIndex <= lastMultipleIndex ||
                lastPointIndex <= lastDivideIndex ||
                lastPointIndex <= lastModuloIndex ) {
                    autoAddOrRemove("point");
                    textField.setText(textField.getText() + ".");
            }
        }
    }
 
    // لتحليل المعادلة التي أدخلها المستخدم ثم عرض الناتج النهائي calculate() عند النقر على زر المساواة = سيتم إستدعاء الدالة
    private void equal_isClicked(){
        if (!textField.getText().isEmpty()) {
            String historyNewText = historyText.getText() + textField.getText() + "\n= ";
            try {
                Double answer = calculate(textField.getText());
                if (answer.isInfinite()) {
                    textField.setText("cannot divide by 0");
                    historyNewText += "cannot divide by 0";
                }
                else if (answer.isNaN()) {
                    textField.setText("Error");
                    historyNewText += "Error";
                }
                else {
                    textField.setText(format.format(answer));
                    historyNewText += format.format(answer);
                }
            }
            catch (Exception ex) {
                textField.setText("Error");
                historyNewText += "Error";
            }
            historyText.setText(historyNewText + "\n\n");
        }
    }
 
    // عند النقر على الزر ← سيتم مسح رقم, رمز أو كلمة واحدة من مربع النص أو مسح أي خطأ ظاهر
    private void back_isClicked(){
        String temp = textField.getText();
        if (temp.equals("Error") || temp.equals("cannot divide by 0")) {
            textField.setText("");
        }
        else if (!temp.isEmpty()) {
            temp = textField.getText().substring(0, textField.getText().length() - 1);
            if (temp.length() >= 2) {
                switch (temp.substring(temp.length() - 2)) {
                    case "co":
                    case "si":
                    case "ta":
                        temp = temp.substring(0, temp.length() - 2);
                        break;
                }
            }
            textField.setText(temp);
        }
    }
 
    // سيتم مسح كل شيء ظاهر و تصفير جميع القيم المخزنة للبدء من جديد C عند النقر على الزر
    private void clear_isClicked(){
        textField.setText("");
    }
 
 
    // هذه الدالة تقوم ببناء كل شيء في البرنامج و تحدد ماذا سيحدث عندما يتفاعل المستخدم مع محتوى النافذة
    private void createAndShowGUI() {
 
        // لجعل النافذة محتوى االنافذة يظهر بشكل أجمل Nimbus إلى الـ UIManager هنا قمنا بتغير الـ
        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        }
        catch (Exception e) { }
 
        // هنا قمنا بإنشاء شريط القوائم, القوائم و العناصر التي بداخلهم
        menuBar = new JMenuBar();
        view = new JMenu(" View ");
        edit = new JMenu(" Edit ");
        help = new JMenu(" Help ");
        history = new JCheckBoxMenuItem("History");
        copy = new JMenuItem("Copy");
        paste = new JMenuItem("Paste");
        copyHistory = new JMenuItem("Copy History");
        clearHistory = new JMenuItem("Clear History");
        keyboardShortcuts = new JMenuItem("Keyboard Shortcuts");
        about = new JMenuItem("About");
 
        // هنا قمنا بإضافة كل عنصر داخل القائمة المناسبة له
        menuBar.add(view);
        menuBar.add(edit);
        menuBar.add(help);
        view.add(history);
        edit.add(copy);
        edit.add(paste);
        edit.addSeparator();
        edit.add(copyHistory);
        edit.add(clearHistory);
        help.add(keyboardShortcuts);
        help.add(about);
 
        // و محتوها panel هنا قمنا بإنشاء محتوى الحاوية
        panel = new JPanel(null);
        b0 = new JButton("0");
        b1 = new JButton("1");
        b2 = new JButton("2");
        b3 = new JButton("3");
        b4 = new JButton("4");
        b5 = new JButton("5");
        b6 = new JButton("6");
        b7 = new JButton("7");
        b8 = new JButton("8");
        b9 = new JButton("9");
        comma = new JButton(".");
        plus = new JButton("+");
        minus = new JButton("-");
        multiple = new JButton("×");
        divide = new JButton("÷");
        cos = new JButton("cos");
        sin = new JButton("sin");
        tan = new JButton("tan");
        sqrt = new JButton("√");
        power = new JButton("^");
        modulo = new JButton("%");
        exponential = new JButton("e");
        pi = new JButton("π");
        parentesesLeft = new JButton("(");
        parentesesRight = new JButton(")");
        equal = new JButton("=");
        clear = new JButton("C");
        back = new JButton("←");
        textField = new JTextField("");
 
        // عند الحاجة scroll bar لإظهار historyScroller هنا قمنا بإنشاء مربع النص الذي سنعرض فيه العمليات و النتائج السابقة و وضعنها بداخل الكائن
        historyText = new JTextArea();
        historyScroller = new JScrollPane(historyText);
 
        // هنا قمنا بتحديد حجم و موقع كل شيء أضفناه في النافذة
        panel.setBounds(0, 0, 256, 358);
        historyScroller.setBounds(256, 0, 258, 328);
        textField.setBounds(11, 11, 234, 60);
        cos.setBounds(10, 80, 45, 38);
        sin.setBounds(58, 80, 45, 38);
        tan.setBounds(106, 80, 45, 38);
        back.setBounds(154, 80, 45, 38);
        clear.setBounds(202, 80, 45, 38);
        pi.setBounds(10, 121, 45, 38);
        exponential.setBounds(58, 121, 45, 38);
        modulo.setBounds(106, 121, 45, 38);
        parentesesLeft.setBounds(154, 121, 45, 38);
        parentesesRight.setBounds(202, 121, 45, 38);
        b7.setBounds(10, 161, 45, 38);
        b8.setBounds(58, 161, 45, 38);
        b9.setBounds(106, 161, 45, 38);
        plus.setBounds(154, 161, 45, 38);
        power.setBounds(202, 161, 45, 38);
        b4.setBounds(10, 201, 45, 38);
        b5.setBounds(58, 201, 45, 38);
        b6.setBounds(106, 201, 45, 38);
        minus.setBounds(154, 201, 45, 38);
        sqrt.setBounds(202, 201, 45, 38);
        b1.setBounds(10, 241, 45, 38);
        b2.setBounds(58, 241, 45, 38);
        b3.setBounds(106, 241, 45, 38);
        multiple.setBounds(154, 241, 45, 38);
        equal.setBounds(202, 241, 45, 78);
        b0.setBounds(10, 281, 93, 38);
        comma.setBounds(106, 281, 45, 38);
        divide.setBounds(154, 281, 45, 38);
 
        // هنا قمنا بتحديد حجم و نوع خط كل شيء أضفناه في النافذة
        view.setFont(font3);
        edit.setFont(font3);
        help.setFont(font3);
        history.setFont(font3);
        copy.setFont(font3);
        paste.setFont(font3);
        copyHistory.setFont(font3);
        clearHistory.setFont(font3);
        about.setFont(font3);
        keyboardShortcuts.setFont(font3);
        b0.setFont(font1);
        b1.setFont(font1);
        b2.setFont(font1);
        b3.setFont(font1);
        b4.setFont(font1);
        b5.setFont(font1);
        b6.setFont(font1);
        b7.setFont(font1);
        b8.setFont(font1);
        b9.setFont(font1);
        comma.setFont(font1);
        equal.setFont(font1);
        plus.setFont(font1);
        minus.setFont(font1);
        multiple.setFont(font1);
        divide.setFont(font1);
        cos.setFont(font2);
        sin.setFont(font2);
        tan.setFont(font2);
        sqrt.setFont(font1);
        power.setFont(font1);
        modulo.setFont(font1);
        exponential.setFont(font1);
        pi.setFont(font1);
        parentesesLeft.setFont(font1);
        parentesesRight.setFont(font1);
        clear.setFont(font1);
        back.setFont(font1);
 
        // هنا قمنا بتحديد حجم و نوع خط النص الذي سيتم إدخاله في مربع النص بالإضافة إلى جعل النص يبدأ بالظهور من اليمين إلى اليسار
        textField.setHorizontalAlignment(JTextField.RIGHT);
        textField.setFont(new Font("Monospaced", Font.BOLD, 19));
 
        // هنا قمنا بتحديد حجم و نوع خط النص الذي سيتم إدخاله في مربع النص الذي سيحتوي على العمليات و النتائج السابقة
        historyText.setFont(new Font("Arial", Font.BOLD, 16));
 
        // هنا قمنا بتحديد لون خط كل شيء سنضيفه في النافذة
        b0.setForeground(Color.white);
        b1.setForeground(Color.white);
        b2.setForeground(Color.white);
        b3.setForeground(Color.white);
        b4.setForeground(Color.white);
        b5.setForeground(Color.white);
        b6.setForeground(Color.white);
        b7.setForeground(Color.white);
        b8.setForeground(Color.white);
        b9.setForeground(Color.white);
        comma.setForeground(Color.white);
        equal.setForeground(Color.white);
        plus.setForeground(Color.white);
        minus.setForeground(Color.white);
        multiple.setForeground(Color.white);
        divide.setForeground(Color.white);
        cos.setForeground(Color.white);
        sin.setForeground(Color.white);
        tan.setForeground(Color.white);
        sqrt.setForeground(Color.white);
        power.setForeground(Color.white);
        modulo.setForeground(Color.white);
        exponential.setForeground(Color.white);
        pi.setForeground(Color.white);
        parentesesLeft.setForeground(Color.white);
        parentesesRight.setForeground(Color.white);
        clear.setForeground(Color.white);
        back.setForeground(Color.white);
 
        // هنا قمنا بتحديد لون خلفية كل شيء سنضيفه في النافذة
        textField.setBackground(Color.lightGray);
        b0.setBackground(Color.darkGray);
        b1.setBackground(Color.darkGray);
        b2.setBackground(Color.darkGray);
        b3.setBackground(Color.darkGray);
        b4.setBackground(Color.darkGray);
        b5.setBackground(Color.darkGray);
        b6.setBackground(Color.darkGray);
        b7.setBackground(Color.darkGray);
        b8.setBackground(Color.darkGray);
        b9.setBackground(Color.darkGray);
        comma.setBackground(Color.darkGray);
        plus.setBackground(Color.black);
        minus.setBackground(Color.black);
        multiple.setBackground(Color.black);
        divide.setBackground(Color.black);
        cos.setBackground(Color.black);
        sin.setBackground(Color.black);
        tan.setBackground(Color.black);
        sqrt.setBackground(Color.black);
        power.setBackground(Color.black);
        modulo.setBackground(Color.black);
        exponential.setBackground(Color.black);
        pi.setBackground(Color.black);
        parentesesLeft.setBackground(Color.black);
        parentesesRight.setBackground(Color.black);
        equal.setBackground(Color.black);
        clear.setBackground(new Color(223, 1, 1));
        back.setBackground(new Color(255, 128, 0));
        panel.setBackground(Color.black);
        historyText.setBackground(Color.lightGray);
        getContentPane().setBackground(Color.black);
 
        // هنا قلنا أنه لن يتم البقاء فوق أي زر أو نص بعد النقر عليه حتى يظل المستخدم قادراً على إستخدام لوحة المفاتيح
        textField.setFocusable(false);
        historyText.setFocusable(false);
        b0.setFocusable(false);
        b1.setFocusable(false);
        b2.setFocusable(false);
        b3.setFocusable(false);
        b4.setFocusable(false);
        b5.setFocusable(false);
        b6.setFocusable(false);
        b7.setFocusable(false);
        b8.setFocusable(false);
        b9.setFocusable(false);
        comma.setFocusable(false);
        plus.setFocusable(false);
        minus.setFocusable(false);
        multiple.setFocusable(false);
        divide.setFocusable(false);
        cos.setFocusable(false);
        sin.setFocusable(false);
        tan.setFocusable(false);
        sqrt.setFocusable(false);
        power.setFocusable(false);
        modulo.setFocusable(false);
        exponential.setFocusable(false);
        pi.setFocusable(false);
        parentesesLeft.setFocusable(false);
        parentesesRight.setFocusable(false);
        equal.setFocusable(false);
        clear.setFocusable(false);
        back.setFocusable(false);
 
        // هنا قمنا بإضافة جميع الأزرار التي قمنا بتعريفها و تحديد خصائصها في الحاوية
        panel.add(b0);
        panel.add(b1);
        panel.add(b2);
        panel.add(b3);
        panel.add(b4);
        panel.add(b5);
        panel.add(b6);
        panel.add(b7);
        panel.add(b8);
        panel.add(b9);
        panel.add(comma);
        panel.add(equal);
        panel.add(plus);
        panel.add(multiple);
        panel.add(minus);
        panel.add(divide);
        panel.add(cos);
        panel.add(sin);
        panel.add(tan);
        panel.add(sqrt);
        panel.add(power);
        panel.add(modulo);
        panel.add(exponential);
        panel.add(pi);
        panel.add(parentesesRight);
        panel.add(parentesesLeft);
        panel.add(clear);
        panel.add(back);
        panel.add(textField);
 
        // حتى يتم إستدعاءها عند النقر على أي زر موجود في النافذة actionPerformed() هنا قمنا بربط بجميع أزرار الحاوية و القوائم بالدالة
        history.addActionListener(this);
        copy.addActionListener(this);
        paste.addActionListener(this);
        copyHistory.addActionListener(this);
        clearHistory.addActionListener(this);
        keyboardShortcuts.addActionListener(this);
        about.addActionListener(this);
        b0.addActionListener(this);
        b1.addActionListener(this);
        b2.addActionListener(this);
        b3.addActionListener(this);
        b4.addActionListener(this);
        b5.addActionListener(this);
        b6.addActionListener(this);
        b7.addActionListener(this);
        b8.addActionListener(this);
        b9.addActionListener(this);
        comma.addActionListener(this);
        exponential.addActionListener(this);
        pi.addActionListener(this);
        cos.addActionListener(this);
        sin.addActionListener(this);
        tan.addActionListener(this);
        sqrt.addActionListener(this);
        power.addActionListener(this);
        modulo.addActionListener(this);
        parentesesLeft.addActionListener(this);
        parentesesRight.addActionListener(this);
        plus.addActionListener(this);
        multiple.addActionListener(this);
        divide.addActionListener(this);
        minus.addActionListener(this);
        equal.addActionListener(this);
        clear.addActionListener(this);
        back.addActionListener(this);
 
        // هنا جعلنا النافذة تتلقى الأحرف التي يدخلها المستخدم من لوحة المفاتيح
        // e و يمرر لها الحرف الذي تم النقر عليه مكان الباراميتر keyPressed(KeyEvent e) هنا عند إدخال أي حرف سيتم إستدعاء الدالة
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
 
        // هنا أضفنا شريط القوائم, الحاوية, و مربع النص الذي يخزن العمليات السابقة في النافذة
        add(panel);
        add(historyScroller);
        setJMenuBar(menuBar);
 
        // هنا قمنا بتحديد بعض خصائص النافذة و جعلناها مرئية
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Scientific Calculator");
        setSize(262, 380);
        setLocationRelativeTo(null);
        setResizable(false);
        setLayout(null);
        setVisible(true);
    }
 
 
    // هنا ربطنا الدوال التي قمنا بتعريفها سابقاً بجميع الأزرار الموجودة في النافذة
    // بكل بساطة, الزر الذي يتم النقر عليه سيقوم بتنفيذ الدالة التي صممت لأجله
    // في الأخير قمنا بتعريف ما يحدث عند النقر على أي زر موجود في شريط القوائم
    @Override
    public void actionPerformed(ActionEvent e) {
 
        if (e.getSource() == b0)
            b0_isClicked();
 
        else if (e.getSource() == b1)
            b1_isClicked();
 
        else if (e.getSource() == b2)
            b2_isClicked();
 
        else if (e.getSource() == b3)
            b3_isClicked();
 
        else if (e.getSource() == b4)
            b4_isClicked();
 
        else if (e.getSource() == b5)
            b5_isClicked();
 
        else if (e.getSource() == b6)
            b6_isClicked();
 
        else if (e.getSource() == b7)
            b7_isClicked();
 
        else if (e.getSource() == b8)
            b8_isClicked();
 
        else if (e.getSource() == b9)
            b9_isClicked();
 
        else if (e.getSource() == sin)
            sin_isClicked();
 
        else if (e.getSource() == cos)
            cos_isClicked();
 
        else if (e.getSource() == tan)
            tan_isClicked();
 
        else if (e.getSource() == sqrt)
            sqrt_isClicked();
 
        else if (e.getSource() == exponential)
            exponential_isClicked();
 
        else if (e.getSource() == pi)
            pi_isClicked();
 
        else if (e.getSource() == plus)
            plus_isClicked();
 
        else if (e.getSource() == minus)
            minus_isClicked();
 
        else if (e.getSource() == multiple)
            multiple_isClicked();
 
        else if (e.getSource() == divide)
            divide_isClicked();
 
        else if (e.getSource() == modulo)
            modulo_isClicked();
 
        else if (e.getSource() == power)
            power_isClicked();
 
        else if (e.getSource() == parentesesRight)
            parentesesRight_isClicked();
 
        else if (e.getSource() == parentesesLeft)
            parentesesLeft_isClicked();
 
        else if (e.getSource() == comma)
            comma_isClicked();
 
        else if (e.getSource() == equal)
            equal_isClicked();
 
        else if (e.getSource() == back)
            back_isClicked();
 
        else if (e.getSource() == clear)
            clear_isClicked();
 
        // من شريط القوائم سيتم تكبير حجم النافذة لإظهاره history إذا تم تفعيل الـ
        else if (e.getSource() == history)
        {
            if(history.isSelected())
                this.setSize(520, 380);
            else
                this.setSize(262, 380);
        }
 
        // الموجود في شريط القوائم سيتم نسخ المعادلة المدخلة في مربع النص copy عند النقر على الزر
        else if (e.getSource() == copy)
        {
            textField.selectAll();
            textField.copy();
            textField.setCaretPosition(textField.getText().length());
        }
 
        // الموجود في شريط القوائم سيتم لصق أي نص تم نسخه سابقاً في آخر مربع النص paste عند النقر على الزر
        else if (e.getSource() == paste)
            textField.paste();
 
        // الموجود في شريط القوائم سيتم نسخ جميع المعادلات و الإجابات المخزنة سابقاً copyHistory عند النقر على الزر
        else if (e.getSource() == copyHistory)
        {
            historyText.selectAll();
            historyText.copy();
            textField.setCaretPosition(textField.getText().length());
        }
 
        // الموجود في شريط القوائم سيتم مسح جميع المعادلات و الإجابات المخزنة سابقاً clearHistory عند النقر على الزر
        else if (e.getSource() == clearHistory)
            historyText.setText("");
 
        // الموجود في شريط القوائم سيتم إظهار نافذة منبثقة تحتوي على إرشادات keyboardShortcuts عند النقر على الزر
        else if (e.getSource() == keyboardShortcuts)
        {
            String str = "<html>"
                        + "<ul>"
                        + "<li>Press <b>v</b> to add <b>√</b>.</li>"
                        + "<li>Press <b>p</b> to add <b>π</b>.</li>"
                        + "<li>Press <b>c</b> to add <b>cos</b>.</li>"
                        + "<li>Press <b>s</b> to add <b>sin</b>.</li>"
                        + "<li>Press <b>t</b> to add <b>tan</b>.</li>"
                        + "<li>Press <b>=</b> or <b>Enter</b> to get the result</li>"
                        + "<li>Press <b>BackSpace</b> to clear last character entered.</li>"
                        + "<li>Press <b>Delete</b> to clear all characters entered.</li>"
                        + "</ul>"
                        + "<html>";
 
            JOptionPane.showMessageDialog(getContentPane(), str, "Keyboard Shortcuts", JOptionPane.PLAIN_MESSAGE);
        }
 
        // الموجود في شريط القوائم سيتم إظهار نافذة منبثقة فيها معلومات حول البرنامج about عند النقر على الزر
        else if (e.getSource() == about)
        {
            String str = "<html>"
                        + "<big>Scientific Calculator</big><br><br>"
                        + "<p>Prepared by <b>Mhamad Harmush</b><br><br>"
                        + "If you have any comments, ideas.. just let know<br><br>"
                        + "email:   mhamad.harmush@gmail.com<br>"
                        + "twitter & facebook:   @MhamadHarmush<br><br>"
                        + "<u>Note</u><br>"
                        + "I used JDK 1.8 to compile the source code.<br><br><br>"
                        + "<p><i>© Copyright 2017 harmash.com - All Rights Reserved</i></p>"
                        + "<html>";
 
            JOptionPane.showMessageDialog(getContentPane(), str, "About", JOptionPane.PLAIN_MESSAGE);
        }
 
    }
 
 
    //keyPressed(KeyEvent e) عند الضغط على أي حرف من لوحة المفاتيح سيتم إستدعاء الدالة
    // e و يمرر لها الحرف الذي تم النقر عليه مكان الباراميتر
    // لاحظ أنه على أساس الحرف المدخل سيتم إستدعاء الدالة المناسبة و التي بدورها ستكتبه في مربع النص
    @Override
    public void keyPressed(KeyEvent e) {
 
        switch (e.getKeyChar()) {
            case '0':
            case '٠':
                b0_isClicked();
                break;
 
            case '1':
            case '١':
                b1_isClicked();
                break;
 
            case '2':
            case '٢':
                b2_isClicked();
                break;
 
            case '3':
            case '٣':
                b3_isClicked();
                break;
 
            case '4':
            case '٤':
                b4_isClicked();
                break;
 
            case '5':
            case '٥':
                b5_isClicked();
                break;
 
            case '6':
            case '٦':
                b6_isClicked();
                break;
 
            case '7':
            case '٧':
                b7_isClicked();
                break;
 
            case '8':
            case '٨':
                b8_isClicked();
                break;
 
            case '9':
            case '٩':
                b9_isClicked();
                break;
 
            case 's':
            case 'س':
                sin_isClicked();
                break;
 
            case 'c':
            case 'ؤ':
                cos_isClicked();
                break;
 
            case 't':
            case 'ف':
                tan_isClicked();
                break;
 
            case 'v':
            case 'ر':
                sqrt_isClicked();
                break;
 
            case 'e':
            case 'ث':
                exponential_isClicked();
                break;
 
            case 'p':
            case 'ح':
                pi_isClicked();
                break;
 
            case '+':
                plus_isClicked();
                break;
 
            case '-':
                minus_isClicked();
                break;
 
            case '*':
            case '×':
                multiple_isClicked();
                break;
 
            case '/':
            case '÷':
                divide_isClicked();
                break;
 
            case '%':
                modulo_isClicked();
                break;
 
            case '^':
                power_isClicked();
                break;
 
            case ')':
                parentesesRight_isClicked();
                break;
 
            case '(':
                parentesesLeft_isClicked();
                break;
 
            case '.':
                comma_isClicked();
                break;
 
            case '=':
            case '\n':
                equal_isClicked();
                break;
 
        }
 
        if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE)
            back_isClicked();
 
        else if (e.getKeyCode() == KeyEvent.VK_DELETE)
            clear_isClicked();
 
    }
 
 
    // Override لذلك فعلنا لها KeyListener هذه الدالة موجودة في الإنترفيس
    @Override
    public void keyTyped(KeyEvent e) { }
 
 
    // Override لذلك فعلنا لها KeyListener هذه الدالة موجودة في الإنترفيس
    @Override
    public void keyReleased(KeyEvent e) { }
 
 
    // فقط createAndShowGUI() سيقوم الكونستركتور بإستدعاء الدالة Main عند إنشاء كائن من الكلاس
    public Main() {
        createAndShowGUI();
    }
 
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                // التي ستنشئ النافذة createAndShowGUI() و بالتالي سيتم إستدعاء الدالة Main هنا قمنا بإنشاء كائن من الكلاس
                new Main();
            }
        });
    }
 
}




تعليقات