# فناوری جاوا > برنامه‌نویسی جاوا > Java ME : نگارش میکرو جاوا >  آموزش گام به گام برنامه نویسی موبایل

## rezaTavak

فرضیات:
جاوای استاندارد را بلد هستید.
جاوا بر روی کامپیوتر شما نصب است.
netbeans که دارای افزونه برنامه نویسی موبایل است را نصب کرده‌اید.
مفاهیم برنامه نویسی موبایل را می دانید (مانند j2me,cldc و ...)

خب درس اول:

قالب یک برنامه موبایل بصورت زیر است:


 *import* javax.microedition.midlet.MIDlet;

*public class* MyMIDlet *extends* MIDlet {

*public* MyMIDlet() {
// constructor
}

*public* *void* startApp() {
// entering active state
}

*public* *void* pauseApp() {
// entering paused state
}

*public* *void* destroyApp() {
// entering destroyed state
}
}




اولین خط کلاس midlet  را به خدمت می گیرد. اساسی ترین کلاس در نوشتن برنامه موبایل.

startApp  هنگامی که برنامه شروع می‌شود اجرا خواهد شد.

pauseApp  هنگامیکه مثلا برنامه بصورتی معلق می ماند اجرا می‌شود مثلا خوردن زنگ تلفن.

destroyApp خروج از برنامه دستورات این متد اجرا می‌شود.



*import* javax.microedition.midlet.*;
*import* javax.microedition.lcdui.*;

*public class* HelloMidlet *extends* MIDlet {

// The display for this MIDlet
*private* Display display;
// TextBox to display text
TextBox box = *null*;

*public* HelloMidlet() {
}

*public* *void* startApp() {
display = Display.getDisplay(*this*);
box = *new* TextBox("Simple Example", "Hello World", 20, 0);
display.setCurrent(box);
}

/**
* Pause is a no-op since there are no background activities or
* record stores that need to be closed.
*/
*public* *void* pauseApp() {
}

/**
* Destroy must cleanup everything not handled by the garbage collector.
* In this case there is nothing to cleanup.
*/
*public* *void* destroyApp(*boolean* unconditional) {
}
}



برنامه فوق یک برنامه ساده است که بترتیب زیر در netbeans آنرا بسازید.

از منوی file/new project را انتخاب کرده از پنجره java ME و Mobile Application و سپس Next و در این قسمت نام پروژه و سپس تیک Create Hello Project را بردارید.

و سپس Next و انتخاب ابزار cldc , MIdlet که هر اینجا مهم نیست هر کدام را خواستید انتخاب کنید. اما ورژن پایین تر روی گوشیهای بیشتر قابل اجرا خواهد بود.

و در نهایت Finish

 سپس از پنجره کناری Project در قسمت Source package و سپس Default Package کلیک راست کرده و گزینه  New و سپس MidLet را انتخاب کنید یا از منوی فایل new و سپس Midlet را انتخاب کنید.

در قسمت نام HelloMidlet را قرار دهید و Finish را بفشارید.

سپس برنامه ساده فوق را مانند فوق در آن تایپ کنید.

حال با اجرای برنامه شبیه ساز موبایل اجرا شده و ....


در این برنامه 


*private* Display display;

و

display = Display.getDisplay(*this*);


نشان می دهد که برای نمایش از همین کلاس استفاده شود.

 box = *new* TextBox("Simple Example", "Hello World", 20, 0);

یک تکست باکس ایجاد میکند که اولین پارامتر یک عنوان پنجره است و بعدی مقداری که در تکست باکس قرار می گیرد و ۲۰ حداکثر تعداد کاراکتری که در آن قرار می‌گیرد و ۰ نوع آن را نشان می دهد.

display.setCurrent(box);

نشان میدهد که نمایشگر موبایل این تکست باکس را بعنوان فرم اصلی نشان دهد.

----------


## rezaTavak

اگر برنامه فوق اجرا شود هیچ راهی برای خروج نداریم.

برنامه فوق را تغییر خواهیم داد که در آن یک دکمه دستور ایجاد کنیم.

ابتدا دستور:


*private* Command exitCommand; 


که برای ایجاد یک آدرس شی از نوع دکمه دستور است را اضافه می کنیم.

سپس:

exitCommand = *new* Command("Exit", Command.EXIT, 2);


برای ایجاد یک شی از نوع دستور  است. که در آن Command دارای گزینه‌های زیر است:
اولین پارامتر برچسب دکمه دستور است.
دومین پارامتر نوع دکمه است.
و سومین اولویت را مشخص میکند.
دومین پارامتر دارای مقادیر زیر می تواند باشد:
OK
BACK
CANCEL
STOP
EXIT
HELP
SCREEN
ITEM
و سومین پارامتر هر چه کمتر باشد دکمه در جایی قابل دسترستر قرار خواهد گرفت.
برای اضافه کردن دکمه دستور به فرم :

box.addCommand(exitCommand);


حال اجرای برنامه بصورت فوق فقط یک دکمه دستور ایجاد شده است بدون اینکه این دکمه کاری انجام دهد حال باید رویداد بنویسم


*implements* CommandListener 
را در انتهای تعریف کلاس بیاوریم می توانیم در آن رویداد نویسی نماییم.

یعنی :

*public class* HelloMIDlet *extends* MIDlet  *implements* CommandListener 
تغییر می دهیم.


برای رویداد هم 


*public* *void* commandAction(Command c, Displayable s) {
*if* (c == exitCommand) {
destroyApp(*false*);
notifyDestroyed();
}


حال جهت بررسی رویداد :


box.setCommandListener(*this*);




متد فوق را اضافه می کنیم که تقریبا گویا است.
destroyApp(*true*);  منابع در دسترس برنامه را از بین می‌برد.
و  notifyDestroyed();   یعنی برنامه ما تمام شود.

در نهایت برنامه به صورت زیر خواهد 


*import* javax.microedition.midlet.*;
*import* javax.microedition.lcdui.*;

*public class* HelloMidlet *extends* MIDlet *implements* CommandListener {

// The display for this MIDlet
*private* Display display;
// TextBox to display text
TextBox box = *null*;
*private* Command exitCommand; 
*public* HelloMidlet() {
}

*public* *void* startApp() {
display = Display.getDisplay(*this*);
box = *new* TextBox("Simple Example", "Hello World", 20, 0);
exitCommand = *new* Command("Exit", Command.EXIT, 0);
box.addCommand(exitCommand);
box.setCommandListener(*this*);
display.setCurrent(box);
}

/**
* Pause is a no-op since there are no background activities or
* record stores that need to be closed.
*/
*public* *void* pauseApp() {
}

/**
* Destroy must cleanup everything not handled by the garbage collector.
* In this case there is nothing to cleanup.
*/
*public* *void* destroyApp(*boolean* unconditional) {
}
*public* *void* commandAction(Command c, Displayable s) {

*if* (c == exitCommand) {

destroyApp(*true*);

notifyDestroyed();

}

}
}

----------


## rezaTavak

دانستن نوع دستگاهی که با آن کار می‌کنیم و برخی مشخصات آن در ابتدای اجرای برخی برنامه ‌ها ممکن است ضروری به نظر برسد به عنوان مثال فرض کنید شما محاسبات اعشاری در برنامه خود دارید و برنامه شما جهت cldc 1.1 کمپایل شده باشد. راه صحیح این است که برنامه در ابتدا تشخیص دهد این برنامه مناسب این ابزار است؟ یا ممکن است میزان حافظه مصرفی برنامه زیاد باشد و دستگاه نتواند آنرا اجرا کند در اینجا برنامه‌ای ارائه خواهد شد که این مشخصات را نشان دهد. در واقع همان برنامه قبلی است توضیحات را بعد از برنامه ببینید:


import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

*public class Midlet extends MIDlet implements CommandListener * {

    // The display for this MIDlet
    private Display display;
    private static final String[] properties = {
        "microedition.configuration",
        "microedition.encoding",
        "microedition.platform",
        "microedition.profiles"
    };

    // Form to display text
    Form box = null;
    private Command exitCommand = new Command("Exit",Command.EXIT,0);


*    public Midlet()* {
    }

*    public void startApp()* {
        display = Display.getDisplay(this);

        box = new Form("Properties:");
        for (int i = 0; i < properties.length; i++) {
            box.append(properties[i] + " = " +
                                System.getProperty(properties[i]));
        }
        display.setCurrent(box);
        box.addCommand(exitCommand);
        box.setCommandListener(this);
    }

    /**
     * Pause is a no-op since there are no background activities or
     * record stores that need to be closed.
     */
*    public void pauseApp()* {
    }

    /**
     * Destroy must cleanup everything not handled by the garbage collector.
     * In this case there is nothing to cleanup.
     */
*    public void destroyApp(boolean unconditional)* {
    }

*    public void commandAction(Command c, Displayable s)* {

        if (c == exitCommand) {
            destroyApp(true);
            notifyDestroyed();
            System.out.print("exit");
        }

    }

ابتدا دقت کنید که در اینجا به جای تکست باکس از فرم که یک شی دیگر برای Display است استفاده شده است. 

    private static final String[] properties = {
        "microedition.configuration",
        "microedition.encoding",
        "microedition.platform",
        "microedition.profiles"
    };
برای گرفتن مشخصات است که مثل جدول زیر است:

http://developers.sun.com/mobility/m...ns/properties/

JSR Property Name
Default Value¹   30 microedition.platform null     microedition.encoding ISO8859_1     microedition.configuration CLDC-1.0     microedition.profiles null   37 microedition.locale null     microedition.profiles MIDP-1.0   75 microedition.io.file.FileConnection.version 1.0     file.separator (impl-dep)     microedition.pim.version 1.0   118 microedition.locale null     microedition.profiles MIDP-2.0     microedition.commports (impl-dep)     microedition.hostname (impl-dep)   120 wireless.messaging.sms.smsc (impl-dep)   139 microedition.platform (impl-dep)     microedition.encoding ISO8859-1     microedition.configuration CLDC-1.1     microedition.profiles (impl-dep)   177 microedition.smartcardslots (impl-dep)   179 microedition.location.version 1.0   180 microedition.sip.version 1.0   184 microedition.m3g.version 1.0   185 microedition.jtwi.version 1.0   195 microedition.locale (impl-dep)     microedition.profiles IMP-1.0   205 wireless.messaging.sms.smsc (impl-dep)   205 wireless.messaging.mms.mmsc (impl-dep)   211 CHAPI-Version 1.0    

متد append در Form برای اضافه کردن هر نوع شی به فرم بکار میرود. 

یعنی box.append برای اضافه کردن رشته در فرم بکار می‌رود.

اما java.lang.System.getProperty  برای گرفتن مشخصات بکار می‌رود.



برنامه دیگر برای نمایش میزان حافظه:



import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

*public class MidletProperties extends MIDlet implements CommandListener * {

    // The display for this MIDlet
    private Display display;
    private static final String[] properties = {
        "microedition.configuration",
        "microedition.encoding",
        "microedition.platform",
        "microedition.profiles"
    };

    // TextBox to display text
    Form box = null;
    private Command exitCommand = new Command("Exit",Command.EXIT,0);


*    public Midlet()* {
    }

*    public void startApp()* {
        display = Display.getDisplay(this);
        StringBuffer properties1=new StringBuffer();
        box = new Form("Properties:");
        for (int i = 0; i < properties.length; i++) {
            box.append(properties[i] + " = " +
                                System.getProperty(properties[i]));
        }
        display.setCurrent(box);
        box.addCommand(exitCommand);
        box.append("Total Memory: " + Runtime.getRuntime().totalMemory()  + "\n");
        box.append("Free Memory: " + Runtime.getRuntime().freeMemory()  + "\n");


        box.setCommandListener(this);
    }

    /**
     * Pause is a no-op since there are no background activities or
     * record stores that need to be closed.
     */
*    public void pauseApp()* {
    }

    /**
     * Destroy must cleanup everything not handled by the garbage collector.
     * In this case there is nothing to cleanup.
     */
*    public void destroyApp(boolean unconditional)* {
    }

*    public void commandAction(Command c, Displayable s)* {

        if (c == exitCommand) {
            destroyApp(true);
            notifyDestroyed();
            System.out.print("exit");
        }
    }
}
برنامه زیر تمام مشخصات را نشان میدهد:



import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class Midlet extends MIDlet implements CommandListener  {

    // The display for this MIDlet
    private Display display;
    private static final String[] properties = {
        "microedition.configuration",
        "microedition.encoding",
        "microedition.platform",
        "microedition.profiles",
        "microedition.locale",
        "icroedition.io.file.FileConnection.version",
        "file.separator",
        "microedition.pim.version",
        "microedition.locale",
        "microedition.commports",
        "microedition.hostname",
        "wireless.messaging.sms.smsc",
        "microedition.smartcardslots",
        "microedition.location.version",
        "microedition.sip.version",
        "microedition.m3g.version",
        "microedition.jtwi.version",
        "microedition.locale",
        "wireless.messaging.sms.smsc",
        "wireless.messaging.mms.mmsc",
        "CHAPI-Version"

    };

    // TextBox to display text
    Form box = null;
    private Command exitCommand = new Command("Exit",Command.EXIT,0);


    public Midlet() {
    }

    public void startApp() {
        display = Display.getDisplay(this);
        StringBuffer properties1=new StringBuffer();
        box = new Form("Properties:");
        for (int i = 0; i < properties.length; i++) {
            box.append(properties[i] + " = " +
                                System.getProperty(properties[i]));
        }
        box.append("Total Memory: " + Runtime.getRuntime().totalMemory()  + "\n");
        box.append("Free Memory: " + Runtime.getRuntime().freeMemory()  + "\n");
        display.setCurrent(box);
        box.addCommand(exitCommand);
        box.setCommandListener(this);
    }

    /**
     * Pause is a no-op since there are no background activities or
     * record stores that need to be closed.
     */
    public void pauseApp() {
    }

    /**
     * Destroy must cleanup everything not handled by the garbage collector.
     * In this case there is nothing to cleanup.
     */
    public void destroyApp(boolean unconditional) {
    }

    public void commandAction(Command c, Displayable s) {

        if (c == exitCommand) {
            destroyApp(true);
            notifyDestroyed();
            System.out.print("exit");
        }
    }
}



مقادیر بیش از اینها هستند که در بالا لیست شده اند شما برای هر مقدار باید به JSR مربوطه مراجعه کنید. مثلا :
"microedition.media.version", "supports.mixing",
"supports.audio.capture", "supports.video.capture", "supports.recording", "audio.encodings",
"video.encodings", "video.snapshot.encodings", "streamable.contents"

از مشخصات دیگری است که در مولتی مدیا است. 

http://download-llnw.oracle.com/java...w-summary.html

----------


## rezaTavak

اضافه کردن یک TextField  به فرم:

برنامه زیر را نگاه کنید:




import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

public class TextField1 extends MIDlet implements CommandListener {
  protected Display display;
  protected boolean started;
  Command exitCommand = new Command("Exit",Command.EXIT,0);

  protected void startApp() {
    if (!started) {
      display = Display.getDisplay(this);
      Form form = new Form("Item Layout");

      TextField txtField1 = new TextField("Name", "J. Doe", 32, TextField.ANY);
      form.append(txtField1);
      form.addCommand(exitCommand);
      form.setCommandListener(this);
      display.setCurrent(form);
      started = true;
    }
  }

  protected void pauseApp() {
  }

  protected void destroyApp(boolean unconditional) {
  }
    public void commandAction(Command c, Displayable s) {

        if (c == exitCommand) {
            destroyApp(true);
            notifyDestroyed();
            System.out.print("exit");
        }
    }

}



در این کلاس :



 TextField txtField1 = new TextField("Name", "J. Doe", 32, TextField.ANY);

یک تکست باکس جدید تعریف میکند. اولین پارامتر عبارتی است که قبل از آن نمایش داده می‌شود. دومین عبارتی است که داخل تکست باکس قرار می‌گیرد. سومین حداکثر طول و چهارمین نوع آن است که شامل :
ANY هر نوع کاراکتر
TextField.EMAILADDR
فقط آدرس ایمیل
TextField.NUMERIC
فقط عدد
TextField.PHONENUMBER
شماره تلفن
TextField.URL
آدرس اینترنتی
TextField.PASSWORD

رمز

البته دقت کنید بصورت زیر هم می تواند باشد:

TextField.PASSWORD | TextField.ANY

----------


## rezaTavak

امروز عنصر دیگری از که قابل ایجاد در فرم است را معرفی میکنم :



*import* javax.microedition.lcdui.*;
*import* javax.microedition.midlet.MIDlet;

*public class* GaugeTracker *extends* MIDlet *implements* ItemStateListener, CommandListener {
*private* Gauge mGauge = *new* Gauge("GaugeTitle", true, 5, 3);

*private* StringItem mStringItem = *new* StringItem(null, "[value]");

*public* GaugeTracker() {
itemStateChanged(mGauge);
}

*public* *void* itemStateChanged(Item item) {
*if* (item == mGauge)
mStringItem.setText("Value = " + mGauge.getValue());
}

*public* *void* commandAction(Command c, Displayable s) {
*if* (c.getCommandType() == Command.EXIT)
notifyDestroyed();
}

*public* *void* startApp() {
Form *form* = *new* Form("GaugeTracker");
*form*.addCommand(*new* Command("Exit", Command.EXIT, 0));
*form*.setCommandListener(*this*);
// Now add the selected items.
*form*.append(mGauge);
*form*.append(mStringItem);
*form*.setItemStateListener(*this*);

Display.getDisplay(*this*).setCurrent(*form*);
}

*public* *void* pauseApp() {
}

*public* *void* destroyApp(*boolean* unconditional) {
}
}



حال شرح برنامه :

*implements* ItemStateListener, CommandListener


که برای نگاه به رویدادها است ItemStateListener  برای رویدادهایی بکار میرود که بصورت Item در فرم قرار می‌گیرند. این Item ها تا کنون دو مورد آن معرفی شده است یکی TextField و دیگری Gauge که برنامه امروز است. خاطر نشان می‌شود فقط عناصری که از روی کلاس Item ساخته شده باشند می‌توانند در داخل فرم قرار گیرند. کم کم با این عناصر آشنا خواهیم شد.



 *private* Gauge mGauge = *new* Gauge("GaugeTitle", true, 5, 3);



یک گیج (فارسی آن عقربه و پیمانه یا فشار سنج است) ایجاد میکند که اولین پارامتر عنوان آن دومین پارامتر آیا کاربر اجازه تغییر را دارد؟ سومین پارامتر بیشترین مقدار چقدر باشد و چهارمین پارامتر مقدار اولیه چقدر باشد؟

 *private* StringItem mStringItem = *new* StringItem(null, "[value]");

عنصر دیگری است که از روی کلاس Item ساخته می‌شود. پارامتر اول برچسب و دومی مقدار رشته است. 
اگر بخواهیم کنترل روی نوشته‌ای که در صفحه قرار می‌دهیم داشته باشیم از این شی استفاده می کنیم. شما قبلا از متد append در فرم یاد گرفته‌اید که می‌توان رشته‌ای را در صفحه قرار داد.


*public* GaugeTracker() {
itemStateChanged(mGauge);
}



سازنده شی است که در ابتدای ساخت مقدار gauge را نشان بدهد.



*public* *void* itemStateChanged(Item item) {
*if* (item == mGauge)
mStringItem.setText("Value = " + mGauge.getValue());
}




متد فوق در کلاس ItemStateListener جایگزین خواهد شد و به رویدادهایی پاسخ می‌دهد که از Item های روی فرم شنیده شده باشند.



*form*.setItemStateListener(*this*);



برای تنظیم جهت دهی به رویدادهایی است که در فرم اتفاق می‌افتد و عامل آن یکی از Item های فرم باشد.

----------


## rezaTavak

اگر gauge در دومین پارامتر خود مقدار false را داشته باشد قابل تغییر توسط کاربر نبوده و برای ProcessBar استفاده خواهد شد. شکل آن هم عوض خواهد شد (از شکل صعودی به شکل یکنواخت)

----------


## rezaTavak

آیتم بعدی که می توان بر روی فرم قرار داد تاریخ و زمان است:



 *import* java.util.Calendar;

*import* javax.microedition.lcdui.DateField;
*import* javax.microedition.lcdui.Display;
*import* javax.microedition.lcdui.Form;
*import* javax.microedition.midlet.MIDlet;

*public class* DateFieldTIME *extends* MIDlet {
*protected* Display display;

*protected* *void* startApp() {
display = Display.getDisplay(*this*);

Form *form* = *new* Form("Demo");

*form*.append("line");

DateField timeOnly = *new* DateField("Time", DateField.TIME);
timeOnly.setDate(Calendar.getInstance().getTime());
*form*.append(timeOnly);

display.setCurrent(*form*);
}

*protected* *void* pauseApp() {
}

*protected* *void* destroyApp(*boolean* unconditional) {
}
}



برنامه تقریبا گویا است 



DateField timeOnly = *new* DateField("Time", DateField.TIME);
timeOnly.setDate(Calendar.getInstance().getTime());




برای ساختن شی DateField دو پارامتر نیاز است اول برچسبی که نمایش داده می‌شود و دومین نوع آن است که می‌تواند :
DateField.DATE, DateField.TIME, or DateField.DATE_TIME.

باشد. که اولی فقط تاریخ دومی فقط زمان و سومی هم تاریخ و هم زمان است.

خط دوم متدی را معرفی می کند که برای تنظیم تاریخ و زمان بکار می‌رود.



امروز چیزی جدید هم یاد بگیریم بد نیست نگاه به کلاس اصلی DateField بیاندازیم:


public class DateField extends Item {
// Public Constructors
public DateField( String label, int mode);
public DateField(String label, int mode,
java.util.TimeZone timeZone);
// Public Constants
public static final int DATE;
public static final int DATE_TIME;
public static final int TIME;
// Public Instance Methods
public java.util.Date getDate();
public int getInputMode();
public void setDate( java.util.Date date);
public void setInputMode( int mode);
// Public Methods Overriding Item
public void setLabel( String label);
}




می بینیم که یک کلاس که بخواهد درون فرم قرار گیرد باید از روی Item ساخته شود. 

کلاس Item هم به شکل زیر تعریف می‌شود:



public abstract class Item {
// No Constructor
// Public Instance Methods
public String getLabel();
public void setLabel( String label);
}



همه کلاسهایی که روی فرم باشند از روی کلاس بالا ساخته می‌شوند.

با نگاهی به این کلاسها کلیه مواردی که باید دستگیرتان خواهد شد.
http://download.oracle.com/javame/co...cdui/Item.html


http://download.oracle.com/javame/co...DateField.html

----------


## rezaTavak

کلاس بعدی که می تواند در داخل Screen قرار گیرد (یعنی داخلAlert, Form, List, TextBox)


کلاس :

*Ticker*

است که بصورت یک نوشته در حال حرکت در بالای تمام screen ها می ‌توان از آن استفاده کرد. با دستورات



Ticker aTicker = *new* Ticker("ticker");
Screenable.setTicker(aTicker);



در دستور اول شی ساخته می‌شود و دستور دوم آنرا به شئی از نوع Screen اضافه خواهد کرد.



 *import* javax.microedition.lcdui.Command;
*import* javax.microedition.lcdui.CommandListener;
*import* javax.microedition.lcdui.Display;
*import* javax.microedition.lcdui.Displayable;
*import* javax.microedition.lcdui.TextBox;
*import* javax.microedition.lcdui.Ticker;
*import* javax.microedition.midlet.MIDlet;

*public class* J2MEappendTicker *extends* MIDlet *implements* CommandListener {
*private* Command exitCommand  = *new* Command("cmd", Command.EXIT, 1);

*private* Display display;

*public* J2MEappendTicker() {
display = Display.getDisplay(*this*);
}

*public* *void* startApp() {
TextBox t = *new* TextBox("Hello", "Welcome to MIDP Programming", 256, 0);
Ticker aTicker = *new* Ticker("ticker");
t.setTicker(aTicker);
t.addCommand(exitCommand);
t.setCommandListener(*this*);
display.setCurrent(t);
}

*public* *void* pauseApp() {
}

*public* *void* destroyApp(*boolean* unconditional) {
}

*public* *void* commandAction(Command c, Displayable s) {
*if* (c == exitCommand) {
destroyApp(*false*);
notifyDestroyed();
}
}
}





یک مثال است.


این کلاس بصورت زیر تعریف شده است:




public class Ticker {
// Public Constructors
public Ticker( String str);
// Public Instance Methods
public String getString();
public void setString( String str);
}



که سازنده آن فقط یک رشته نیاز دارد و برای تغییر این رشته دو متد تعریف شده است.

در هر کلاسی که از روی Screen  ساخته شود دو متد وجود دارد که برای تنظیم کردن Ticker است کلاس Screen  :



public abstract class Screen extends Displayable {
// No Constructor
// Public Instance Methods
public Ticker getTicker();
public String getTitle();
public void setTicker( Ticker ticker);
public void setTitle( String s);
}




که می بینید این کلاس فقط این متدها را برای Ticker دارد.

اما بد نیست به کلاس Displayable هم نگاهی بیاندازیم:




public abstract class Displayable {
// No Constructor
// Public Instance Methods
public void addCommand( Command cmd);
public boolean isShown();
public void removeCommand( Command cmd);
public void setCommandListener( CommandListener l);
}

----------


## rezaTavak

با توجه به توضیحات فوق کلاسهایی که در lcdui تعریف شده مانند زیر است:




* Class Hierarchy* 

 
class java.lang.*Object*
class javax.microedition.lcdui.*AlertType*class javax.microedition.lcdui.*Command*class javax.microedition.lcdui.*Display*class javax.microedition.lcdui.*Displayable*
class javax.microedition.lcdui.*Canvas*class javax.microedition.lcdui.*Screen*
class javax.microedition.lcdui.*Alert*class javax.microedition.lcdui.*Form*class javax.microedition.lcdui.*List* (implements javax.microedition.lcdui.Choice)class javax.microedition.lcdui.*TextBox*class javax.microedition.lcdui.*Font*class javax.microedition.lcdui.*Graphics*class javax.microedition.lcdui.*Image*class javax.microedition.lcdui.*Item*
class javax.microedition.lcdui.*ChoiceGroup* (implements javax.microedition.lcdui.Choice)class javax.microedition.lcdui.*DateField*class javax.microedition.lcdui.*Gauge*class javax.microedition.lcdui.*ImageItem*class javax.microedition.lcdui.*StringItem*class javax.microedition.lcdui.*TextField*class javax.microedition.lcdui.*Ticker*
* Interface Hierarchy* 


interface javax.microedition.lcdui.*Choice*interface javax.microedition.lcdui.*CommandListener*interface javax.microedition.lcdui.*ItemStateListener*




کل پکیجهای موجود در MID هم بقرار زیر است





* MID Profile*

      *User Interface Package*   *javax.microedition.lcdui* The UI API provides a set of features for implementation of user  interfaces for MIDP applications.          *Persistence Package*   *javax.microedition.rms* The Mobile Information Device Profile provides a mechanism for MIDlets to persistently store data and later retrieve it.    
      *Application Lifecycle Package*   *javax.microedition.midlet* The MIDlet package defines Mobile Information Device  Profile applications and the interactions between the application and  the environment in which the application runs.
    
      *Networking Package*   *javax.microedition.io*  MID Profile includes networking support based on the      GenericConnection framework from the _Connected     Limited Device Configuration_.    
      *Core Packages*   *java.io* Provides for system input and output through data streams.   *java.lang* MID Profile Language Classes included from Java 2 Standard     Edition.   *java.util* MID Profile Utility Classes included from Java 2 Standard     Edition.

----------


## rezaTavak

تا اینجا بدنه یک برنامه برای موبایل را یاد گرفتیم. برخی از عناصر سطح بالای ارتباط با کاربر را فرا گرفتیم.

اما در ادامه عنصر دیگر را معرفی خواهیم کرد که قابل استفاده در فرم است.

به ماثل زیر دقت کنید:





 *import* java.io.IOException;

*import* javax.microedition.lcdui.ChoiceGroup;
*import* javax.microedition.lcdui.Display;
*import* javax.microedition.lcdui.Form;
*import* javax.microedition.lcdui.Image;
*import* javax.microedition.midlet.MIDlet;

*public class* ChoiceGroupMIDlet *extends* MIDlet {
*protected* Display display;

*protected* *void* startApp() {
display = Display.getDisplay(*this*);

Form *form* = *new* Form("Demo");

*form*.append("line");
*try* {
Image red = Image.createImage("/red.png");
Image green = Image.createImage("/green.png");
Image blue = Image.createImage("/blue.png");

String[] strings = *new* String[] { "Red", "Green", "Blue" };
Image[] images = *new* Image[] { red, green, blue };
ChoiceGroup exGroup = *new* ChoiceGroup("Choose one", ChoiceGroup.EXCLUSIVE,
strings, images);
*form*.append(exGroup);
ChoiceGroup multiGroup = *new* ChoiceGroup("Choose any", ChoiceGroup.MULTIPLE);
*form*.append(multiGroup);
multiGroup.append("Use SSL", *null*);
multiGroup.append("Reconnect on failure", *null*);
multiGroup.append("Enable tracing", *null*);
} *catch* (IOException ex) {
*form*.append("Failed to load images");
}


display.setCurrent(*form*);
}

*protected* *void* pauseApp() {
}

*protected* *void* destroyApp(*boolean* unconditional) {
}
}


عنصر جدید در این فرم choice  است که در :



ChoiceGroup exGroup = *new* ChoiceGroup("Choose one", ChoiceGroup.EXCLUSIVE,
strings, images);

تعریف شده است دقت کنید پارامترهای این شی را که ایجاد شده اند :
اولی برچسب است
دومی نوع آن است که می‌تواند بصورتهای: EXCLUSIVE or MULTIPLE است یعنی از بین گزینه ها فقط بتوان یکی را انتخاب کرد یا چند تا البته شکل آن هم فرق میکند شکل انحصاری (یکی انتخاب شود) بصورت دکمه دستور رادیویی است (رادیوهای ضبط قدیمی برای تعویض کانال یا دستور دارای دکمه هایی بودند که انتخاب یکی دیگری به بالا می پرید و فقط در هر لحظه یکی قابل انتخاب بود.) یا بصورت چک باکس (یک مربع در آن یک ضربدر یا تیک باشد) 
سومین پارامتر آرایه‌ای است که هر یک از برچسبهایی که در این دستور نمایش داده می‌شود در آن ذخیره شده است و چهارمین پارامتر هم عکسهایی است که در کنار دکمه قرار می‌گیرد.

جلوتر خواهید دید که این تعریف بصورت فقط دو پارامتر اولی هم می‌تواند باشد.

دقت کنید در مسیر src باید عکسهای مورد استفاده باشد اگر آنها را نمی  خواهید برنامه را بصورت زیر ویرایش کنید :



/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package hello;

import java.io.IOException;

import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.midlet.MIDlet;

public class ChoiceMidlet extends MIDlet {
  protected Display display;

  protected void startApp() {
    display = Display.getDisplay(this);

    Form form = new Form("Demo");

    form.append("line");
        try {
          /*Image red = Image.createImage("/red.png");
          Image green = Image.createImage("/green.png");
          Image blue = Image.createImage("/blue.png");*/

          String[] strings = new String[] { "Red", "Green", "Blue" };
          //Image[] images = new Image[] { red, green, blue };
          ChoiceGroup exGroup = new ChoiceGroup("Choose one", ChoiceGroup.EXCLUSIVE,
                                                      strings, null);
          form.append(exGroup);
          ChoiceGroup multiGroup = new ChoiceGroup("Choose any", ChoiceGroup.MULTIPLE);
          form.append(multiGroup);
          multiGroup.append("Use SSL", null);
          multiGroup.append("Reconnect on failure", null);
          multiGroup.append("Enable tracing", null);
       } catch (Exception ex) {
          form.append("Failed to load images");
       }


    display.setCurrent(form);
  }

  protected void pauseApp() {
  }

  protected void destroyApp(boolean unconditional) {
  }
}


در واقع سازنده کلاس به دو صورت چهار پارامتری و دو پارامتری تعریف شده است. 

یعنی شی دوم بصورت دو پارامتری تعریف شده است:



ChoiceGroup multiGroup = *new* ChoiceGroup("Choose any", ChoiceGroup.MULTIPLE);

برای اضافه کردن عنصر به دومی از :



multiGroup.append("Use SSL", *null*);

استفاده شده که اولی برچسب و دومی عکسی است که استفاده می‌شود.

http://download.oracle.com/javame/co...oiceGroup.html

اطلاعات این کلاس و شئی که ساخته می‌شود را به شما نشان میدهد.
 اگر بخواهیم بدانیم این شی ما چند عنصر دارد از size استفاده می‌‌شود.

* getString برای برگردانیدن یک مقدار ر
*

برچسب و...

اما 
*isSelected*


برای اینکه بدانیم یک عنصر انتخاب شده یا نه که دارای یک پارامتر که عددی بین صفر و size() - 1  است به آن ارسال می‌شود.

*getSelectedIndex*() 

هم برای دکمه های رادیویی است که شماره دکمه انتخاب شده را باز می‌کرداند اگر -۱ بود یعنی هیچیک انتخاب نشده است دقت کنید عددی بین صفر و size()- 1 است.

----------


## rezaTavak

شی امروز قرار دادن عکس در فرم است که راهنمای آن در :

http://download.oracle.com/javame/co...ImageItem.html
است.

حال یک برنامه ساده در این خصوص خواهیم نوشت _اما دقت کنید که عکسی که استفاده میکند فرمت png داشته باشد._ و آنرا در جایی که پروژه شما است در src  قرار دهید. اگر درون شاخه خاصی قرار میدهید باید نام شاخه را ذکر کنید یک / زده سپس نام قایل را قرار دهید.


 *import* java.io.IOException;

*import* javax.microedition.lcdui.Display;
*import* javax.microedition.lcdui.Form;
*import* javax.microedition.lcdui.Image;
*import* javax.microedition.lcdui.ImageItem;
*import* javax.microedition.midlet.MIDlet;

*public class* ImageItemLAYOUT_CENTER *extends* MIDlet {
*protected* Display display;

*protected* *void* startApp() {
display = Display.getDisplay(*this*);

Form *form* = *new* Form("Demo");

*form*.append("line");
*try* {
Image red = Image.createImage("/red.png");
*form*.append(*new* ImageItem("Center", red, ImageItem.LAYOUT_CENTER, *null*));
} *catch* (IOException ex) {
*form*.append("Failed to load images");
}
display.setCurrent(*form*);
}

*protected* *void* pauseApp() {
}

*protected* *void* destroyApp(*boolean* unconditional) {
}
}



فقط :




Image red = Image.createImage("/red.png");
*form*.append(*new* ImageItem("Center", red, ImageItem.LAYOUT_CENTER, *null*));





جدید است که اولین خط یک شی از نوع Image می سازد که می تواند پارامتر آن نام فایل باشد سازنده های دیگر را از http://download.oracle.com/javame/co...dui/Image.html
ببینید.
خط دوم برای ساختن ImageItem   است که روی فرم قرار می‌گیرد. اما پارامترهای آن:

اولین پارامتر عنوان یا برچسب
دومین پارامتر شی عکس از نوع Image
سومین پارامتر نحوه قرارگیری یا Layout است که مقادیر زیر را می‌تواند داشته باشد:
* LAYOUT_DEFAULT*

LAYOUT_LEFT
LAYOUT_RIGHT
LAYOUT_CENTER
LAYOUT_NEWLINE_BEFORE
LAYOUT_NEWLINE_AFTER دقت کنید که ترکیب اینها هم می تواند باشد مثلا LAYOUT_CENTER | LAYOUT_NEWLINE_AFTER

پارامتر چهارم هم اگر عکس قابل نمایش توسط دستگاه نباشد متن نوشته شده در این پارامتر نشان داده می‌شود.

----------


## rezaTavak

تا کنون دو نوع از عناصر screen را یاد گرفتیم که *Form و* *TextBox است. فقط دو عنصر دیگر مانده است که اولین آن لیست * *List**است که از روی کلاس*  (implements javax.microedition.lcdui.Choice) ساخته می شود.

یک مثال کار را برای ما روشن خواهد ساخت:



 *import* javax.microedition.lcdui.Choice;
*import* javax.microedition.lcdui.Display;
*import* javax.microedition.lcdui.List;
*import* javax.microedition.midlet.MIDlet;

*public class* PaymentMIDlet *extends* MIDlet {
*private* Display display;

List options = *new* List("Method of Payment", Choice.EXCLUSIVE);

*public* *void* startApp() {
display = Display.getDisplay(*this*);
options.append("Visa", *null*);
options.append("MasterCard", *null*);
options.append("Amex", *null*);
display.setCurrent(options);
}

*public* *void* pauseApp() {
}

*public* *void* destroyApp(*boolean* unconditional) {
}
}


که یک شی توسط دستور :



List options = *new* List("Method of Payment", Choice.EXCLUSIVE);

ساخته می‌شود. پارامتر اول عنوان یا برچسب و دومی نوع لیست است که یکی از مقادیر زیر است:

EXCLUSIVE,   IMPLICIT,   MULTIPLE

EXCLUSIVE لیستی با دکمه رادیویی نشان میدهد
IMPLICIT    لیستی مانند یک منو بشما نشان میدهد
MULTIPLE  لیستی که در کنار آن چک باکس است نشان میدهد و قابلیت چند انتخابی را به شما خواهد داد.


سپس یکی یکی عناصر آن توسط دستور append که دارای دو پارامتر است که اولی برچسب منو و دومی یک Image که در کنار برچسب قرار گیرد را اضافه می کنیم. مانند :



options.append("Visa", *null*);
options.append("MasterCard", *null*);
options.append("Amex", *null*);





مانند ChoiseGroup  شما برای گرفتن مقدار انتخاب شده کاربر از    int *getSelectedIndex*() و برای چند انتخابی از   int *getSelectedFlags*(boolean[] selectedArray_return 

استفاده کنید.

----------


## rezaTavak

به کد زیر دقت کنید:



*import* javax.microedition.lcdui.*;
*import* javax.microedition.midlet.*;


*public class* DisplayAlert *extends* MIDlet *implements* CommandListener {
*private* Display display;

*private* Alert alert;

*private* Form *form* = *new* Form("Throw Exception");

*private* Command exit = *new* Command("Exit", Command.SCREEN, 1);

*private* *boolean* exitFlag = *false*;

*public* DisplayAlert() {
display = Display.getDisplay(*this*);
*form*.addCommand(exit);
*form*.setCommandListener(*this*);
}

*public* *void* startApp() {
display.setCurrent(*form*);
}

*public* *void* pauseApp() {
}

*public* *void* destroyApp(*boolean* unconditional) *throws* MIDletStateChangeException {
*if* (unconditional == *false*) {
*throw new* MIDletStateChangeException();
}
}

*public* *void* commandAction(Command command, Displayable displayable) {
*if* (command == exit) {
*try* {
*if* (exitFlag == *false*) {
alert = *new* Alert("Busy", "Please try again.", null, AlertType.WARNING);
alert.setTimeout(Alert.FOREVER);
display.setCurrent(alert, *form*);
destroyApp(*false*);
} *else* {
destroyApp(*true*);
notifyDestroyed();
}
} *catch* (Exception exception) {
exitFlag = *true*;
}
}
}
}

فرم دیگری که می‌توان استفاده کرد Alert است که برای اخطار به کاربر استفاده می‌شود و سازنده آن :



*Alert*(String title)   Constructs a new, empty Alert object with the given title. 
*Alert*(String title,       String alertText,       Image alertImage,       AlertType alertType)   Constructs a new Alert object with the given title, content  string and image, and alert type.


است که در اینجا :



alert = *new* Alert("Busy", "Please try again.", null, AlertType.WARNING);

پارامتر اول عنوان صفحه است دوم متنی است که باید نمایش داده شود سومی یک عکس است که اینجا آورده نشده است و چهارمی هم نوع آن است که شامل:

 static AlertType *ALARM*   An ALARM AlertType is a hint to alert the user to an event for which  the user has previously requested to be notified. 
 static AlertType *CONFIRMATION*   A CONFIRMATION AlertType is a hint to confirm user actions. 
 static AlertType *ERROR*   An ERROR AlertType is a hint to alert the user to an erroneous operation. 
 static AlertType *INFO*   An INFO AlertType typically provides non-threatening information to the  user. 
 static AlertType *WARNING*   A WARNING AlertType is a hint to warn the user of a potentially  dangerous operation.   



که بترتیب برای رویداد، تایید، خطا، نمایش اطلاعات و اخطار بکار می‌روند.



alert.setTimeout(Alert.FOREVER);

چون می‌توان نمایش را برای این نوع بصورت زمانی تعریف کرد و غیر زمانی در اینجا غیر زمانی تعریف شده است در غیر این صورت یک عدد که نشاندهنده میلی ثانیه باید بعنوان پارامتر ارسال کنید مثلا ۲۰۰۰ برای ۲ ثانیه.



display.setCurrent(alert, *form*);

صفحه بعدی برای نمایش alert را به برنامه می‌گوید.



void *setCurrent*(Alert alert,            Displayable nextDisplayable)  
           Requests that this Alert be made current, and that nextDisplayable be   made current  after the Alert is dismissed.    


void *setCurrent*(Displayable nextDisplayable)  
           Requests that a different Displayable object be made visible on the  display.


این دو تابع که در  Display تعریف شده اند به دو صورت فوق هستند یعنی نمایش یک صفحه یا نمایش Alert و سپس صفحه بعدی آن.


display.setCurrent(*form*);


هم نمونه دیگر است پس برای تغییر از یک فرم به فرم دیگر هم از این متد استفاده کنیم/

----------


## pejman181818

فقط میتونم بگم عالی بود
حالا اگه سوالی داشتم حتما مزاحم میشم! :قلب:  :قلب:

----------


## rezaTavak

بوم نقاشی

تا به حال صفحات و شی های سطح بالا را بررسی کردیم.

حال به سطوح پایین نگاه می‌کنیم. منظور در این سطوح همه چیز باید توسط شما بوجود آورده شود. مثلا خواندن کلیدها و...

برای اینکار بایستی از کلاسی استفاده شود که در آن بتوان مانور داد اول به برنامه زیر نگاه کنیم:


 *import* javax.microedition.lcdui.Canvas;
*import* javax.microedition.lcdui.Display;
*import* javax.microedition.lcdui.Graphics;
*import* javax.microedition.midlet.MIDlet;

*public class* CanvasMyMidlet *extends* MIDlet {
*public* CanvasMyMidlet() { // constructor
}

*public* *void* startApp() {
Canvas canvas = *new* MyCanvas();
Display display = Display.getDisplay(*this*);
display.setCurrent(canvas);
}

*public* *void* pauseApp() {
}

*public* *void* destroyApp(*boolean* unconditional) {
}
}

*class* MyCanvas *extends* Canvas {
*public* *void* paint(Graphics g) {
g.setColor(255, 0, 0);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(255, 255, 255);
g.drawString("Hello World!", 0, 0, g.TOP | g.LEFT);
}
}



کلاس *Canvas برای سطوح پایین دسترسی به عناصر موبایل استفاده می‌شود. دقت کنید کلاس* *Displayable* شامل دو کلاس 



class javax.microedition.lcdui.*Canvas*class javax.microedition.lcdui.*Screen*



است که قبلا در مورد Screen و کلاسهای زیر مجموعه آن برنامه‌هایی دیدیم.

در حقیقت برای برنامه نویسی بازی از این کلاس استفاده می‌شود همچنین فونتهای فارسی در این کلاس قابل ساخت است.

برنامه‌هایی که ظاهری متفاوت دارند از این کلاس بهره برده اند.

www.*j2mepolish*.org  یکی از ابزارهایی است که بسیاری از چیزها را در این محیط برای شما فراهم کرده است.

 شرح برنامه:


Canvas canvas = *new* MyCanvas();

یک شی از روی کلاس   MyCanvas  می سازد. در داخل این کلاس متد paint وجود دارد که *paint*(Graphics g) اصلی ترین عنصر یک کلاس canvas است. در این متد یک عنصر گرافیکی از نوع Graphics ارسال شده و canvas در اولین باری که اجرا شود آنرا اجرا می‌کند.

کلاس دیگری هم در این راستا وجود دارد:

*repaint*()  
یا 
*repaint*(int x,         int y,         int width,         int height)  

در دفعات بعدی صدا زده می‌شود.

عنصر Graphics مانند همان چیزی است که در java.awt.Graphics می‌شناسید اما مشخصات آن کمی متفاوت است. (اینجا cldc است نه pc)

اینجا متدهای بسیار زیادی وجود دارد که برای دستابی به عناصر گرافیکی مانند دایره، مربع و... کاربر دارد.

لیست کامل را از روی کلاس بخوانید.


g.setColor(255, 0, 0);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(255, 255, 255);
g.drawString("Hello World!", 0, 0, g.TOP | g.LEFT);

خط اول رنگ را قرمز میکند
خط دوم یک مستطیل به ابعاد صفحه نمایش می کشد. دقت کنید برای ابعاد از دو متد getWidth(), getHeight() کمک گرفته شده است. سپس رنگ سفید شده و یک عبارت نوشته می‌شود.



display.setCurrent(canvas);



هم برای عنصر Displayable از کلاس canvas استفاده کند.

----------


## rezaTavak

بوم نقاشی

تا به حال صفحات و شی های سطح بالا را بررسی کردیم.

حال به سطوح پایین نگاه می‌کنیم. منظور در این سطوح همه چیز باید توسط شما بوجود آورده شود. مثلا خواندن کلیدها و...

برای اینکار بایستی از کلاسی استفاده شود که در آن بتوان مانور داد اول به برنامه زیر نگاه کنیم:


 *import* javax.microedition.lcdui.Canvas;
*import* javax.microedition.lcdui.Display;
*import* javax.microedition.lcdui.Graphics;
*import* javax.microedition.midlet.MIDlet;

*public class* CanvasMyMidlet *extends* MIDlet {
*public* CanvasMyMidlet() { // constructor
}

*public* *void* startApp() {
Canvas canvas = *new* MyCanvas();
Display display = Display.getDisplay(*this*);
display.setCurrent(canvas);
}

*public* *void* pauseApp() {
}

*public* *void* destroyApp(*boolean* unconditional) {
}
}

*class* MyCanvas *extends* Canvas {
*public* *void* paint(Graphics g) {
g.setColor(255, 0, 0);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(255, 255, 255);
g.drawString("Hello World!", 0, 0, g.TOP | g.LEFT);
}
}



کلاس *Canvas برای سطوح پایین دسترسی به عناصر موبایل استفاده می‌شود. دقت کنید کلاس* *Displayable* شامل دو کلاس 



class javax.microedition.lcdui.*Canvas*class javax.microedition.lcdui.*Screen*



است که قبلا در مورد Screen و کلاسهای زیر مجموعه آن برنامه‌هایی دیدیم.

در حقیقت برای برنامه نویسی بازی از این کلاس استفاده می‌شود همچنین فونتهای فارسی در این کلاس قابل ساخت است.

برنامه‌هایی که ظاهری متفاوت دارند از این کلاس بهره برده اند.

www.*j2mepolish*.org  یکی از ابزارهایی است که بسیاری از چیزها را در این محیط برای شما فراهم کرده است.

 شرح برنامه:


Canvas canvas = *new* MyCanvas();

یک شی از روی کلاس   MyCanvas  می سازد. در داخل این کلاس متد paint وجود دارد که *paint*(Graphics g) اصلی ترین عنصر یک کلاس canvas است. در این متد یک عنصر گرافیکی از نوع Graphics ارسال شده و canvas در اولین باری که اجرا شود آنرا اجرا می‌کند.

کلاس دیگری هم در این راستا وجود دارد:

*repaint*()  
یا 
*repaint*(int x,         int y,         int width,         int height)  

در دفعات بعدی صدا زده می‌شود.

عنصر Graphics مانند همان چیزی است که در java.awt.Graphics می‌شناسید اما مشخصات آن کمی متفاوت است. (اینجا cldc است نه pc)

اینجا متدهای بسیار زیادی وجود دارد که برای دستابی به عناصر گرافیکی مانند دایره، مربع و... کاربر دارد.

لیست کامل را از روی کلاس بخوانید.


g.setColor(255, 0, 0);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(255, 255, 255);
g.drawString("Hello World!", 0, 0, g.TOP | g.LEFT);

خط اول رنگ را قرمز میکند
خط دوم یک مستطیل به ابعاد صفحه نمایش می کشد. دقت کنید برای ابعاد از دو متد getWidth(), getHeight() کمک گرفته شده است. سپس رنگ سفید شده و یک عبارت نوشته می‌شود.



display.setCurrent(canvas);



هم برای عنصر Displayable از کلاس canvas استفاده کند.

----------


## rezaTavak

یکی از خاصیتهای Canvas این است که می توان در آن به ضرب کلیدها پاسخ گفت.

به برنامه زیر دقت کنید:



/*
J2ME: The Complete Reference

James Keogh

Publisher: McGraw-Hill

ISBN 0072227109

*/
//jad file (please verify the jar size)
/*
MIDlet-Name: KeyCodeExample
MIDlet-Version: 1.0
MIDlet-Vendor: MyCompany
MIDlet-Jar-URL: KeyCodeExample.jar
MIDlet-1: KeyCodeExample, , KeyCodeExample
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-1.0
MIDlet-JAR-SIZE: 100

*/
*import* javax.microedition.midlet.*;
*import* javax.microedition.lcdui.*;
*public class* KeyCodeExample *extends* MIDlet
{
*private* Display  display;       
*private* MyCanvas canvas;   
*public* KeyCodeExample ()
{
display = Display.getDisplay(*this*);
canvas  = *new* MyCanvas(*this*);
}
*protected* *void* startApp()
{
display.setCurrent(canvas);
}
*protected* *void* pauseApp()
{ 
}
*protected* *void* destroyApp( *boolean* unconditional )
{ 
}
*public* *void* exitMIDlet()
{
destroyApp(*true*);
notifyDestroyed();
}
}
*class* MyCanvas *extends* Canvas *implements* CommandListener
{
*private* Command exit;          
*private* String direction;
*private* KeyCodeExample keyCodeExample;
*public* MyCanvas (KeyCodeExample keyCodeExample)
{
direction = "2=up 8=dn 4=lt 6=rt";    
*this*.keyCodeExample = keyCodeExample;
exit = *new* Command("Exit", Command.EXIT, 1);
addCommand(exit);
setCommandListener(*this*);
} 
*protected* *void* paint(Graphics graphics)
{
graphics.setColor(255,255,255);
graphics.fillRect(0, 0, getWidth(), getHeight());
graphics.setColor(255, 0, 0);
graphics.drawString(direction, 0, 0, 
Graphics.TOP | Graphics.LEFT);
}
*public* *void* commandAction(Command command, Displayable displayable)
{
*if* (command == exit)
{
keyCodeExample.exitMIDlet();
}
}
*protected* *void* keyPressed(*int* key)
{
*switch* ( key ){
*case* KEY_NUM2:
direction = "up";
*break*;
*case* KEY_NUM8:
direction = "down";
*break*;
*case* KEY_NUM4:
direction = "left";
*break*;
*case* KEY_NUM6:
direction = "right";
*break*;
}
repaint();
}
}





یکی از متدهایی که در Canvas  وجود دارد :



*keyPressed*(int keyCode)  
          Called when a key is pressed.



است که به ضرب کلیدها پاسخ می‌دهد. همچنین متدهای دیگری هم هستند:



*keyReleased*(int keyCode)  
          Called when a key is released.

*keyRepeated*(int keyCode)  
          Called when a key is repeated (held down).


این متدها برای پاسخ گویی به ضرب کلید فراهم شده است.

کد کلیدها هم همه در Canvas تعریف شده اند که شامل:



* UP*

 public static final int *UP* Constant for the UP game action.
   Constant value 1 is set to UP.
* DOWN*

 public static final int *DOWN* Constant for the DOWN game action.   Constant value 6 is set to DOWN.
* LEFT*

 public static final int *LEFT* Constant for the LEFT game action.   Constant value 2 is set to LEFT.
* RIGHT*

 public static final int *RIGHT* Constant for the RIGHT game action.   Constant value 5 is set to RIGHT.
* FIRE*

 public static final int *FIRE* Constant for the FIRE game action.   Constant value 8 is set to FIRE.
* GAME_A*

 public static final int *GAME_A* Constant for the general purpose "A" game action.   Constant value 9 is set to GAME_A.
* GAME_B*

 public static final int *GAME_B* Constant for the general purpose "B" game action.   Constant value 10 is set to GAME_B.
* GAME_C*

 public static final int *GAME_C* Constant for the general purpose "C" game action.   Constant value 11 is set to GAME_C.
* GAME_D*

 public static final int *GAME_D* Constant for the general purpose "D" game action.   Constant value 12 is set to GAME_D.
* KEY_NUM0*

 public static final int *KEY_NUM0* keyCode for ITU-T key 0.   Constant value 48 is set to KEY_NUM0.
* KEY_NUM1*

 public static final int *KEY_NUM1* keyCode for ITU-T key 1.   Constant value 49 is set to KEY_NUM1.
* KEY_NUM2*

 public static final int *KEY_NUM2* keyCode for ITU-T key 2.   Constant value 50 is set to KEY_NUM2.
* KEY_NUM3*

 public static final int *KEY_NUM3* keyCode for ITU-T key 3.   Constant value 51 is set to KEY_NUM3.
* KEY_NUM4*

 public static final int *KEY_NUM4* keyCode for ITU-T key 4.   Constant value 52 is set to KEY_NUM4.
* KEY_NUM5*

 public static final int *KEY_NUM5* keyCode for ITU-T key 5.   Constant value 53 is set to KEY_NUM5.
* KEY_NUM6*

 public static final int *KEY_NUM6* keyCode for ITU-T key 6.   Constant value 54 is set to KEY_NUM6.
* KEY_NUM7*

 public static final int *KEY_NUM7* keyCode for ITU-T key 7.   Constant value 55 is set to KEY_NUM7.
* KEY_NUM8*

 public static final int *KEY_NUM8* keyCode for ITU-T key 8.   Constant value 56 is set to KEY_NUM8.
* KEY_NUM9*

 public static final int *KEY_NUM9* keyCode for ITU-T key 9.   Constant value 57 is set to KEY_NUM09.
* KEY_STAR*

 public static final int *KEY_STAR* keyCode for ITU-T key "star" (*).   Constant value 42 is set to KEY_STAR.
* KEY_POUND*

 public static final int *KEY_POUND* keyCode for ITU-T key "pound" (#).   Constant value 35 is set to KEY_POUND.




هستند. 


برنامه مثال در :


  protected void keyPressed(int key)
  {
    switch ( key ){
     case KEY_NUM2:
       direction = "up";
       break;
     case KEY_NUM8:
       direction = "down";
       break;
     case KEY_NUM4:
       direction = "left";
       break;
     case KEY_NUM6:
       direction = "right";
       break;
    }
    repaint();
  }


فقط برای کلیدهای ۲ و ۴و ۶ و ۸ برنامه نویسی شده است و متناسب با ضرب کلید عبارت مناسبی چاپ میکند که توسط repaint این عبارت چاپ خواهد شد متذکر میشوم که paint اولین بار در اجرای نخست فقط اجرا می‌شود و در دفعات بعدی از repaint استفاده کنید.

متد :



 graphics.drawString(direction, 0, 0, 
                         Graphics.TOP | Graphics.LEFT);


برای نوشتن متن در Canvas کاربرد دارد.

----------


## rezaTavak

تایمر :

ابتدا به برنامه زیر دقت کنید:



 *import* java.util.Calendar;
*import* java.util.Date;
*import* java.util.Timer;
*import* java.util.TimerTask;

*import* javax.microedition.lcdui.Command;
*import* javax.microedition.lcdui.CommandListener;
*import* javax.microedition.lcdui.Display;
*import* javax.microedition.lcdui.Displayable;
*import* javax.microedition.lcdui.TextBox;
*import* javax.microedition.midlet.MIDlet;

*public class* FixedRateScheduleMIDlet *extends* MIDlet *implements* CommandListener {

*private* Command exitCommand = *new* Command("Exit", Command.EXIT, 1);

*private* Display display;

TextBox t= *new* TextBox("Time setting", "", 256, 0);

*private* Timer aTimer= *new* Timer();

*private* Date currentTime= *new* Date();

*private* Calendar now = Calendar.getInstance();

*public* FixedRateScheduleMIDlet() {
display = Display.getDisplay(*this*);
now.setTime(currentTime);
}

*public* *void* startApp() {
ClockTimerTask aTimerTask = *new* ClockTimerTask();

aTimer.schedule(aTimerTask, 1000, 1000);

t.addCommand(exitCommand);
t.setCommandListener(*this*);
display.setCurrent(t);
}

*public* *void* pauseApp() {
}

*public* *void* destroyApp(*boolean* unconditional) {
}

*public* *void* commandAction(Command c, Displayable s) {
*if* (c == exitCommand) {
destroyApp(*false*);
notifyDestroyed();
}
}

*class* ClockTimerTask *extends* TimerTask {
*public final* *void* run() {
t.setString("" + now.get(Calendar.HOUR) + "" + now.get(Calendar.MINUTE) + ""
+ now.get(Calendar.SECOND) + "");
display.setCurrent(t);
}
}

}



 کلاس *Timer برای ساخت اشیاء‌ است که در آن بایستی در زمان مشخصی کاری صورت گیرد. سازنده این کلاس بصورت بسیار ساده است :


**Timer*()  
          Creates a new timer.
در آن متدهایی تعریف شده که بصورت زیر هستند:


public void *schedule*(TimerTask task,
                     long delay)

*schedule*(TimerTask task,          Date time)  *schedule*(TimerTask task,
         Date firstTime,
         long period)

*schedule*(TimerTask task,          long delay,          long period)  *scheduleAtFixedRate*(TimerTask task,
                    Date firstTime,
                    long period)
*scheduleAtFixedRate*(TimerTask task,
                    long delay,
                    long period)
*cancel*()





دقت کنید در تمام متدها بایستی یک کلاس از نوع TimerTask ساخته باشید. در برنامه ما :



*class* ClockTimerTask *extends* TimerTask {
*public final* *void* run() {
t.setString("" + now.get(Calendar.HOUR) + ""+ now.get(Calendar.MINUTE) + ""
+ now.get(Calendar.SECOND) + "");
display.setCurrent(t);
}
}


دقت کنید زمانها به میلی ثانیه است. یا بصورت کلاس Date

که متد ما در برنامه بصورت زیر استفاده شده است:



aTimer.schedule(aTimerTask, 1000, 1000);

که دومین پارامتر تاخیر تا اولین اجرا است و سومین پارامتر تاخیر بین هر اجرا است که در اینجا ۱۰۰۰ میلی ثانیه یا ۱ ثانیه است.

همچنین لازم است که با کلاس :



*Calendar*  Calendar is an abstract class for getting and setting dates  using a  set of integer fields such as  YEAR, MONTH, DAY,  and so on.

 آشنا شویم. که تقریبا مانند جاوای استاندارد است. در اینجا :


*private* Calendar now = Calendar.getInstance();

برای گرفتن زمان حال استفاده شده است.

----------


## rezaTavak

چند ماثل برای یادگیری Canvas

*کشیدن خط*


*import* javax.microedition.midlet.*;
*import* javax.microedition.lcdui.*;

*public class* DrawLine *extends* MIDlet{
*private* Display display;

*public* *void* startApp(){
display = Display.getDisplay(*this*);
display.setCurrent (*new* DrawingCanvas()); 
}

*public* *void* pauseApp(){}

*public* *void* destroyApp (*boolean* forced){}
}

*class* DrawingCanvas *extends* Canvas{
*public* *void* paint (Graphics g){
g.setColor (255, 0, 0);
g.fillRect (0, 0, getWidth(), getHeight());
g.setColor (0, 0, 255);
g.fillRect (20, 30, 200, 80);
g.setColor (128, 0, 255);
g.drawLine (0, 0, 100, 200);
}
}




کشیدن مستطیل :



*import* javax.microedition.midlet.*;
*import* javax.microedition.lcdui.*;

*public class* DrawRectengle *extends* MIDlet {
*public* *void* startApp () {
Display.getDisplay (*this*).setCurrent (*new* DrawingDemoCanvas ()); 
}

*public* *void* pauseApp () {}

*public* *void* destroyApp (*boolean* forced) {}
}

*class* DrawingDemoCanvas *extends* Canvas {
*public* *void* paint (Graphics g) {
g.setColor (255, 0, 0);
g.fillRect (0, 0, getWidth (), getHeight ());
g.setColor (0, 0, 255);
g.fillRect (20, 30, 200, 80);
}
}


درج متن در جاهای مختلف صفحه نمایش


*import* javax.microedition.midlet.*;
*import* javax.microedition.lcdui.*;

*public class* DrawString *extends* MIDlet{
*private* Display display;

*public* *void* startApp(){
display = Display.getDisplay(*this*);
display.setCurrent (*new* TextCanvas()); 
}

*public* *void* pauseApp(){}

*public* *void* destroyApp(*boolean* unconditional){}

*public* *void* commandAction(){}
}

*class* TextCanvas *extends* Canvas{
*public* *void* paint(Graphics g){
g.setColor(255, 0, 0);
g.fillRect(0, 0, getWidth(), getHeight());

g.setColor(0, 0, 255);
g.drawString("Top/Left", 0, 0, Graphics.TOP | Graphics.LEFT);
g.drawString("Baseline/Center", getWidth() / 2, getHeight() / 2, 
         Graphics.HCENTER | Graphics.BASELINE);
g.drawString("Bottom/Right", getWidth(), getHeight(),       Graphics.BOTTOM | Graphics.RIGHT);
}
}




کشیدن قطاع و دایره:


*import* javax.microedition.midlet.*;
*import* javax.microedition.lcdui.*;

*public class* RunningCircle *extends* MIDlet{

*public* *void* startApp(){
Display display = Display.getDisplay (*this*);
display.setCurrent(*new* CircleCanvas(display, 10)); 
}

*public* *void* pauseApp(){}

*public* *void* destroyApp(*boolean* unconditional){}
}

*class* CircleCanvas *extends* Canvas *implements* Runnable{
*int* degree = 360;
*long* startTime;
*int* seconds;
Display display;

CircleCanvas(Display display, *int* seconds){
*this*.display = display;
*this*.seconds = seconds;
startTime = System.currentTimeMillis();
}

*public* *void* paint(Graphics g){
g.setColor(0, 0, 255);
g.fillRect(0, 0, getWidth(), getHeight());

g.setColor(255, 0, 0);
g.fillArc(15,15, 200, 200, 90, degree);
display.callSerially(*this*);
g.setColor(255, 0, 0);
g.drawArc(15, 15, 200, 200, 0, 360);
}

*public* *void* run(){
*int* i = 0;
*int* milisecond = (*int*)((System.currentTimeMillis() - startTime)/seconds); 
degree = 360 - (milisecond * 360)/7200;
*for*(i = 0; i <= milisecond; i++){
repaint();
}
}
}


کشیدن مثلث:


*import* javax.microedition.midlet.*;
*import* javax.microedition.lcdui.*;

*public class* DrawTraingle *extends* MIDlet *implements* CommandListener{
*private* Display display;
*private* List list;
*private* Command ok, exit;
*private* CanvasDraw canvasDraw;

*public* DrawTraingle(){
canvasDraw = *new* CanvasDraw();
display = Display.getDisplay(*this*);
list = *new* List("DrawTraingle", List.IMPLICIT);
ok = *new* Command("Draw", Command.OK, 2);
exit = *new* Command("Exit", Command.EXIT, 2);
list.append("Draw Triangle", *null*);
list.addCommand(ok);
list.addCommand(exit);
list.setCommandListener(*this*);
}

*public* *void* startApp(){
display.setCurrent(list);
}

*public* *void* pauseApp(){}

*public* *void* destroyApp(*boolean* unconditional){
notifyDestroyed ();
}

*public* *void* commandAction(Command c, Displayable d){
*int* listItemIndex = list.getSelectedIndex();
*if*(c == ok){
display.setCurrent(canvasDraw);
}*else if*(c == exit){
destroyApp(*true*);
}
}

*class* CanvasDraw *extends* Canvas *implements* CommandListener{
Command back;

*public* CanvasDraw(){
back = *new* Command("Back", Command.BACK, 1);
addCommand(back);
setCommandListener(*this*);
}

*public* *void* paint(Graphics g){
g.setColor(0, 0, 255);
g.fillRect(0,0, getWidth (), getHeight ());
g.setColor(255, 0, 0);

g.drawString("Draw Traingle", getWidth () / 2, 5, Graphics.HCENTER | Graphics.TOP);
g.fillTriangle(getWidth() / 4, 100, 90, 180, 180, 90);
}

*public* *void* commandAction (Command c, Displayable d){
*if*(c == back){
display.setCurrent(list);
}
}
}
}

----------


## rezaTavak

ممکن است شما نیاز داشته باشید که در مواقعی فونت را هم استفاده کنید این فونت ساده بوده و ممکن است در هر دستگاهی پشتیبانی نشود. 

Font کلاسی است که برای اینکار در نظر گرفته شده است.


هر فونت دارای سه خاصیت است:

style, size, و face

خاصیتها همه به عدد هستند یعنی FACE ممکن است یکی از مقادیر زیر باشد:

* FACE_SYSTEM*

 public static final int *FACE_SYSTEM* The "system" font face.
   Value 0 is assigned to FACE_SYSTEM.
* FACE_MONOSPACE*

 public static final int *FACE_MONOSPACE* The "monospace" font face.
   Value 32 is assigned to FACE_MONOSPACE.
* FACE_PROPORTIONAL*

 public static final int *FACE_PROPORTIONAL* The "proportional" font face.
   Value 64 is assigned to FACE_PROPORTIONAL.




و style ممکن است یکی از حالات زیر باشد:



* STYLE_PLAIN*

 public static final int *STYLE_PLAIN* The plain style constant. This may be combined with the  other style constants for mixed styles. 
   Value 0 is assigned to STYLE_PLAIN.
* STYLE_BOLD*

 public static final int *STYLE_BOLD* The bold style constant. This may be combined with the  other style constants for mixed styles.
   Value 1 is assigned to STYLE_BOLD.
* STYLE_ITALIC*

 public static final int *STYLE_ITALIC* The italicized style constant. This may be combined with  the other style constants for mixed styles.
   Value 2 is assigned to STYLE_ITALIC.
* STYLE_UNDERLINED*

 public static final int *STYLE_UNDERLINED* The underlined style constant. This may be combined with  the other style constants for mixed styles.
   Value 4 is assigned to STYLE_UNDERLINED.





و اندازه ممکن است یکی از حالات زیر باشد:



* SIZE_SMALL*

 public static final int *SIZE_SMALL* The "small" system-dependent font size.
   Value 8 is assigned to STYLE_SMALL.
* SIZE_MEDIUM*

 public static final int *SIZE_MEDIUM* The "medium" system-dependent font size.   Value 0 is assigned to STYLE_MEDIUM.
* SIZE_LARGE*

 public static final int *SIZE_LARGE* The "large" system-dependent font size.
   Value 16 is assigned to SIZE_LARGE.
*
*





دقت کنید ممکن است از OR برای ترکیب چند Style هم استفاده شود مانند:


STYLE_BOLD | STYLE_ITALIC  


اما در مورد اندازه فقط یکی باید باشد.

آنچه در فونت مهم است اندازه طول و عرض آن است که تابع هایی آنرا بر می‌گردانند:
* getHeight()   برای ارتفاع و 
*

*charWidth   برای عرض که به دوصورت هم تعریف شده  است.*



همچنین 
*stringWidth  و substringWidth است.*


همچنین متدها:

  boolean *isBold*()  
          Returns true if the font is bold.     boolean *isItalic*()  
          Returns true if the font is italic.     boolean *isPlain*()  
          Returns true if the font is plain.     boolean *isUnderlined*()  
          Returns true if the font is underlined.
برای تشخیص نوع Style است. 

از 



 static Font *getFont*(int face,         int style,         int size)  

هم برای ساخت یک وفونت استفاده می‌شود اما مثال:


 *import* javax.microedition.lcdui.Canvas;
*import* javax.microedition.lcdui.Command;
*import* javax.microedition.lcdui.CommandListener;
*import* javax.microedition.lcdui.Display;
*import* javax.microedition.lcdui.Displayable;
*import* javax.microedition.lcdui.Font;
*import* javax.microedition.lcdui.Graphics;
*import* javax.microedition.midlet.MIDlet;

*public class* FontMIDlet *extends* MIDlet *implements* CommandListener {
*private* FontCanvas mFontCanvas;

*private* Command mBoldCommand, mItalicCommand, mUnderlineCommand;

*public* FontMIDlet() {
mFontCanvas = *new* FontCanvas();

mBoldCommand = *new* Command("Bold", Command.SCREEN, 0);
mItalicCommand = *new* Command("Italic", Command.SCREEN, 0);
mUnderlineCommand = *new* Command("Underline", Command.SCREEN, 0);
Command exitCommand = *new* Command("Exit", Command.EXIT, 0);

mFontCanvas.addCommand(mBoldCommand);
mFontCanvas.addCommand(mItalicCommand);
mFontCanvas.addCommand(mUnderlineCommand);
mFontCanvas.addCommand(exitCommand);
mFontCanvas.setCommandListener(*this*);
}

*public* *void* startApp() {
Display.getDisplay(*this*).setCurrent(mFontCanvas);
}

*public* *void* pauseApp() {
}

*public* *void* destroyApp(*boolean* unconditional) {
}

*public* *void* commandAction(Command c, Displayable s) {
*if* (c.getCommandType() == Command.EXIT) {
notifyDestroyed();
*return*;
}

*boolean* isBold = mFontCanvas.isBold() ^ (c == mBoldCommand);
*boolean* isItalic = mFontCanvas.isItalic() ^ (c == mItalicCommand);
*boolean* isUnderline = mFontCanvas.isUnderline() ^ (c == mUnderlineCommand);

*int* style = (isBold ? Font.STYLE_BOLD : 0) | (isItalic ? Font.STYLE_ITALIC : 0)
| (isUnderline ? Font.STYLE_UNDERLINED : 0);

mFontCanvas.setStyle(style);
mFontCanvas.repaint();
}
}

*class* FontCanvas *extends* Canvas {
*private* Font mSystemFont, mMonospaceFont, mProportionalFont;

*public* FontCanvas() {
*this*(Font.STYLE_PLAIN);
}

*public* FontCanvas(*int* style) {
setStyle(style);
}

*public* *void* setStyle(*int* style) {
mSystemFont = Font.getFont(Font.FACE_SYSTEM, style, Font.SIZE_MEDIUM);
mMonospaceFont = Font.getFont(Font.FACE_MONOSPACE, style, Font.SIZE_MEDIUM);
mProportionalFont = Font.getFont(Font.FACE_PROPORTIONAL, style, Font.SIZE_MEDIUM);
}

*public* *boolean* isBold() {
*return* mSystemFont.isBold();
}

*public* *boolean* isItalic() {
*return* mSystemFont.isItalic();
}

*public* *boolean* isUnderline() {
*return* mSystemFont.isUnderlined();
}

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

*int* x = w / 2;
*int* y = 20;

y += showFont(g, "System", x, y, mSystemFont);
y += showFont(g, "Monospace", x, y, mMonospaceFont);
y += showFont(g, "Proportional", x, y, mProportionalFont);
}

*private* *int* showFont(Graphics g, String s, *int* x, *int* y, Font f) {
g.setFont(f);
g.drawString(s, x, y, Graphics.TOP | Graphics.HCENTER);
*return* f.getHeight();
}
}

----------


## rezaTavak

پکیج *javax.microedition.rms برای ذخیره اطلاعات در موبایل است که کلاس اصلی* *RecordStore را در خود دارد. 

برای یادگیری آن به برنامه زیر دقت کنید:

*
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import javax.microedition.midlet.*;
import javax.microedition.rms.*;
import javax.microedition.lcdui.*;

/**
 * @author root
 */
public class RecRw extends MIDlet implements CommandListener{

    private Display display;
    private Form form,show;
    private TextField textfield;
    private Command commandExit,commandAdd,commandShow;
    private RecordStore rs;

    public RecRw(){
        display = Display.getDisplay(this);
        form = new Form("Record Store");
        show = new Form("Show");
        textfield = new TextField("Name:","",30,TextField.ANY);
        commandExit = new Command("Exit",Command.EXIT,1) ;
        commandAdd = new Command("Add",Command.SCREEN,1) ;
        commandShow = new Command("Show",Command.SCREEN,1) ;
        form.addCommand(commandExit);
        form.addCommand(commandAdd);
        form.addCommand(commandShow);
        form.setCommandListener(this);
        form.append(textfield);
        show.addCommand(commandExit);
        show.setCommandListener(this);
        try{rs=rs.openRecordStore("simple", true);}catch(Exception e){}

    }


    public void startApp() {
        display.setCurrent(form);

    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
        notifyDestroyed();
    }

    public void commandAction(Command c, Displayable d){
        try {
        if(c.getLabel()=="Exit"){
            destroyApp(false);
            rs.closeRecordStore();
        }
        else if(c.getLabel()=="Add")
            rs.addRecord(textfield.getString().getBytes(), 0, textfield.getString().length());
        else {
            for(int i=1; i<rs.getNumRecords();i++){
                String s = new String(rs.getRecord(i));

                show.append(s);
            }
            display.setCurrent(show);
        }
        }catch(Exception e){
            form.append(e.getMessage());
        }

    }

}




ابتدا بایستی یک RecordStore با دستور open باز شود:
 try{rs=rs.openRecordStore("simple", true);}catch(Exception e){}پارامتر اول نام دیتابیس و دومی اگر وجود نداشت ساخته شود.
سپس با دستور :
             rs.addRecord(textfield.getString().getBytes(), 0, textfield.getString().length());رکوردها اضافه میشوند که پارامتر اول بایتهایی که بایستی نوشته شوند و دومین شروع آفست بایتها و سومین تعداد بایتها

سپس با دستور :
                 String s = new String(rs.getRecord(i));هر رکورد خوانده میشود که پارامتر شماره رکورد باید ارسال شود.

در نهایت این دیتا بیس بسته خواهد شد:
             rs.closeRecordStore();دقت کنید چون ممکن است خطا رخ دهد تمام این متدها باید با مدیریت خطا صورت گیرد.

----------


## rezaTavak

خاصیت چند پردازشی در موبایل نیز وجود دارد که مانند جاوای استاندارد در :

*Thread

تعریف شده است.

هر پروسه یا نخ دارای یک اولویت اجرا است. هرچه عدد بزرگتر باشد اولویت پایین تر است.

به دو صورت میتوان یک پروسه چند نخی را ایجاد کرد یکی از طریق Thread و دیگر از طریق * 
implements Runnable 

روش اول مانند زیر است :
 ابتدا یک کلاس بوجود می آوریم و متد run را رونویسی می کنیم:



     class PrimeThread extends Thread {
         long minPrime;
         PrimeThread(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }



 و 



     PrimeThread p = new PrimeThread(143);


     p.start();



هر جایی خواستیم پروسه را صدا می زنیم راه دیگر :




     class PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }


و برای کاربردن :



     PrimeRun p = new PrimeRun(143);
     new Thread(p).start();
 



حال یک برنامه نمونه:



 *import* javax.microedition.lcdui.Canvas;
*import* javax.microedition.lcdui.Command;
*import* javax.microedition.lcdui.CommandListener;
*import* javax.microedition.lcdui.Display;
*import* javax.microedition.lcdui.Displayable;
*import* javax.microedition.lcdui.Graphics;
*import* javax.microedition.midlet.MIDlet;

*public class* J2MESweep *extends* MIDlet {
*public* *void* startApp() {
*final* SweepCanvas sweeper = *new* SweepCanvas();
sweeper.start();

sweeper.addCommand(*new* Command("Exit", Command.EXIT, 0));
sweeper.setCommandListener(*new* CommandListener() {
*public* *void* commandAction(Command c, Displayable s) {
sweeper.stop();
notifyDestroyed();
}
});

Display.getDisplay(*this*).setCurrent(sweeper);
}

*public* *void* pauseApp() {
}

*public* *void* destroyApp(*boolean* unconditional) {
}
}

*class* SweepCanvas *extends* Canvas *implements* Runnable {
*private* *boolean* mTrucking;

*private* *int* mTheta = 0;

*private* *int* mBorder = 10;

*private* *int* mDelay = 50;

*public* *void* start() {
mTrucking = *true*;
Thread t = *new* Thread(*this*);
t.start();
}

*public* *void* stop() {
mTrucking = *false*;
}

*public* *void* paint(Graphics g) {
*int* width = getWidth();
*int* height = getHeight();

g.setGrayScale(255);
g.fillRect(0, 0, width - 1, height - 1);

*int* x = mBorder;
*int* y = mBorder;
*int* w = width - mBorder * 2;
*int* h = height - mBorder * 2;
*for* (*int* i = 0; i < 8; i++) {
g.setGrayScale((8 - i) * 32 - 16);
g.fillArc(x, y, w, h, mTheta + i * 10, 10);
}
}

*public* *void* run() {
*while* (mTrucking) {
mTheta = (mTheta + 1) % 360;
repaint();
*try* {
Thread.sleep(mDelay);
} *catch* (InterruptedException ie) {
}
}
}
}




کلاس :
 *class* SweepCanvas *extends* Canvas *implements* Runnable { * از نوع چند نخی تعریف شده است که دارای متد run است که هر بار پس از فراخواندن نخ اجرا خواهد شد. در نخ هر بار متد repaint فرا خوانده شده و پس از ۵۰ میلی ثانیه دوباره به کار خود ادامه می‌دهد. فرمان*  sweeper.start(); باعث اجرای نخ خواهد شد.

در حقیقت run متدی است که پیوسته در حال اجرا است و مانند یک حلقه همیشه فراخوانی می‌شود.

----------


## rezaTavak

کلاس CustomItem برای ساخت آیتمهایی است که وجود ندارد و به سفارش شما ساخته می‌شود و از روی کلاس *Item ساخته میشود اما دقت کنید که باید نگارش MID بالاتر از ۲ باشد. یعنی این آیتم در MID 1.0 وجود ندارد. 

اگر به help مربوط به*  Item که در نگارش ۲ است دقت کنید می بینید که با نگارش ۱  *Item* تفاوت دارد! *
(روی لینکها کلیک کنید.)

بنابراین دقت کنید که حتما نگارش درستی از MID انتخاب شده باشد.

بیشتر موبایلها سعی کرده‌اند که هم MID و CLDC بالاتری را در زمان تولید خود در اختیار داشته باشند اما موبایلهای قدیمی (بسیار قدیمی) دارای نگارش پایین هستند.

نگارش یک فقط دارای تنظیماتی کوچکی است اما نگارش ۲ تنظیمات زیادتری برای ITem دارد.

مثلا طرحبندی که شامل :

*
 LAYOUT_DEFAULT LAYOUT_LEFT LAYOUT_RIGHT LAYOUT_CENTER LAYOUT_TOP LAYOUT_BOTTOM LAYOUT_VCENTER LAYOUT_NEWLINE_BEFORE LAYOUT_NEWLINE_AFTER LAYOUT_SHRINK LAYOUT_VSHRINK LAYOUT_EXPAND LAYOUT_VEXPAND LAYOUT_2
   اندازه

اضافه کردن دکمه دستور

نحوه نمایش که شامل PLAIN,  HYPERLINK, or BUTTON.است


چون کلاس Item  بصورت 
public abstract class *Item*extends Objectتعریف شده است پس کلاسی انتزاعی یا abstract است.

مشخصات کلاس CustomItem:
سازنده کلاس بصورت

 protected  *CustomItem*(String label)


 است. 

همچنین این کلاس قابلیت تشخیص کلیدها توسط کاربر را مانند حالت canvas دارد. که توسط متدها را دارد همچنین دارای متد paint , repaint است که می‌توان این شی را کنترل کرد. 

شما باید توسط     getMinContentHeight,  getMinContentWidth,    getPrefContentHeight,  getPrefContentWidth, and  sizeChanged  و Item.getMinimumHeight,  Item.getMinimumWidth,  Item.getPreferredHeight, and  Item.getPreferredWidth. اندازه این کنترل را تعیین کنید.

نمونه برنامه:




*import* javax.microedition.midlet.*;
*import* javax.microedition.lcdui.*;

*public class* CustomItemMIDletExample *extends* MIDlet *implements* CommandListener{
*private* Form form;
*private* Command exit;
*private* Display display;
*private* CustomItemExample customItem;

*public* CustomItemMIDletExample(){
form = *new* Form("CustomItemMIDletExample");
exit = *new* Command("Exit", Command.EXIT, 0);
form.append(*new* CustomItemExample("CustomItemExample"));
form.addCommand(exit);
form.setCommandListener(*this*);
}

*public* *void* startApp(){
display = Display.getDisplay(*this*);
display.setCurrent(form);
}

*public* *void* pauseApp(){}

*public* *void* destroyApp(*boolean* unconditional){}

*public* *void* commandAction(Command c, Displayable s){
*if*(c.getCommandType() == Command.EXIT)
notifyDestroyed();
}
}

*class* CustomItemExample *extends* CustomItem{
*public* CustomItemExample(String title){
*super*(title);
}

*public* *int* getMinContentWidth(){
*return* 100;
}

*public* *int* getMinContentHeight(){
*return* 60;
}

*public* *int* getPrefContentWidth(*int* width){
*return* getMinContentWidth();
}

*public* *int* getPrefContentHeight(*int* height){
*return* getMinContentHeight();
}

*public* *void* paint(Graphics g, *int* w, *int* h){
g.drawRect(0, 0, w - 1, h - 1);
g.setColor(0, 0, 255);
*int* offset = 0;
*for* (*int* y = 4; y < h; y += 12){
offset = (offset + 12) % 24;
*for* (*int* x = 7; x < w; x += 24){
g.fillTriangle(x + offset, y, x + offset - 3, y + 6, x + offset + 3, y + 6);
}
}
}
}

----------


## rezaTavak

اجرای صوت:

برای اجرای صوت باید شما در MID 2.0  برنامه بنویسید. شما به آسانی می‌توانید با کلاس  *Manager به پخش بپردازید 

اما قبل از ان موردی هم بد نیست بدانیم. در j me شما به فایلها دسترسی ندارید هر چیزی که هست داخل فایل jar باشد شما می‌تواند با آن کار کنید (فقط بخوانید) (گرچه jsr 72 برای فایل است اما در حال استاندارد وجود ندارد.)

هر فایلی در داخل فایل jar یا calss است یا resource که می‌توان هر چیزی را داخل resource ذخیره کرد. مثلا عکس، صدا و...

با استفاده از تابع :* *getResourceAsStream*(String name)  شما می توانید به این منابع دسترسی داشته باشید.

که در *Class تعریف شده است.

فرض کنید فایلی به اسم* 
music.wav

در دایرکتوری اصلی باشد شما با دستور :

 try {     InputStream is = getClass().getResourceAsStream("music.wav");     Player p = Manager.createPlayer(is, "audio/X-wav");     p.start(); } catch (IOException ioe) { } catch (MediaException me) { } 



 میتوانید آنرا اجرا کنید.

حتی فایلی که روی اینترنت باشد:

 try {     Player p = Manager.createPlayer("http://webserver/music.wav");     p.setLoopCount(5);     p.start(); } catch (IOException ioe) { } catch (MediaException me) { } 
 
یا حتی اجرای یک نت :



try {     Manager.playTone(ToneControl.C4, 5000 /* ms */, 100 /* max vol */); } catch (MediaException e) { }



 یا بصورت یک پیانو!



/**
 * "Mary Had A Little Lamb" has "ABAC" structure.
 * Use block to repeat "A" section.
 */
byte tempo = 30; // set tempo to 120 bpm
byte d = 8;      // eighth-note

byte C4 = ToneControl.C4;;
byte D4 = (byte)(C4 + 2); // a whole step
byte E4 = (byte)(C4 + 4); // a major third
byte G4 = (byte)(C4 + 7); // a fifth
byte rest = ToneControl.SILENCE; // rest

byte[] mySequence = {
    ToneControl.VERSION, 1,   // version 1
    ToneControl.TEMPO, tempo, // set tempo
    ToneControl.BLOCK_START, 0,   // start define "A" section
    E4,d, D4,d, C4,d, E4,d,       // content of "A" section
    E4,d, E4,d, E4,d, rest,d,
    ToneControl.BLOCK_END, 0,     // end define "A" section
    ToneControl.PLAY_BLOCK, 0,    // play "A" section
    D4,d, D4,d, D4,d, rest,d,     // play "B" section
    E4,d, G4,d, G4,d, rest,d,
    ToneControl.PLAY_BLOCK, 0,    // repeat "A" section
    D4,d, D4,d, E4,d, D4,d, C4,d  // play "C" section
};

try{
    Player p = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
    p.realize();
    ToneControl c = (ToneControl)p.getControl("ToneControl");
    c.setSequence(mySequence);
    p.start();
} catch (IOException ioe) {
} catch (MediaException me) { }



مفاهیم پایه:

سه عامل اصلی در اجرای یک صدا نقش دارند:
 Manager
Player
Controlتعامل این سه عنصر به شکل زیر است:




کلاس بالاتر مربوط به manager است  که درخواستها را به player داده و موقعیت اینکه چه جایی پخش شود توسط آن کنترل خواهد شد و توسط Control می‌توان اجرای را کنترل کرد مثلا کاهش یا افزایش میزان صدا.

بنابراین :



Player Manager.createPlayer(String url)

 یک متد است که برای ساخت عنصر Player  استفاده می‌شود. پارامتر ورود آن url بصورت زیر است: 
<protocol>:<content location>

متدها مختلف در کلاس واسطه Player   برای اجرا صوت است:

مثلا *start*()   و *stop*()   و...

برنامه بسیار ساده زیر را دقت کنید:



*import* javax.microedition.midlet.MIDlet;
*import* javax.microedition.media.*;

*public class* MultimediaSound *extends* [COLOR=blue ! important][COLOR=blue ! important]MIDlet[/color] [/color]{
*public* *void* startApp(){
*try* {
Player player = Manager.createPlayer(getClass().          getResourceAsStream("/CatBird.wav"),"audio/x-wav");
     
player.start();
} *catch*(Exception e) {
e.printStackTrace();
}
}

*public* *void* pauseApp() {}

*public* *void* destroyApp(*boolean* unconditional) {}
}


برای دانلود سورس آن *Download Source Code 
*


*این برنامه بسیار ساده یک فایل صوتی را اجرا می کند.
*

----------


## om123456789987654321

با سلام
اولا" از شما تشکر میکنم به خاطر آموزشای مفیدتون.
اما یک انتقاد :(البته این انتقاد به شخص شما بر نمیگرده بلکه منظورم با همه کسائیه که این جور تاپیک های آموزشی رو میزنن)
چرا شما گفتین که ما فقط میتونیم به منابع فایل jar  دسترسی داشته باشیم ولاغیر...
اتفاقا" به منابع خارج از فایل jar هم میشه دسترسی داشت نمونه برنامه که در اون از خاصیت پخش صوت جاوا استفاده شده Player هائیه که با زبان جاوا ایجاد شده مثل ویندوز مدیا پلیر 11 که برای گوشی موبایل با پسوند Jar نوشته شده و فقط کافیه یک جستجوی کوچیک در اینترنت بکنید تا n تا برنامه مثل اینو پیدا کنید.
پس بهتره که هیچ وقت نگیم نمیشه ، بگیم : *من تا به حال انجام ندادم* 
اینو بدونید : *کار هیچوقت نشد نداره*
امیدوارم از من ناراحت نشده باشید.

----------


## rezaTavak

متشکرم از عنایت شما. انتقاد اگر سازنده باشد باعث پیشرفت می‌شود و باعث بهتر درک شدن مطلب من از شما بینهایت متشکرم.

اولا اشاره شده است که ممکن است از jsr های دیگر به فایل دسترسی داشت. 

اما با توجه به این سند:
http://dsc.sun.com/mobility/midp/art...mmapioverview/

و این عکس که در سند فوق است 



دنبال این مطلب بگردید:



Because any InputStream can be passed to the Manager.createPlayer()  method, your application can play back media from a MIDP Record  Management System (RMS), or from a JAR file. Here's how to get an InputStream from an RMS and play media stored in it: 
همچنین هر نوع url که در  <protocol>:<content location>  قبول واقع شود.

ممکن است protocol شامل file:// هم بشود که می توان فایل را هم در این صورت اجرا کرد این کار باید توسط ماشین مجازی جاوا قبلا فراهم شده باشد برای دانستن این موضوع بایستی :
*
*

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.media.*;

public class MediaInformationMIDlet
    extends MIDlet
    implements CommandListener {
  private Form mInformationForm;

  public void startApp() {
    if (mInformationForm == null) {
      mInformationForm =
          new Form("Content types and protocols");
      String[] contentTypes =
          Manager.getSupportedContentTypes(null);
      for (int i = 0; i < contentTypes.length; i++) {
        String[] protocols =
            Manager.getSupportedProtocols(contentTypes[i]);
        for (int j = 0; j < protocols.length; j++) {
          StringItem si = new StringItem(contentTypes[i] + ": ",
              protocols[j]);
          si.setLayout(Item.LAYOUT_NEWLINE_AFTER);
          mInformationForm.append(si);
        }
      }
      Command exitCommand = new Command("Exit", Command.EXIT, 0);
      mInformationForm.addCommand(exitCommand);
      mInformationForm.setCommandListener(this);
    }
    Display.getDisplay(this).setCurrent(mInformationFo  rm);
  }

  public void pauseApp() {}

  public void destroyApp(boolean unconditional) {}

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


*
**را اجرا کنید و نتیجه را ببینید اگر پروتکل file پشتیبانی شود شما به فایلها هم دسترسی دارید اما اگر نشود ندارید. 


تذکر: اگر پشتیبانی نشود ممکن است به دلایل امنیتی باشد. 
*

----------


## rashid1368

سلام دوست عزیز و به قول دوستان.... مدیر لایق این بخش
امیدوارم این آموزش ها ادامه داشته باشه
باز هم تشکر

----------


## rezaTavak

قابل توجه جناب رشید من مدیر فاکس پرو هستم.

ارتباط با اینترنت:

javax.microedition.io.HttpConnection;

Interface ی است برای دسترسی به اینترنت که _HttpConnection توضیحات آن آمده است . همچنین باید از کلاس_ *Connector هم* استفاده کنید. 

نگارش دوم MID کلاسهای بیشتر برای ارتباط دارد: *HttpConnection و* *HttpsConnection 

همچنانکه می دانید دو جور ارتباط داریم: GET, POST که مثالی برای get:

*

     void getViaHttpConnection(String url) throws IOException {
         HttpConnection c = null;
         InputStream is = null;
         try {
             c = (HttpConnection)Connector.open(url);
 
             // Getting the InputStream will open the connection
             // and read the HTTP headers. They are stored until
             // requested.
             is = c.openInputStream();
 
             // Get the ContentType
             String type = c.getType();
 
             // Get the length and process the data
             int len = (int)c.getLength();
             if (len > 0) {
                 byte[] data = new byte[len];
                 int actual = is.read(data);
                 ...
             } else {
                 int ch;
                 while ((ch = is.read()) != -1) {
                     ...
                 }
             }
         } finally {
             if (is != null)
                 is.close();
             if (c != null)
                 c.close();
         }
     }
 




همچنین برای متد فرستادن post:




    void postViaHttpConnection(String url) throws IOException {
        HttpConnection c = null;
        InputStream is = null;
        OutputStream os = null;

        try {
            c = (HttpConnection)Connector.open(url);

            // Set the request method and headers
            c.setRequestMethod(HttpConnection.POST);
            c.setRequestProperty("If-Modified-Since",
                "29 Oct 1999 19:43:31 GMT");
            c.setRequestProperty("User-Agent",
                "Profile/MIDP-1.0 Configuration/CLDC-1.0");
            c.setRequestProperty("Content-Language", "en-US");

            // Getting the output stream may flush the headers
            os = c.openOutputStream();
            os.write("LIST games\n".getBytes());
            os.flush();                // Optional, openInputStream will flush

            // Opening the InputStream will open the connection
            // and read the HTTP headers. They are stored until
            // requested.
            is = c.openInputStream();

            // Get the ContentType
            String type = c.getType();
            processType(type);

            // Get the length and process the data
            int len = (int)c.getLength();
            if (len > 0) {
                byte[] data = new byte[len];
                int actual = is.read(data);
                process(data);
            } else {
                int ch;
                while ((ch = is.read()) != -1) {
                    process((byte)ch);
                }
            }
        } finally {
            if (is != null)
                is.close();
            if (os != null)
                os.close();
            if (c != null)
                c.close();
        }
    }
 




گرچه این برنامه‌ها پیچیده هستند و نیاز به دانسته‌های قبلی در خصوص چگونگی ارتباط با سرور دارند اما برنامه ساده زیر یک فایل را که بصورت txt است به شما نشان می‌دهد:



*import* java.io.IOException;
*import* java.io.InputStream;

*import* javax.microedition.io.Connector;
*import* javax.microedition.io.HttpConnection;
*import* javax.microedition.lcdui.Display;
*import* javax.microedition.lcdui.TextBox;
*import* javax.microedition.midlet.MIDlet;

/**
* An example MIDlet to fetch a page using an HttpConnection.
*/
*public class* J2MESecondExample *extends* MIDlet {

*private* Display display;
*private* String url = "http://www.y.com/hello.txt";

*public* J2MESecondExample() {
display = Display.getDisplay(*this*);
}

/**
* This will be invoked when we activate the MIDlet.
*/
*public* *void* startApp() {
// Use the specified URL is overriden in the descriptor
*try* {
downloadPage(url);
} *catch* (IOException e) {
// handle the exception
}
}

*private* *void* downloadPage(String url) *throws* IOException {
StringBuffer b = *new* StringBuffer();
InputStream is = *null*;
HttpConnection c = *null*;
TextBox t = *null*;
*try* {
*long* len = 0;
*int* ch = 0;

c = (HttpConnection) Connector.open(url);
is = c.openInputStream();

len = c.getLength();
*if* (len != -1) {
// Read exactly Content-Length bytes
*for* (*int* i = 0; i < len; i++)
*if* ((ch = is.read()) != -1)
b.append((*char*) ch);
} *else* {
// Read till the connection is closed.
*while* ((ch = is.read()) != -1) {
len = is.available();
b.append((*char*) ch);
}
}
t = *new* TextBox("hello again....", b.toString(), 1024, 0);
} *finally* {
is.close();
c.close();
}

display.setCurrent(t);
}

/**
* Pause, discontinue....
*/
*public* *void* pauseApp() {
}

/**
* Destroy must cleanup everything.
*/
*public* *void* destroyApp(*boolean* unconditional) {
}

}

حال موارد این برنامه:
به جای *private* String url = "http://www.y.com/hello.txt"; مسیر درست را قرار دهید می‌توانید هر نوع فایلی از نوع html هم باشد اما بصورت سورس کد در اختیار شما خواهد بود نه مانند آن چیزی که در مرورگر خواهید دید.

c = (HttpConnection) Connector.open(url);

یک ارتباط را می‌سازد. و توسط 

is = c.openInputStream();

این ارتباط به جریان ورودی تبدیل می شود. (مثل اینکه مثلا دارید از فایل می خوانید.) 

len = c.getLength(); طول فایل را بر می گرداند. اگر طول دقیق مشخص نباشد مقدار -۱ برگردانیده می‌شود.

و توسط :



*if* ((ch = is.read()) != -1)
b.append((*char*) ch);



اطلاعات فایل درون یک متغیر رشته‌ای ریخته می‌شود. 


در واقع اینترنت مانند یک جریان فایل عمل می‌شود. فقط فایل در دور دست است!

----------


## mahsa_hashemi

واقعا ممنوووووووووووووووووووووو  وووووووووووووووووووونم 
2 ماه دنبال اموزش netbeans میگردم
خیلی ممنونم 
 :تشویق:  :تشویق:  :تشویق:  :تشویق:  :تشویق:

----------

