الأربعاء، 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();
     }
}