• Thứ Năm, 30/12/2010 07:53 (GMT+7)

    Lập trình Java giả lập máy tính bỏ túi trên điện thoại di động

    Từ khóa: Java
    Câu hỏi :

    Xin hướng dẫn lập trình Java giả lập máy tính bỏ túi trên điện thoại di động, có các button thực hiện các phép toán cơ bản như +, -, *, /.



    Trả lời :

    Platform J2ME (Java 2 Mobile Edition) chỉ cung cấp các đối tượng nhỏ và đơn giản đủ dùng để viết các ứng dụng nhỏ và đơn giản chạy trên các thiết bị di động (như điện thoại di động,...), nó chỉ hỗ trợ một số đối tượng giao diện như TextBox, DateField... Do đó để viết ứng dụng cần các đối tượng mà J2ME không hỗ trợ như Button, Checkbox... bạn phải tự viết code để xử lý các đối tượng này. Việc xử lý 1 đối tượng giao diện gồm 2 công việc chính: hiển thị hình ảnh đồ họa của đối tượng và xử lý các sự kiện mà người dùng tác động lên đối tượng trong khi ứng dụng chạy. Để giúp bạn thấy rõ ràng, chi tiết về cách viết code quản lý các đối tượng giao diện, chúng tôi xin giới thiệu qui trình điển hình để xây dựng phần mềm giả lập máy tính bỏ túi thực hiện các phép toán cơ bản như +, -, *, / dùng môi trường NetBean 6.9 với giao diện như sau:

    1. Chạy môi trường lập trình NetBean 6.9, đóng các Project đang được NetBean quản lý lại.

    2. Chọn menu File.New Project để hiển thị cửa sổ New Project. Chọn mục Java ME trong danh sách Categories, chọn mục Mobile Application trong danh sách Projects, chọn button Next để hiển thị cửa sổ New Mobile Application. Nhập tên Project là Calculator, chọn thư mục chứa Project, bỏ chọn checkbox Create Hello Midlet, chọn button Next để hiển thị cửa sổ kế tiếp. Chọn tên driver quản lý thiết bị di động (thí dụ DefaultCldcPhone1), chọn button Finish để hoàn thành việc đặc tả Project cần tạo mới.

    3. Ấn phải chuột vào Project Calculator trong cửa sổ Project, chọn New.MIDlet, nhập tên MIDlet là Calculator, chọn button Finish để hiển thị cửa sổ soạn code cho MIDlet rồi viết code như sau:

    //Mã nguồn Java của ứng dụng di động Calculator
    import javax.microedition.midlet.*;
    import javax.microedition.lcdui.*;
    //đặc tả class phần mềm Calculator
    public class Calculator extends MIDlet implements CommandListener {
    //định nghĩa các biến cần dùng
    private boolean midletPaused = false;
    private SampleCanvas mycanvas;
    private Command exitCommand;
    private Command backCommand;
    //định nghĩa các hàm chức năng
    private void initialize() {}

    public void startMIDlet() {
    Display display = Display.getDisplay(this);
    exitCommand = new Command("D\u1eebng", Command.EXIT, 1);
    backCommand = new Command("Reset", Command.BACK, 2);
    mycanvas=new SampleCanvas();
    mycanvas.addCommand(exitCommand);
    mycanvas.addCommand(backCommand);
    mycanvas.setCommandListener(this);
    display.setCurrent(mycanvas);
    }
    public void resumeMIDlet() {}
    public void switchDisplayable(Alert alert, Displayable nextDisplayable) {
    Display display = Display.getDisplay(this);
    if (alert == null) display.setCurrent(nextDisplayable);
    else display.setCurrent(alert, nextDisplayable);
    }

    public void commandAction(Command command, Displayable displayable) {
    if (command == backCommand) mycanvas.MyInit ();
    else if (command == exitCommand) {
    destroyApp(false);
    this.notifyDestroyed();
    }
    }

    public void exitMIDlet() {
    switchDisplayable (null, null);
    destroyApp(true);
    notifyDestroyed();
    }

    //điểm nhập của ứng dụng
    public void startApp() {
    if (midletPaused) resumeMIDlet ();
    else {
    initialize ();
    startMIDlet ();
    }
    midletPaused = false;
    }

    public void pauseApp() {
    midletPaused = true;
    }
    public void destroyApp(boolean unconditional) {}
    }

    //class đặc tả form làm việc của ứng dụng
    class SampleCanvas extends Canvas {
    //định nghĩa các hằng gợi nhớ cần dùng
    final int ADDID = 1;
    final int SUBID = 2;
    final int MULID = 3;
    final int DIVID = 4;
    final int EQUALID = 5;
    //định nghĩa các biến cần dùng
    Font font;
    Graphics gh;
    int ww, wh;
    int baseX, baseY;
    int bw,bh;
    String valdisp,strOldValue;
    int row, col;
    boolean fDot, fStartData;
    int OldOpID;
    //hàm khởi tạo đối tượng
    SampleCanvas() {
    //thiết lập font chữ cần dùng
    font = Font.getFont(Font.FACE_PROPORTIONAL,
    Font.STYLE_BOLD, Font.SIZE_LARGE);
    MyInit();
    }
    //hàm thiết lập trạng thái đầu cho Calculator
    public void MyInit() {
    //xác định độ rộng, độ cao của form
    ww=this.getWidth();
    wh = this.getHeight();
    //xác định độ rộng, độ cao của từng button
    bw= (ww-15)/4;
    bh = 25;
    //xác định vị trí trên trái của vùng làm việc
    baseX = 3; baseY= 4;
    valdisp = "0.";
    fStartData = true;
    fDot = false;
    strOldValue = "0";
    OldOpID = EQUALID;
    repaint();
    }
    //hàm xử lý phím ấn, hiện chỉ có khung sườn
    protected void keyPressed(int key) {
    int action = getGameAction(key);
    switch (action) {
    case LEFT:
    break;
    case RIGHT:
    break;
    case UP:
    break;
    case DOWN:
    break;
    case FIRE:
    break;
    }
    repaint();
    }

    //hàm cập nhật màn hình tinh thể lỏng
    protected void UpdateDisplay(int d) {
    if(fStartData) {
    valdisp = Integer.toString(d);
    fStartData = fDot = false;
    } else
    valdisp = valdisp + Integer.toString(d);
    repaint();
    }

    //hàm xử lý phím phép toán
    private void Op_Process(int op) {
    double dblOldValue;
    double dblValue;
    //xác định 2 toán hạng
    dblValue = Double.parseDouble(valdisp);
    dblOldValue = Double.parseDouble(strOldValue);
    //kiểm tra phép toán cần thực hiện
    switch (OldOpID) {
    case ADDID :
    dblValue = dblOldValue + dblValue; break;
    case SUBID:
    dblValue = dblOldValue - dblValue; break;
    case MULID:
    dblValue = dblOldValue * dblValue; break;
    case DIVID :
    dblValue = dblOldValue / dblValue; break;
    }
    valdisp = Double.toString(dblValue);
    strOldValue = valdisp;
    OldOpID = op;
    fStartData = true;
    }

    //hàm xử lý sự kiện ấn chuột (chạm màn hình cảm ứng)
    protected void pointerPressed(int x, int y) {
    //kiểm tra vị trí chuột có nằm trên các button?
    if (baseY+bh+3 > y || y > baseY + (bh+3)*6) return;
    //xác định vị trí button được chọn
    col = (x - baseX) / (bw+3);
    row = (y - baseY-bh-3) / (bh+3);
    switch (row) {
    case 0: //các button hàng đầu
    switch (col) {
    case 0: //nút C
    MyInit(); break;
    case 1: //nút sqrt
    valdisp = Double.toString(Math.sqrt(Double.parseDouble(valdisp)));
    break;
    case 2: //nút 1/x
    valdisp = Double.toString(1/Double.parseDouble(valdisp)); break;
    case 3: //nút /
    Op_Process(DIVID);
    }
    break;
    case 1: //các button hàng thứ 2
    switch (col) {
    case 0: //nút 7
    UpdateDisplay(7); break;
    case 1: //nút 8
    UpdateDisplay(8); break;
    case 2: //nút 9
    UpdateDisplay(9); break;
    case 3: //nút *
    Op_Process(MULID);
    }
    break;
    case 2: //các button hàng thứ 2
    switch (col) {
    case 0: //nút 4
    UpdateDisplay(4); break;
    case 1: //nút 5
    UpdateDisplay(5);break;
    case 2: //nút 6
    UpdateDisplay(6);break;
    case 3: //nút -
    Op_Process(SUBID);
    }
    break;
    case 3: //các button hàng thứ 3
    switch (col) {
    case 0: //nút 1
    UpdateDisplay(1);break;
    case 1: //nút 2
    UpdateDisplay(2); break;
    case 2: //nút 3
    UpdateDisplay(3);break;
    case 3: //nút +
    Op_Process(ADDID);
    }
    break;
    case 4: //các button hàng thứ 4
    switch (col) {
    case 0: //nút 0
    UpdateDisplay(0);break;
    case 1: //nút .
    if (fStartData) {
    valdisp = "0.";
    fStartData = false;
    } else if (fDot==false) {
    valdisp = valdisp + ".";
    fDot = true;
    }
    break;
    case 2: //nút +/-
    //nếu là số âm thì đổi thành dương và ngược lại
    if (valdisp.charAt(0)!= '-') {
    //chỉ đảo dấu khi giá trị khác 0
    if (Double.parseDouble(valdisp) != 0)
    valdisp = "-" + valdisp;
    } else valdisp = valdisp.substring(1);
    break;
    case 3: //nút =
    Op_Process(EQUALID);
    }
    break;
    }
    repaint();
    }

    //hàm hiển thị các đối tượng trong form
    protected void paint(Graphics g) {
    int x, y;
    gh = g;
    g.setFont(font);
    x = baseX;
    y = baseY;
    //vẽ textbox miêu tả màn hình display
    gh.setColor(128,128,128);
    gh.fillRect(x, y, ww-6,bh);
    gh.setColor(0,255,255);
    gh.drawRect(x, y, ww-6,bh);
    gh.setColor(255,255,255);
    gh.drawString(valdisp, ww-8, y, Graphics.RIGHT|Graphics.TOP);
    //vẽ hàng button thứ nhất
    y = y + bh+3;
    DispButton(x, y,"C",0);
    DispButton(x+bw+3, y,"sqrt",0);
    DispButton(x+(bw+3)*2, y,"1/x",0);
    DispButton(x+(bw+3)*3, y,"/",0);
    //vẽ hàng button thứ nhất
    y = y + bh+3;
    DispButton(x, y,"7",0);
    DispButton(x+bw+3, y,"8",0);
    DispButton(x+(bw+3)*2, y,"9",0);
    DispButton(x+(bw+3)*3, y,"*",0);
    //vẽ hàng button thứ nhất
    y = y + bh+3;
    DispButton(x, y,"4",0);
    DispButton(x+bw+3, y,"5",0);
    DispButton(x+(bw+3)*2, y,"6",0);
    DispButton(x+(bw+3)*3, y,"-",0);
    //vẽ hàng button thứ nhất
    y = y + bh+3;
    DispButton(x, y,"1",0);
    DispButton(x+bw+3, y,"2",0);
    DispButton(x+(bw+3)*2, y,"3",0);
    DispButton(x+(bw+3)*3, y,"+",0);
    //vẽ hàng button thứ 5
    y = y + bh+3;
    DispButton(x, y,"0",0);
    DispButton(x+bw+3, y,".",0);
    DispButton(x+(bw+3)*2, y,"+/-",0);
    DispButton(x+(bw+3)*3, y,"=",0);
    }
    //hàm vẽ 1 button
    private void DispButton(int x, int y, String str, int flag) {
    if (flag==0) { //ở trạng thái chưa chọn
    gh.setColor(128,128,128);
    gh.fillRect(x, y, bw,bh);
    gh.setColor(0,255,255);
    gh.drawRect(x, y, bw,bh);
    gh.setColor(0,0,255);
    gh.drawString(str, x+15, y, Graphics.LEFT|Graphics.TOP);
    } else { //ở trạng thái đang chọn
    gh.setColor(0,0,255);
    gh.fillRect(x, y, bw,bh);
    gh.setColor(0,255,255);
    gh.drawRect(x, y, bw,bh);
    gh.setColor(255,255,255);
    gh.drawString(str, x+15, y, Graphics.LEFT|Graphics.TOP);
    }
    }
    }

    4. Chọn menu Run.Run Project để dịch và chạy thử ứng dụng. Nếu bạn nhập đúng mọi hàng lệnh như được liệt kê ở trên thì chương trình sẽ chạy tốt.

    5. Vào thư mục Calculator\dist, copy file Calculator.jar sang điện thoại di động và chạy nó thử trên điện thoại di động. Nếu điện thoại của bạn là điện thoại cảm ứng, hỗ trợ các version CLDC và MIDP như lúc cấu hình cho ứng dụng thì ứng dụng sẽ chạy tốt.

    Chuyên mục: Lập trình