السبت، 23 أكتوبر 2010

برنامج قاموس لهواتف Symbian

السلام عليكم ورحمه الله...
اليوم تم اطلاق النسخه الأول من برنامج قاموس لنظام Symbian التي تعمل عليها معظم هواتف Nokia. طبعا المشروع مفتوح المصدر وهو نتيجه ثمره تعاون بيني وبين أخي محمد هويدي حيث أنه هو من أسس المشروع وقام بعمل نسخه Linux ثم سمح لي مشكورا بالدخول معه في المشروع، واليوم نحن نقوم باطلاق النسختين التاليتين وهما تخصا نظامي Symbian  و Windows.

المشروع مفتوح المصدر وله صفحه على موقع Google Code

تنزيل البرنامج على هواتف Symbian



ما هي الهواتف التي يمكنها تشغيل البرنامج
البرنامج يعتمد على Qt وبالتالي يجب أن يعمل الهاتف على نظام Symbian S60 3rd Edition FP1 او ما يليه أو نظام S60 5th Edition. حسنا كيف لي ان اعرف ما هو نظام هاتفي؟ اذهب الى موقع نوكيا وتأكد من النظام بنفسك.


هناك نسختان للتتحميل الأول بدون Nokia Smart Installer والثانيه معه. يمكنك استخدام أحدى الطريقتين.





الطريقه الأولى:
وهي الطريقه التي ينصح باستعمالها وهي تحميل نسخه القاموس التي تحمل معها Nokia Smart Installer. الهدف من هذا البرنامج انه لكي تعمل برامج Qt فانه يجب توافر مكتبات Qt على الهاتف، وهذا البرنامج يقوم بالتأكد من وجودها فان لم يجدها سوف يقوم بتحميلها من الانترنت، لذلك فانك تحتاج الى اتصال بالشبكه حتى تتمكن من تنصيب القاموس بشكل صحيح، أما اذا كان هاتفك يحتوي على مكتبات Qt فانه سيقوم بتصيب البرنامج مباشره. مكتبه Qt يتم تنزيلها مره واحده فقط على الهاتف ثم تستخدمها كل التطبيقات دون الحاجه لاعاده تنزيلها من جديد في كل مره.

الطريقه الثانيه:
لا ينصح باستخدامها وهي تخص المستخدمين المتقدمين ومن لا يريد دفع مبلغ طائل لتحميل مكتبه Qt. اذا كان هاتفك لا يحتوي على Qt فقم بتنزيل المكتبه من هنا ثم قم بنقلها الى هاتفك وتنصيبها بعدها قم بتحميل نسخه القاموس التي لا تحتوي على Nokia Smart Installer من هنا

تنزيل البرنامج على Windows
قم بتحميل النسخه المخصصه ل Windows ثم قم بفك ضغطها وابدأ العمل   

أرجوا ممن يستطيع المساعده في أحد هذه النقاط ان لا يتردد
1. تجريب البرنامج وطلاعنا على أي أخطاء أو مميزات تودونها، هنا أو على صفحه البرنامج في Google Code
2. قاعده البيانات المتوفره فقيره وبها بعض الأخطاء، من يملك قاعده بيانات أفضل يكون من حقنا استخدامها أن يطلعنا عليها.
2. القاموس يحتوي على قاعده للترجمه من الانجليزيه الى العربيه ونحتاج الى قاعده بيانات اخرى للترجمه من العربيه الى الانجليزيه.
4. نحتاج الى مصمم يساعدنا في تصميم icon للبرنامج, ويا حبذا لو أن أحد المصممين يقترح علينا تصميم بسيط فيمكننا عمل ( CSS ( Cascade Style sheet للبرنامج مثل مواقع الويب, هذا التصميم سيضاف لنسخه الهاتف فقط لانها لا تبدو جميله بعكس نسخه Linux و Windows
5. من يملك جهاز يعمل على نظام MeeGo أو Maemo ويستطيع مساعدتنا في تجربه البرنامج، للأسف أنا لم أقم بتجهيزها لهذا النظام ولكن ان وجد من يستطيع تجربتها على جهازه فيمكنني المحاوله.

في انتظار أرائكم ومقترحاتكم..

الجمعة، 22 أكتوبر 2010

ماذا أحتاج لكي أبدأ البرمجة باستخدام Qt

حسنا لقد تأخرت في اكمال مواضيع Qt بما فيه الكفايه اليوم سأعود لها ان شاء الله وستكون أول مهمه هي تحديث المقال السابق الذي كان يحمل نفس العنوان حيث أن معلوماته أصبحت قديمه للأسف. الأمور تسير مع Qt بسرعه فائقه.


الأدوات التي أحتاجها
1. Nokia Ovi Suite : فائده البرنامج هذا هو نقل التطبيقات وتنزيلها على هاتفك ال Symbian بعد الانتهاء من برمجتها.
2. Nokia Qt SDK : وهي بيئه تطوير متكامله لتطوير برامج Qt ل Symbian وباقي المنصات، ما يميز هذه البيئه سهولتها عن الأمور المعقده التي كنا نستخدمها سابقا لتجهيز بيئه التطوير كما أنها تحتوي على كل ما تحتاجه من الأف الى الياء.

تجهيز الهاتف
بعد أن قمت بتنزيل Nokia Qt SDK الأن يجب تجهيز الهاتف لكي يستقبل برامج Qt كالتالي:
1. يجب تنصيب Qt Runtime على الهاتف

2. تنصيب برنامج ال TRK لتمكين الهاتف من عمل On Device Debugging كالتالي:
ولكن توجد أكثر من نسخه كيف يمكنني معرفه النسخه التي تلائم الهاتف, فمثلا على هاتف Nokia N97 يمكنك التوجه الى موقع نوكيا وفحص مواصفات الجهاز وعندها ستشاهد التالي:
طبعا واضح ان الهاتف يعمل على نظام S60 5th Edition وبالتالي يجب أخذ النسخه المناسبه لهذا النظام.

الان أنت جاهز لعمل تطبيقات Qt لهواتف Symbian.

الأحد، 10 أكتوبر 2010

نوكيا تقوم بعقد دوره تدريبيه ل Qt في الأردن و لبنان

سوف تقوم شركه نوكيا بعقد دوره تدريبيه عن Qt في كل من الأردن ولبنان, مده الدوره يومان سوف يتم تعريف المشتركين بالأمور الأساسيه في Qt. لا تحتاج الى معرفه مسبقه بها، بل الى معرفه في لغه C++ فقط.

المواضيع التي سيتم تناولها في الدوره

الوم الأول
Time: 9:00 - 17:00

Welcome and Forum Nokia Intro
Intro to Forum Nokia Services
Lowering the barriers to publishers
Marketing your apps
Developers meet Businesses

Qt Overview and Introduction
What is Qt? Why use Qt?
Qt Status, Qt in Mobile Devices
Changes in Qt 4.7
Qt and the Nokia N8 Device

Qt Essentials
Qt Modules
Tools and Build Chain

First Qt Application
Qt Projects
QObject
Parent/Child Relationship
Basic QWidgets
Layout managers

Nokia Qt SDK
Working with Qt Projects in Mobile Platforms
Multi-Platform Development with Nokia Qt SDK

Meta-Object System
Meta-Objects
Signals and Slots

Creating Simple UIs with Nokia Qt SDK
Qt Creator and Form Designer
Using Generated UI code
QActions
Existing Dialog Classes

Event Handling Basics
Events in Qt
Timers



اليوم الثاني
Time: 9:00 - 17:00

Custom Widgets – Painting System
Paint Events
QPainter and QPaintDevices
Overview on QGraphicsView

Creating Outstanding User Interfaces
Animations Framework and Effects
Graphics View and Custom UI
Qt Gesture Framework and Multi-touch UI in N8

Porting Mobile Applications to Qt
Comparing Android and Qt Based Development
Comparing iPhone and Qt Based Development
Approaches When Code Re-Use Is Not Possible
Re-Using Native Platform Code
Approaches on Wrapping Symbian Services

New Qt APIs – Qt Mobility APIs
Overview on Qt Mobility APIs
API Walkthrough
Contacts, Location, Messaging, Multimedia, Sensors

للتسجيل من الأردن
للتسجيل من لبنان

السبت، 31 يوليو 2010

التحريك

مقدمة
في هذا الدرس سوف نتعرف على أسس التحريك وهي نفس الأسس التي تعتمد عليها جميع الألعاب حتى ألعاب الحاسوب تعتمد على طرق مشابهة للمبادئ المطروحة في هذا الدرس.
ملاحظة قبل المتابعة
هذا الدرس يعتمد بشكل كلي على ال Multi-Threading في جافا لذلك يجب عليك الاحاطه في هذا الموضوع. يمكنك الاطلاع على هذا الدرس الممتاز في منتيدات الفريق العربي.


public class AnimationCanvas extends Canvas implements Runnable {

    protected void showNotify() {
        Random r = new Random( System.currentTimeMillis() );
        x = r.nextInt( getWidth() );
        y = r.nextInt( getHeight() );
        dirX = 4;
        dirY = 4;

    }

    protected void paint(Graphics g) {
        g.setColor( 0x0 );
        g.fillRect( 0, 0, getWidth(), getHeight() );

        g.setColor( 0xFFFFFF );
        g.fillRect( x, y, WIDTH, HEIGHT );

    }

    public void run() {
        while( !quit ) {
            x += dirX;
            y += dirY;

            if( x <= 0 || x + WIDTH >= getWidth() ) {
                dirX *= -1;

            }

            if( y <= 0 || y + HEIGHT >= getHeight() ) {
                dirY *= -1;
                
            }
            repaint();
            serviceRepaints();

            try {
                Thread.sleep( 50 );

            } catch( Exception ex ) {
                ex.printStackTrace();

            }

        }

    }

    public void start() {
        Thread t = new Thread( this );
        t.start();

    }

    public void stop() {
        quit = true;

    }
    private boolean quit = false;
    private int x;
    private int y;

    private int dirX;
    private int dirY;
    private final int WIDTH = 10;
    private final int HEIGHT = 10;
}

في السطور ما بين 3 و 9 قمنا بأخذ قيمه عشوائيه لكل من الاحداثيات السينية والصادية. الاحداثايات السينية محصورة ما بين 0 و عرض شاشه الهاتف أما الاحداثيات الصادية فهي محصورة ما بين 0 و ارتفاع الشاشة. ثم قمنا بتجهيز متجهات الحركة على المحورين بقيم ابتدائية تساوي 4 لكل منهما.


لاحظ أن الفئة تقوم بعمل implements لل Runnable أي أنها يمكن أن تكون قيمه مرسلة لخيط معين لتنفيذها في ذلك الخيط وهو ما تم عمله فعلا في ال start method ما بين السطور 50 و 54.

في ال run method نقوم بالتحرك خطوه على كل من المحاور ثم نقوم بفحص القيم الجديدة للاحداثايت فاذا تجاوزت أحدها الشاشه نقوم بعكس اتجاه الحركه. هذه ال method عالقه في حلقه تكراريه لا نهائيه لن تنتهي الا بتغيير قيمه المتغير quit الى false.

في كل حلقه نقوم باعاده رسم المربع في المكان الجديد ثم نجبر الخيط على الانتظار لمده 50 milliseconds.

الان نقوم بعرض هذه الشاشة على شاشه الهاتف كالتالي:
public class AnimationMidlet extends MIDlet implements CommandListener {
    AnimationCanvas animator;
    
    public void startApp() {
        animator = new AnimationCanvas();
        animator.start();
        Display.getDisplay(this).setCurrent( animator );
        animator.addCommand( new Command( "Exit", Command.EXIT, 0 ) );
        animator.setCommandListener( this );

    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    public void commandAction(Command c, Displayable d) {
        animator.stop();
        destroyApp(true);
        notifyDestroyed();
    }
}

مقدمة في انشاء واجهة مستخدم منخفضة المستوى - الجزء الثالث

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

كيفيه انشاء خط لاستخدامه في الرسم
Font f = Font.getFont(int face, int style, int size);
أنواع الخطوط
  • FACE_SYSTEM
  • FACE_MONOSPACE
  • FACE_PROPORTIONAL
 تنسيق الخطوط
  • STYLE_PLAIN
  • STYLE_BOLD
  • STYLE_ITALIC
  • STYLE_UNDERLINED
حجم الخط
  • SIZE_SMALL
  • SIZE_MEDIUM
  • SIZE_LARGE
الصور
يتم رسم الصور عن طريق ال drawImage method الموجوده في الفئه Graphics.
public void drawImage(Image img,
                      int x,
                      int y,
                      int anchor)
محاذاه الصوره يشبه الى حد كبير محاذاه النصوص التي تم شرحها سابقا.

مجال الرسم
يمكن تحديد مجال للرسم بحيث أن لأي شيء خارج هذا المجال فانه لن يرسم باستخدام ال setClip method الموجوده في الفئه Graphics.
public void setClip(int x,
                    int y,
                    int width,
                    int height)
استقبال الأحادث في ال Canvas
عند الضغط على أزرار الهاتف فان مجموعه من ال methods سوف يتم تنفيذها لكي تعلمك بحدوث الحدث كما سترسل لك بعض المعلومات عن الزر الذي تم الضغط عليه.
protected void keyPressed(int keyCode)
protected void keyReleased(int keyCode)
Protected void keyRepeated(int keyCode)

Game Actions
يمكن معرفه ال Game Action المقابل لكل keycode تم استقباله في أحد ال methods السابقه عن طريق
int gameAction = getGameAction(keyCode);
أنواع ال Game Actions التي تدعمها JME هي كالتالي:
  • UP
  • DOWN
  • LEFT
  • RIGHT
  • FIRE
  • GAME_A
  • GAME_B
  • GAME_C
  • GAME_D
ال Game Actions يمكن أت ترتبط بأزرار مختلفه حسب نوع الجهاز وهي بذلك تريح المبرمج من عناء اختلاف الأجهزه فمثلا زر ال Fire في هواتف Nokia عاده هو الزر الموجود في منتصف لوحه التحرك أو الزر الذي يحمل الرقم 5 وبالتالي فانت عندما تقوم بعمل لعبه ما فان المستخدم سيستخدم نفس الأزرار التي تعود على استخدامها وبنفس الطريقه.

مثال
public class KeyCanvas extends Canvas {

    private Font mFont;
    private String mMessage = "[Press keys]";


    public KeyCanvas() {
        mFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
    }


    public void paint(Graphics g) {
        int w = getWidth();
        int h = getHeight();

        g.setColor(0xFFFFFF);
        g.fillRect(0, 0, w - 1, h - 1);
        g.setColor(0x0);
        g.drawRect(0, 0, w - 1, h - 1);
        g.setFont(mFont);
        int x = w / 2;
        int y = h / 2;
        g.drawString(mMessage, x, y, Graphics.BASELINE | Graphics.HCENTER);
    }

    protected void keyPressed(int keyCode) {
        int gameAction = getGameAction(keyCode);

        switch (gameAction) {
            case UP:
                mMessage = "UP";
                break;

            case DOWN:
                mMessage = "DOWN";
                break;

            case LEFT:
                mMessage = "LEFT";
                break;

            case RIGHT:
                mMessage = "RIGHT";
                break;
            case FIRE:
                mMessage = "FIRE";
                break;
            case GAME_A:
                mMessage = "GAME_A";
                break;
            case GAME_B:
                mMessage = "GAME_B";
                break;
            case GAME_C:
                mMessage = "GAME_C";
                break;
            case GAME_D:
                mMessage = "GAME_D";
                break;
            default:
                mMessage = "";
                break;
        }
        repaint();
    }
}
في المثال السابق أعدنا تعريف keyPressed method وفي داخلها قمنا بمعرفه ال Game Action الذي حصل باستخدام جملة switch ثم أدخلنا اسم هذا ال Game Action في متغير اسمه mMessage وفي أخر سطر من ال method استدعينا repaint لكي تقوم باعاده رسم الشاشه.


في ال paint method نقوم برسم المتغير mMessage في منتصف الشاشه. لاحظ أن هذه الفئه ترث من الفئه Canvas وبالتالي نستطيع وضعها على شاشه الهاتف وهو ما سنقوم به في السطور الأتيه:
public class KeyEvents extends MIDlet {
    public void startApp() {
        KeyCanvas canvas = new KeyCanvas();
        Display.getDisplay(this).setCurrent( canvas );
        
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }
}

الجمعة، 16 يوليو 2010

نوكيا سوف تجعل عمليه ال Signing لبرامج ال Symbian مجانا

أعلنت شركه نوكيا عن نيتها جعل ال Signing لبرامج ال Symbian مجانا بعد أن كانت تكلف هذه العمليه 215$ وقد بدأ العمل في هذه الخطوه التجربيه منذ 23 June. وهذا البرنامج سوف يغطيي البرامج التي من نوع Symbian بشقيها sis و sisx والتي من نوع Qt والتي من نوع Flash Lite. سوف لن يغطي البرنامج برامج الجافا وهو أمر مفهوم حيث ان تكاليف ال Signing لبرامج الجافا لا تذهب لشركه نوكيا وانما لشركه Oracle مالكه جافا.

خطوات نشر برنامج على Ovi أصبح كالتالي كما جاء نقلا عن موقع نوكيا:
  • Ovi Publisher emails support and requests more details  
  • Ovi Publish support asks publisher to review and accept new terms and conditions
  • Ovi Publisher accepts new terms and conditions and provides IMEI numbers for up to 5 devices
  • Ovi Publish support sends publisher UIDs, a cert installer, and developer cert/key pair for testing their app
  • Ovi Publisher packages their unsigned SIS file using the UID provided and tests on their device making sure is tested against Symbian’s signing criteria
  • Ovi Publisher submits their app (unsigned SIS file with the UID provided) to the intake tool
  • QA and moderation will test the app and if it passes it will be express signed by Nokia and put into Ovi Store

الأربعاء، 26 مايو 2010

مقدمة في انشاء واجهة مستخدم منخفضة المستوى - الجزء الثاني

تنسيق الخطوط
يوجد تنسيقان مختلفان للخطوط وهما:
  • Solid
  • Dotted
ويمكن استخدامهما عن طريق ال setStrokeStyle method داخل الفئة Graphics كالتالي:
public void paint(Graphics g) {
 g.drawRect(20, 10, 35, 35);
 g.setStrokeStyle(Graphics.DOTTED);
 g.drawRect(20, 60, 35, 35);
}

في المثال السابق سوف يتم رسم مربع ولكن حدود المربع سوف ترسم بخط متقطع بسبب تغيير التنسيق. 

رسم النصوص
يوجد العديد من ال methods التي سةف تساعدك على رسم النصوص على الشاشة وجميعها موجودة داخل الفئة Graphics:
  • public void drawChar(char character, int x, int y, int anchor)
  • public void drawChars(char[] data, int offset, int length,int x, int y, int anchor)
  • public void drawString(String str, int x, int y, int anchor)
  • public void drawSubstring(String str, int offset, int len,int x, int y, int anchor)
جميع القيم الممررة لل methods واضحة وبسيطه الا أخر قيمة وهي ال anchor. هذه القيمة هي عبارة عن النقطة المرجعية للرسم والتي يجب أن تنطبق عليها قيم ال x و y في جميع ال methods.


قيم ال anchor هي عباره عن عملية Bitwise Or بين قيمة المحاذاة الأفقيه والتي يمكن أن تكون ( LEFT, HCENTER, RIGHT ) وبين قيمة المحاذاة العمودية والتي يمكن أن تكون ( TOP, BASELINE, BOTTOM ).

الأن لنفترض أنك أعطيت احدى ال methods السابقة القيم التالية:
x = 10
y = 5
anchor = Graphics.LEFT | Graphics.TOP

سيرسم النص بحيث أن زاويه المربع المحيطة بالنص من الأعلى واليسار سوف تنطبق على النقطة ( 10,5 ).

مثال
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.*;

public class TextDrawing extends MIDlet implements CommandListener {
    Command cmdExit = new Command( "Exit", Command.EXIT, 0 );

    public void startApp() {
        TextCanvas canvas = new TextCanvas();
        canvas.addCommand( cmdExit );
        canvas.setCommandListener( this );
        Display.getDisplay(this).setCurrent( canvas );

    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    public void commandAction(Command c, Displayable d) {
        notifyDestroyed();

    }
    
}

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

public class TextCanvas extends Canvas {
    public void paint(Graphics g) {
        int w = getWidth();
        int h = getHeight();
        g.setColor(0xffffff);
        g.fillRect(0, 0, w, h);
        g.setColor(0x000000);

        g.drawString("TOP_LEFT", 0, 0, Graphics.TOP | Graphics.LEFT);
        g.drawString("TOP_RIGHT", w, 0, Graphics.TOP | Graphics.RIGHT);
        g.drawString("BOTTOM_LEFT", 0, h, Graphics.BOTTOM | Graphics.LEFT);
        g.drawString("BOTTOM_RIGHT", w, h, Graphics.BOTTOM | Graphics.RIGHT);

        g.drawString("JME World", w / 2, h / 2, Graphics.BASELINE | Graphics.HCENTER);
    }
    
}

الثلاثاء، 25 مايو 2010

مقدمة في انشاء واجهة مستخدم منخفضة المستوى - الجزء الأول

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

تستخدم عاده هذه ال APIs في برمجيات الألعاب التي تعتمد على الرسم بشكل كبير كما أن كثيرا من المطورين يستخدمونها لأنشاء أدوات لا تحتويها واجهات المستخدم عاليه المستوى في JME.

Canvas
في مقدمه الواجهات عاليه المستوى ذكرنا أن هناك فئتان ترثان من الفئه Displayable وهما Screen و Canvas وقد تطرقنا الى ال Screen والفئات التي ترث منها بالتفصيل أما اليوم فسنتكلم عن الفئه Canvas.

الفئه Canvas هي Abstract Class لا يمكنك انشاء كائن منها وأحب أن أشبهها بورقه الرسم البيضاء الجاهزة للرسم. يتم العمل عليها عن طريق انشاء فئة جديدة ترث من الفئه Canvas ثم تقوم بكتابة ال paint method الموجودة بداخل ال Canvas والتي بها تتم عمليات الرسم كاملة.
public class MyCanvas extends Canvas {
 public void paint(Graphics g) {
  // Draw stuff using g.
 }
}

الرسم واعادة الرسم
يتم استدعاء ال paint method بمجرد وضع كائن من أي فئة ترث من فئة ال Canvas على شاشة الهاتف وعندها يتم رسم الشاشه لأول مرة، أما اذا أردت اعادة رسم الشاشه لتحديثها مثلا يمكنك ذلك عن طريق ال repaint method.
public void repaint()
public void repaint(int x, int y, int width, int height)

احداثيات الرسم
احداثيات الرسم في JME تطابق احداثيات الرسم التي تعلمناها في علوم الحاسوب فالمحور x الموجب ينطلق باتجاه اليمين والمحور y الموجب ينطلق بانجاة الأسفل.

رسم الأشكال
يمرر الى ال paint method كائن من الفئه Graphics وهو الكائن الذي يمثل حلق الوصل بينك وبين ال Canvas فهو يمثل القلم الذي سوف تستخدمة في الرسم على ال Canvas.

تحتوي هذة الفئة على جميع ال methods الرئيسة التي تمكنك من الرسم على ال Canvas ولنبدأ مع رسم الأشكال وهي كالتالي:
أولا: ال methods المسؤلة عن رسم الأشكال المفرغه من الألوان وهي:
  • drawLine(int x1, int y1, int x2, int y2)
  • drawRect (int x, int y, int width, int height) 
  • drawRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight)
  • drawArc (int x, int y, int width, int height, int startAngle, int arcAngle)
ثانيا: ال methods المسؤلة عن رسم الأشكال المعبئة بالألوان وهي:
  • fillTriangle (int x1, int y1, int x2, int y2, int x3, int y3)
  • fillRect (int x, int y, int width, int height) 
  • fillRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight)
  • fillArc (int x, int y, int width, int height, int startAngle, int arcAngle)
التعامل مع الألوان
يمكن تحديد لون الرسم عن طريق ال methods التالية:
public void setColor(int RGB)
public void setColor(int red, int green, int blue)

تمثل الألوان في JME عن طريق استخدام integer وهو يقسم الى 4 Bytes الأول من اليمين يمثل اللون الأزرق والثاني الأخضر والثالث الأحمر وأخر Byte غير مستخدم, بعض ال APIs الأخرى تستخدمه من أجل تحديد الشفافية.

كل مركب من هذة المركبات يأخذ القيمة ما بين 0-255 ودمج هذه المركبات بنتج لنا اللون المراد فمثلا:
اللون 0xFFFFFF هو اللون الأببيض واللون 0x0 هو اللون الأسود. يمكن أخذ هذه القيم باستخدام برنامج ال Photoshop أو أي برنامج رسم أخر واستخدامها في برنامجك.

الشريط المتحرك

مقدمة
هو شريط يوضع أعلى الشاشة أو أسفلها حسب نوع الهاتف ويقى يتحرك الى ما لا نهاية.

انشاء الشريط
// Displayable d = ...
Ticker ticker = new Ticker("This is the ticker message!");
d.setTicker(ticker);

يتم انشاء الشريط عن طريق ارسال الرساله المراد اظهارها عليه الى المشيد، ثم بعد ذلك يتم اضافه الشريط الى أي نافذة Displayable من النوافذ الأربع التي سبق الحديث عنها.

مثال
 public class TickerMIDlet extends MIDlet 
 implements CommandListener {
     
 private Form form;
     private Command cmdExit;
     public TickerMIDlet() {
          form = new Form( "Ticker" );
          Ticker ticker = new Ticker( "This is a ticker message!" );
          form.setTicker( ticker );
          cmdExit = new Command(  "Exit",Command.EXIT,  0 );        
  form.addCommand( cmdExit );
          form.setCommandListener( this );
          Display.getDisplay( this ).setCurrent( form );        
     }
        
        public void startApp() {
     }
     public void pauseApp() {
     }
     public void destroyApp(boolean unconditional) {
     }
 public void commandAction(Command c, Displayable d) {
          destroyApp( true );
          notifyDestroyed();
     }
}

الجمعة، 30 أبريل 2010

دراسه تحليليه لمنصات التشغيل في الهواتف النقاله والأجهزه الكفيه

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

سوف يتم الاشاره الى الهواتف النقاله والأجهزه الكفيه في هذه الدراسه بكلمه "الهواتف النقاله" وسوف أتغاضى عن الفرق بينهما.

ان هدف كل شركه تقوم بانتاج البرمجيات هو تحقيق أكبر قدر ممكن من المبيعات، وأهم عنصر يجب أن تنتبه له الشركه اذا ارادت رفع نسبه المبيعات هو "كم عدد الناس الذين باستطاعتهم تنصيب البرنامج على أجهزتهم". لذلك فانه يمكن أن نفكر بحل هذه المشكله عن طريق ايجاد حصه السوق لكل منصه تشغيل ومن ثم العمل على انتاج برنامج يعمل على أشهر منصه وهذه النقطه الأولى التي سوف ننطلق منها.

حصة السوق لأشهر منصات التشغيل
ان أول ملاحظه سوف نلاحظها أن الموضوع هنا يختلف عنه في أجهزه الحواسيب الشخصيه، هنا كل منصه لها حصه قريبه من الأخرى رغم سيطره Symbian على السوق حاليا, والنقطه الملاحظه هي سهوله تقلب السوق وتغير الحصص وهو المتوقع حدوثه هذا العام والعام المقبل.
هذه الاحصائيه حتى الربع الثاني من عام 2009. وكما هو ملاحظ فان السيطره ما زالت حتى الأن لنظام Symbian المنتشر بصوره كبيره على هواتف Nokia. رغم ظهور منصات تشغيل جديده مثل Android وانتعاش نسبه ال iPhone.

Symbian
نظره عامه
هي المنصه الأكثر انتشارا حاليا، لها ما يقارب نصف حصه السوق. يدار هذا النظام من قبل ال Symbian Foundation. وهي منظمه غير ربحيه تقوم باداره النظام وتضم العديد من الأعضاء أشهرهم Nokia, Sony Ericsson, Motorola, Samsung وغيرهم الكثير. تم فتح الشيفر المصدريه للنظام في 4 فبراير 2010. يوجد Store يمكن المستخدمين من تحميل تطبيقات ال Symbian على أجهزه ال Nokia وهو Ovi Store.

اصدارات النظام
سوف نتحدث في هذه النقطه عن اصدارات نظام ال Symbian والمرتبطه ارتباطا وثيقا بأجهزه النوكيا لأنها الأكثر انتشارا وهي التي تهمنا، ( لن أتحدث عن UIQ ).
  1. Series 60 V1.
  2. Series 60 V2: Initial Release, Feature Pack 1, Feature Pack 2.
  3. Series 60 V3: Initial Release, Feature Pack 1, Feature Pack 2.
  4. Series 60 V5.
  5. Series 80.


ان الفرق بين البرمجه في نظام ال S60 V1 لم يختلف عنه كثيرا في النظام الذي يليه الا وهو S60 V2. أما النسخه الثالثه وهي ما يسمى اليوم بأجهزه الجيل الثالث من نوكيا فانه حدث تغير شاسع في طريقه التطوير كما أنه البرامج القديمه التي كانت تعمل على النسخ القديمه من النظام لم تعد متوافقه مع النظام الجديد.

عند صدور النسخه الجديد وهي ال S60 V5 كان من أهم المميزات الي أضافتها توفر خاصيه اللمس في الأجهزه التي تعمل عليها وكان الهدف من وجودها هو منافسه ال iPhone الذي بدأ يطغي في الساحه. من أشهر الأجهزه التي تعمل عليه هذه المنصه هي ال Nokia N97 و Nokia 5800 Express Music.

اما Series 80 فهي نزلت على عدد قليل من الأجهزه ولم تلق النجاح الذي لاقته ال S60.

خيارات التطوير المتاحة
  1. Symbian C++: Native language
  2. Open C/C++
  3. JME
  4. Flash Lite
  5. Python
  6. Web Runtime (WRT)
  7. Qt

RIM BlackBerry
نظرة عامة
هي المنصه الثانيه في الترتيب ولها ما نسبته 20.9 % من حصه السوق، طورت من قبل شركه RIM وهو نظام مغلق المصدر. جافا هي اللغه الرئيسه للتطوير على النظام وله Store يسمى AppWorld وهو يعمل على الأجهزه التي تحمل نظام 4.2 أو نظام لاحق. في الشهر الماضي - ابريل 2010 - أعلنت RIM ظهور نظامها الجديد الذي يحمل الرقم 6.0 وهو أحدث نظام لها.


اصدارات النظام
  1. 4.2
  2. 4.3
  3. 4.5
  4. 4.6
  5. 4.7
  6. 5.0
  7. 6.0
بدأت ظهور الأجهزه التي تدعم اللمس منذ الاصدار 4.7 ويجدر الاشاره الى أنه كسر التوافقيه مع الانظمه السابقه اي انه عليك اعاده ترجمته (Compile) برامجك مرتين لكي تعمل على كلا القسمين من الأنظمة.

Apple iPhone
نظرة عامة
يحتل المرتبه الثالثه في السوق، مطور من قبل شركه Apple وهو نظام مغلق المصدر. يمتاز بشكله الرائع الذي يجذب الناس اليه. يوفر خاصيه اللمس المتعدد. Objective C هي لغه التطوير الوحيده للنظام ونظام Mac OS هو النظام الوحيد الي يمكنك التطوير عليه. لا يمكن للمستخدمين رسميا تحميل البرامج الا من خلال AppStore.


تجدر الاشاره الى أن AppStore هو أول متجر الكتروني يطلق لبيع تطبيقات الهواتف النقاله وهو يعد من أنجح المتاجر الالكترونيه على الاطلاق لذلك تنبهت الكثير من الشركات لهذا الموضوع وسعوا الى انشاء افكار مشابهه ومنهم Nokia, BlackBerry, Android وغيرهم الكثير.

من الملفت للنظر أنه لا يدعم جافا ولا Adobe Flash وهو ما سبب خلافات كبيره بين Sun و Apple وبين Adobe و Apple.

في التاسع من ابريل 2010 قامت Apple بالاعلان عن نظامها الجديد iPhone OS 4.0 ومن أهم المميزات التي سيأتي بها النظام هي ميزه تعدد المهام (Multitasking).



اصدارات النظام
عدد اصدارات النظام مهول جدا, وربما يكون أكثر منصه تشغيل لها هذا العدد من الاصدارات. لمزيد من المعلومات راجع الرابط التالي.

Windows Mobile
نظره عامه
يحتل المرتبه الرابعه في الترتيب, مطور من قبل شركه ميكروسوفت وهو نظام مغلق المصدر. له Store يسمى Windows Market Place for Mobile. في الفتره الأخيره بدأ النظام يفقد حصته شيئا فشيئا، لذلك قامت ميكروسوفت بالاعلان عن Windows Phone 7 في 15 فبراير 2010 ومن المفترض أن يكون النظام الجديد نقله نوعيه وسوف تعتمد عليه في العوده الى السوق بقوه.



من أهم الخصائص التي سيقدمها هو ربطه مع XBox Live. سوف لن يقوم بدعم تعدد المهام مبدئيا ولن يدعم القص واللص ، لكن ميكروسوفت سوف تقوم بدعم هاتان الخاصيتان لاحقا عبر خاصيه التحديث التلقائي للهاتف. سوف يتم التطوير له باستخدام XNA و Silverlight مع ال .NET. سوف لن يسمح النظام الجديد بتنزيل التطبيقات الا من خلال ال Windows Market Place وهي سياسه تشابه سياسه Apple والى الأن لا يوجد الا هاتان الشركتان اللتان تفرضان هذا الشرط.

خيارات التطوير المتاحة
  1. C++, native language
  2. .NET Framework
  3. Qt
  4. JME - CDC
  5. JME - CLDC
  6. JavaFX
  7. Qt
  8. Python
Android
نظره عامة
يحتل المرتبه الخامسه في الترتيب، وهو نظام مفتوح المصدر يدار ويطور من قبل ال Open Handset Alliance وهي منظمه تضم أكثر من 65 شركة. له Store يسمى Android Market ويسمح للمستخدمين بتحميل تطبيقات ال Android. جافا هي لغه التطوير الرئيسه للنظام رغم أنه يمكن كتابه أجزاء من التطبيقات باستخدام C++.





النظام يستخدم نسخة معدله من ال Linux Kernel تم تعديلها من قبل Google. هذه النسخه تختلف عن باقي توزيعات ال Linux بشكل كبير حيث أنها لا تحتوي على native X Window System ولا على جميع مكتبات GNU القياسية، وهذا من شأنه تصعيب عمليه اعاده استخدام تطبيقات ال Linux الحاليه على ال Android.

نظام Android لم يستعمل نسخ الجافا المعروفه من JavaSE أو JavaME وهو ما يمنع التوافقيه بين تطبيقات Android وتطبيقات الجافا الحاليه. Android لم يستخدم من جافا الا طريقه الكتابه أو ما يسمى ال Syntax. هناك امكانيه لرؤيه JavaFX على Android.



هذا المقطع يعرض JavaFX على Android ومنذ ذلك الوقت لم أسمع عن هذا الأمر أي جديد.


التوقعات
  1. Symbian
  2. Android
  3. iPhone
  4. Windows Mobile
  5. BlackBerry

اصدارات النظام
  • Android 1.0
  • Android 1.1
  • Android 1.5
  • Android 1.6
  • Android 2.0
  • Android 2.0.1
  • Android 2.1
أترككم مع هذا العرض لأهم مميزات Android 2.0


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

خيارات التطوير
  • C/C++
  • Qt
  • Java
  • Python
  • Ruby
  • Mono
باختصار يمكن أن تطور عليه كما تطور على توزيعه Linux الاعتياديه. ونتيجه للنجاح الذي لاقته قامت Intel بالتعاون مع Nokia باصدار منصه MeeGo وهي نسخه معدله من Mameo لكي تعمل بكفاءه عاليه على معالجات Intel.



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

بيئات التطوير
  • Objective C
  • Symbian C++
  • C/C++
  • RIM's Java
  • Android's Java
  • Java ME
  • Java FX
  • Qt
Objective C
  • سهوله التعلم: صعبة نسبيا وهي تختلف قليلا عن لغة ال C المعروفة.
  • المنصات الي تعمل عليها: أجهزه ال iPhone وال iPod وال iPad.
  • التوافقيه: لا أعلمها..
  • تكلفه التطوير: الأدوات مجانيه ولكن تحتاج الى حاسوب Mac والى دفع 99$ للحصول على Signing Keys للمطورين.
++Symbian C
  • سهولة التعلم: صعبه نسيبا فهي تختلف عن لغة ++C التي نعرفها قليلا.
  • المنصات التي تعمل عليها: جميع الهواتف التي تعمل باستخدام منصة Symbian.
  • التوافقية: على الأغلب نسخه منفصله لكل سلسله وهناك تغييرات جذريه بسبب الاختلاف الشاسع بين S60 V2 و S60 V3 ووجود اختلاف بين S60 V3 و S60 V5.
  • تكلفة التطوير: هناك أدوات مجانية وأخرى غير مجانية.
C/C++
  • سهولة التعلم: متوسطة, وسهلة بالنسبه لمطوري Win32.
  • المنصات التي تعمل عليها: Windows Mobile, Windows CE وربما مع بعض التعديلات يمكن تشغيلها على هواتف Nokia باستخدام Open C/C++.
  • التوافقيه: على الأغلب نسخه لكل منصة ولكن التغييرات ليست كبيرة في معظم الأحيان.
  • تكلفة التطوير: يوجد أدوات مجانية تعتمد على سطر الأوامر ويمكن استخدام eMbeded VC++ او Visual Studio Standard Edition.
RIM's Java
  • سهولة التعلم: متوسطة.
  • المنصات التي تعمل عليها: أجهزة BlackBerry فقط.
  • التوافقية: نسختان على الأقل واحدة للأجهزة من 4.2.1 الى 4.6 وأخرى للأجهزه من 4.7 وما يليها بسبب عدم التوافقيه بين هذه الأنظمة.
  • تكلفة التطوير: جميع الأدوات مجانية.

Android's Java
  • سهولة التعلم: متوسطة.
  • المنصات التي تعمل عليها: أجهزة Android فقط بسبب ال Dalvik VM.
  • التوافقية: تختلف بحسب البرنامج ربما تحتاج الى نسخة واحده وربما لأكثر من نسخة اذا احتجت لمكتبات توفرها الأنظمة الجديدة, هناك بعض الشكاوى على اختلاف طريقة عمل البرنامج من جهاز لأخر.
  • تكلفة التطوير: جميع الأدوات مجانية.
Java ME
  • سهولة التعلم: متوسطة.
  • المنصات التي تعمل عليها: أكثر من 2.6 مليار جهاز يدعم جافا حتى الربع الرابع من عام 2009.
  • التوافقية: في معظم الاحيان تحتاج الى العديد من النسخ لكي تحصل على أكبر عدد من الأجهزه. باختصار Write once, debug everywhere.
  • تكلفة التطوير: جميع الأدوات مجانية.
Java FX
  • سهولة التعلم: لا أعلمها.
  • المنصات التي تعمل عليها: الحواسيب الشخصية، متصفحات الانترنت، الهواتف النقالة، أجهزة التلفاز، Play Station3، مشغلات ال Blue-ray، حاليا هي تعمل على أنظمه Windows XP, Windows Vista, Mac وهناك نسخة Beta لل Linux. أما في أجهزة الهاتف فهناك نسخة Beta لل Windows Mobile. ربما نراها على Android.
  • التوافقيه: نرجو أن تكون نسخة واحده لكن لا أظن ذلك.
  • تكلفة التطوير: جميع أدوات التطوير مجانية.
Qt
  • سهولة التعلم: لا أعلمها.
  • المنصات التي تعمل عليها: Embeded Linux, Mac OS X, Windows, Linux, Windows CE, Windows Mobile, Symbian, Maemo, MeeGo.
  • التوافقيه: نرجوا أن تكون نسخة واحدة.
  • تكلفة التطوير: أدوات التطوير مجانية.

حسننا لنأخذ الأن وقفه مع المعطيات التي تناولناها. ان أكثر لغة برمجه تغطي أكبر عدد من الأجهزه هي Java ME بلا منازع، فهل هي الخيار الأمثل؟ الجواب بالطبع لا، يوجد العديد من المعطيات التي يجب أخذها بالحسبان فمثلا صحيح أن معظم الأجهزه تدعم Java ME ولكن جزء كبير من هذه الأجهزه هي أجهزه قديمه. كما أن مستخدموا هذه الأجهزه لا يميلون بكثره الى شراء تطبيقات الهاتف النقال بعكس مستخدموا iPhone الذين لا يعيشون دون شراء تطبيقاته ربما فقط من أجل التجربة. Java ME مليئه بالقيود فهي لا تصلح للتعامل مع ال Hardware بشكل مكثف مثل Symbian C++ مثلا. حسنا ماذا عن Symbian C++ ؟ لغه قويه تحررك من قيود Java ME ولكنك سوف تدخل في مشاكل أخرى أولها هي صعوبه اللغه وقله الدعم لها. في الحقيقه هنا في الأردن لا أعرف الى الأن سوى شخص واحد فقط يستطيع عمل برنامج كامل عليها. ثم نتأتي الى مشاكل التوافقيه بين النسخ المختلفه.

حسنا ماذا عن Objective C, Android's Java, RIM's Java ؟ جميع هذه اللغات محصوره في منصات التشغيل التي تعمل عليها فقط ولا تعمل على أي شيء أخر. كنا نتمنى أن تسهل حياتنا كلما تقدم الزمن ولكن الزمن يثبت عكس ذلك، حتى أن Windows Phone 7 سار على نفس الطريق وقرر أن تعمل عليه باستخدام .NET فقط ولا شيء غيرها.

اذا كان برنامجك يهدف الى العمل على احدى المنصات السابقه فعلى الأغلب أنه لا توجد لديك خيارات كثيره وعليك المضي قدما باستعمالها.

نأتي الى أخر خيارين, أدركت Sun أنه يجب عليها استهداف أكبر عدد من المستخدمين ببرامجها ولذلك قررت اطلاق JavaFX اتي تهدف الى توحيد كتابه التطبيقات ليس بين الهواتف فقط وانما بين جميع الأجهزه على اختلافها ان كانت هواتف ام أجهزه تلفاز أم تطبيقات الانترنت وغيرها. لكن بصراحه المشروع يبدو صعب المنال فهي لم تنجح في JavaME كما كان مخططا لها وكان هدفها توحيد التطبيقات على أجهزه الهاتف فقط وظهرت المشاكل على مخلف الأجهزه فكيف ستوحد التطبيقات على كل هذه المنصات في JavaFX. شيء أخر ان نقطه القوه التي ظلت Sun مركزه عليها هو عدد الهواتف التي تدعم JavaME وبخطوه JavaFX هي ببساطه قامت بتصفير العداد لأنه لا يوجد هاتف حالي يدعم JavaME سوف يستطيع ان يدعم JavaFX وانما يمكن ان تظهر على الأجهوة الجديده فقط وهو ما يعني العودة الى نقطه الصفر.

من ناحية أخرى فان Sun أعلنت العام الماضي عن نيتها اطلاق Store خاص بلغة جافا. هذه الخطزة بنظري ربما تقلب بعض الموازين فالمحلات الخاصه ب Apple أو نوكيا هي محلات مقتصره على أجهزة محدده ولكن في Java Store سوف يكون بامكان المطورين بيع برامجهم المكتوبه بلغه جافا بغض النظر عن المنصه التي تعمل عليها هذه البرامج. كما أننا لن ننسى أن Sun سوف تقوم بدفع هذا ال Store عن طريق ال Java Update أي أنه من قبل حتى ظهوره فهو يضمن وجود مليارات المستخدمين عليه لأنهم يملكون جافا على اجهزتهم.



لنأتي الى Qt فهي أيضا تهتم بدعم عدد كبير من المنصات ويمكن عمل برامج عليها تستهدف كل هذه المنصات وهي أسهل من Symbian وأقوى من JavaME أي أنها تمتلك جميع نقاط القوة, النقطة الوحيده التي عليها هي قله عدد أجهزه Nokia التي تعمل عليها وهو ما سيختفي قريبا لأن كل أجهزة Nokia التي تعمل على نظام Symbian سوف يمكنك استهدافها باستخدام Qt من الأن فصاعدا.

الأن أكملت مهمتي وأرجو أن تكون قد استفدت من هذه المعلومات والحقائق. أريد أن أنوه في النهايه أن كل هذا هو عامل واحد فقط في نجاح برنامجك وبالتأكيد هناك عوامل أخرى عليك دراستها وأخذها بعين الأعتبار.

من يجد خطأ أو معلومه ناقصه أرجو أن يعلمني بذلك حتى نصححها أو نضيفها وله جزيل الشكر...

الاثنين، 26 أبريل 2010

انشاء النوافذ - النموذج

جميع النوافذ السابقه كانت عباره عن نافذة تغطي كامل الشاشه وتخدم هدف واحد فقط، ماذا لو أردت نافذه تحتوي على محموعه من الهناصر المختلفه. النموذج هو الحل لمثل هذه الحالات.

انشاء النموذج
public Form(String title)
public Form(String title, Item[] items)
المتغير الأول هو عنوان النموذج والثاني هو العناصر التي يحتويها النموذج.

عناصر النموذج
يمكن اضافه مجموعه من العناصر الى النموذج وهي:
  1. StringItem : وهو عباره عن نص غير قابل للتعديل يستخدم في الكتابه على النموذج.
  2. Spacer: عنصر يضاف للنموذج لحجز مساحه فارغه، يستخجم عاده لتحسين شكل النموذج.
  3. TextField: مربع نصي يشبه النافذه النصيه ولكنه لا يغطي كامل الشاشه.
  4. ImageItem: عنصر الصوره وهو عباره عن صوره يتم اضافتها للنموذج.
  5. DateField: حقل اختيار التاريخ.
  6. Gauge: وهو عباره عن مؤشر للعمليات يستخدم للدلاله على وجود عمليه طويله تتطلب الانتظار من المستخدم.
مثال
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.DateField;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.ImageItem;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.Spacer;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.*;

public class FormDemo extends MIDlet implements CommandListener {
private Form form;
private Command cmdExit = new Command( "Exit", Command.EXIT, 0 );

public FormDemo() {
form = new Form( "Form Demo" );
form.append( "StringItem" );

StringItem si = new StringItem( "Label", "Text" );
form.append( si );

Spacer spacer = new Spacer( 100, 40 );
form.append( spacer );

TextField txt= new TextField( "Phone No", "", 100, TextField.PHONENUMBER );
form.append( txt );

try {
Image img = Image.createImage( "/duke.png" );
ImageItem imgItem = new ImageItem( "Picture", img, Item.LAYOUT_CENTER, "Picture" );
form.append( imgItem );

} catch( Exception ex ) {
System.err.println("can't load the image");
}

DateField dateField = new DateField( "Date Of Birth" , DateField.DATE_TIME );
form.append( dateField );

form.setCommandListener(this);
form.addCommand(cmdExit);

}

public void startApp() {
Display.getDisplay(this).setCurrent(form);

}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

public void commandAction(Command c, Displayable d) {
if( c == cmdExit ) {
destroyApp(true);
notifyDestroyed();

}

}
}
في السطر 20 أنشأنا النموذج وفي السطر الذي يليه قمنا باضافه StringItem مباشره الى ال Form. في السطر 23 أنشأنا StringItem جديد ثم أضفناه للنموذج في السطر 24. في السطور 26-27 أنشأنا مساحه فارغه عرضها 100 نقطه وارتفاعها 40 نقطه ثم أضفناها للنموذج. في السطور 32-39 قمنا بانشاء صوره ثم وضعناها في ImageItem ثم أضفناه للنموذج.

ملاحظات مهمه:
  1. الصوره وضعناها في ملف ال src وهو المجلد الرئيسي في المشروع لذلك فان المسار يكون على الشكل التالي: duke.png/
  2. أي عمليه IO في جافا يجب وضعها في

try {

} catch(Exception ex) {

}
في السطور 41-42 أنشأنا حقل اختيار التاريخ وأضفناه للنموذج. وفي النهايه أضفنا المتنصت وأمر الخروج. في ال startApp عرضنا النموذج السابق على شاشه الهاتف.

الخميس، 22 أبريل 2010

فزعة العرب Development Life Cycle

العالم المثالي
أذكر في أيام الدراسة وقف أمامنا مدير لاحدى الشركات الكبرى وأخذ يخطب فينا لأكثر من نصف ساعة وهو يشرح لنا الفرق بين العمل في الشركات وبين ما ندرسة وكيف أن الجامعة لا تؤهلنا بشكل جيد للعمل في الشركات وكيف أنه لابد لنا من أخذ الدورات التدريبية حتى نحصل على فرصة عمل مرت السنوات وأيقنت ان ذلك الشخص كان مخطأ على الأقل حسب تجربتي الشخصية.

العالم الواقعي
ثلاث سنوات منذ ذلك اليوم وفي احدى الايام القريبة كنت أنا وصديقي نتمشى أثناء فترة الاستراحه واذا بة يشاهد صديقا له يكبرنا سنا وخبرة استوقفناه, سلمنا عليه واذا بصديقي يسألة سؤالا "كيف تديرون عملية انتاج برامجكم؟" على اعتبار اننا نعاني من هذه المشكلة وأحببنا أن نأخذ نصيحه منه فاذا به يجيبنا: "نحن نعتمد طريقة فزعة العرب Development Life Cycle".

فزعة العرب Development Life Cycle
كان وقع الاجابة علينا مضحكا مبكيا في نفس الوقت. سأشرح لكم ما هي هذه الطريقة. يأتي زيون ويطلب مشروعا ما أو تقفز فكره جهنمية في رأس المدير فيقرر اطلاق شارة البداية لمراثون لا نعرف له نهاية في معظم الاحيان. بعد ساعتان أو يومان على الأكثر تجد مستند يسمى User Requirement لا تعرف من كتبه ولا من أين اتى وفي معظم الأحيان شخص غير مؤهل يكون هو كاتب هذه التحفة الفنية. بعدها يأتي مدير المشروع ليأمرك ببداية البرمجة وتبدأ انت في سباق مع الزمن لكي تنهي شيئا أنت لا تعرفه ولا حتى مديرك يعرفة.

تنهي نسخة أولية من المشروع وتكون فرحا بانجازك تريها للمدير أو للزبون وتبدأ التعليقات والتغييرات. لماذا فعلت هذا؟ ولم لم تفعل ذلك؟ ونحن لم نتفق على هذه، وحبذا لو أضفت هذه. عليك تقبل الطلبات وتبدأ في تنفيذ التغييرات وتعود للسباق المحموم مرة أخرى ويبدأ التذمر من التأخر في المشروع وكيف أنه تجاوز ميزانيته المسموح بها و و و.........

ينتهي المشروع بعد صراع مرير مع كل طرف من أطراف هذه العملية السقيمة وتكون محظوظا اذا رأى البرنامج النور وأحيانا أخرى تجده انتهى في سلة المهملات.

الخلاصة
ثلاث سنوات وأنا أعمل في الشركات وما زلت أرى هذه المأساة تتكرر. أتذكر مشاريع التخرج، أتذكر كيف كنا نكتب ال documentation وكيف صممنا ال DFD وال EER وال Use Cases ولا أعلم من منهما هو العالم المثالي، هل هو ما درسته أم ما هو كائن في شركاتنا البرمجية. والعجيب في الموضوع أننا دائما نحاول اقناعهم ان هذا لا يجوز. هناك خطوات يجب أن تتم قبل ان تبدأ أصابعنا بالطقطقه على أزرار الكود ولكن لا حياة لمن تنادي.

الأربعاء، 21 أبريل 2010

انشاء النوافذ - القائمة

القائمة
هي عبارة عن قائمة تحتوي مجموعة من الخيارات وتسمح لك اما الاختيار منها او تنفيذ عملية عند الضغط على أحدها ويتم ذلك حسب نوع القائمة.

انشاء القائمة
List(String title, int listType)
List(String title, int listType, String[] stringElements, Image[] imageElements)
يمكن انشاء القائمه عن طريق تمرير عنوان القائمة ونوعها كما يمكنك ارسال الخيارات الابتدائية للقائمة والصورة لكل خيار. مع ملاحظة أن مصفوفة الصور يجب ان تكون مساوية في العدد للخيارات الموجودة في القائمة كما يمكنك تمرير القيمة null اذا كنت لا ترغب باضافة صور.

أنواع القائمة
Implicit: هي قائمة يتم فيها اختيار العناصر ضمنيا بمجرد تحديده وعند الضغط على ال Fire Button في الهاتف فانه سيتم استدعاء ال commandAction في المتنصت المضاف لهذة القائمة.

Exclusive: هي قائمة تسمح لك باختيار أحد الخيارات فقط.

Multiple: هذه القائمة تسمح لك باختيار مجموعة من الاختيارات في نفس الوقت.

معالجة الأحداث
معالجة الأحداث في القائمة implicit يتم بطريقة مختلفة قليلا حيث سوف يتم ارسال SELECT_COMMAND الى ال commandAction الموجودة في المتنصت وهذا ال command معرف داخل ال List Class.
public void commandAction(Command c, Displayable s) {
if (c == nextCommand)
// ...
else if (c == List.SELECT_COMMAND)
// ...
}
مثال
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;
import javax.microedition.midlet.*;

public class Lists extends MIDlet implements CommandListener {
List mainList;
List implicitList;
List exclusiveList;
List multipleList;
Command cmdExit = new Command( "Exit", Command.EXIT, 0 );
Command cmdBack = new Command( "Back", Command.BACK, 0 );

public void startApp() {
String[] options = {"Implicit", "Exclusive", "Multiple"};
mainList = new List("List Example", Choice.IMPLICIT, options, null);
mainList.setCommandListener(this);
mainList.addCommand(cmdExit);

options = new String[] {"A", "B", "C"};
implicitList = new List("Implicit List", Choice.IMPLICIT, options, null);
implicitList.addCommand(cmdExit);
implicitList.addCommand(cmdBack);
implicitList.setCommandListener(this);

exclusiveList = new List("Exclusive List", Choice.EXCLUSIVE, options, null);
exclusiveList.addCommand(cmdExit);
exclusiveList.addCommand(cmdBack);
exclusiveList.setCommandListener(this);

multipleList = new List( "Multiple List", Choice.MULTIPLE, options, null );
multipleList.addCommand(cmdExit);
multipleList.addCommand(cmdBack);
multipleList.setCommandListener(this);

Display.getDisplay(this).setCurrent( mainList );

}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

public void commandAction(Command c, Displayable d) {
if(c == List.SELECT_COMMAND && d == mainList) {
int index = mainList.getSelectedIndex();
if( index == 0 ) {
Display.getDisplay(this).setCurrent(implicitList);

} else if(index==1) {
Display.getDisplay(this).setCurrent(exclusiveList);

} else if(index == 2) {
Display.getDisplay(this).setCurrent(multipleList);

}

} else if(c == cmdBack ) {
Display.getDisplay(this).setCurrent(mainList);

} else if(c == cmdExit) {
destroyApp(true);
notifyDestroyed();

}

}
}
في السطور من 10-13 قمنا بتعريف أربعة قوائم الأولى هي القائمة الرئيسة التي سوف تختار منها نوع القائمة التي تريد عرضها. في السطور من 18-21 تم انشاء القائمة الرئيسة واضافة الخيارات لها ثم تم اضافة الأمر cmdExit والمتنصت.

في السطور ما بين 23-27 تم انشاء القائمة الضمنية implicitList واضافة الأمران cmdExit و cmdBack واضافة المتنصت. ثم تمت اعادة العملية لكل من القائمة exclusiveList والقائمة multipleList. ثم في السطر 39 تم عرض القائمة الرئيسة.

الان سوف ننتقل الى ال commandAction في السطر 49 وبها سوف نتأكد في البداية من الأمر التابع للقائمة الضمنية مع ضرورة التأكد أن الأمر تم حدوثه في النافذة الرئيسة وليس في النافذة الداخلية حيث أنه توجد قائمتان ضمنيتان وهذا تم في السطر 50. بعد ذلك قمنا بمعرفة العنصر المحدد من القائمة والذي قام المستخدم بتحديدة ثم عرضنا القائمة المناسبة لهذا العنصر.

اذا تم اطلاق الأمر رجوع cmdBack نقوم بالعودة للقائمة الرئيسة عن طريق عرضها على نافذة الهاتف.