Thứ Tư, 14 tháng 8, 2013

nhập văn bản trực tiếp từ Canvas

thường thì muốn nhập chuỗi thì ta thiết kế sử dụng TextBox hoặc là TextField trên Form, nhưng trong game nên hạn chế cho người dùng sử dụng giao diện bậc cao như vậy. Ta sẽ cho nhập văn bản trực tiếp từ bàn phím trên Canvas dựa vào hàm keyPressed(int i) :
C:\Users\WIN7\Documents\NetBeansProjects\textfield\src\textfield.java
  1 //textfield.java
  2 import javax.microedition.lcdui.*;
  3 
  4 public class textfield {
  5 
  6     int x, y, w, lk = 0, np = 0, fh, tcolor = 0, bgcolor = 0xf0f0f0;
  7     String s = "", title;
  8     //mảng ac chứa các kí tự cần thiết tương ứng với các phím bấm từ 0 đến 9
  9     String[] ac = {" 0", ".,1", "abc2", "def3", "ghi4", "jkl5", "mno6", "pqrs7", "tuv8", "wxyz9"};
 10     long lp = 0, rr = 0;
 11     boolean focus = false;
 12     Font f = Font.getFont(0, 0, 8);
 13 //hàm khởi tạo textfield nhận các giá trị tiêu đề (title), vị trí đặt hộp text(x, y), và chiều rộng hộp (w)
 14     public textfield(String title, int x, int y, int w) {
 15         this.title = title;
 16         this.x = x;
 17         this.y = y;
 18         this.w = w;
 19         fh = f.getHeight();
 20     }
 21 
 22     String getString() {
 23         return s;
 24     }
 25 //hàm paint này dùng vẽ textfield lên Graphic (g) và được dùng trên Canvas, nó nhận các biến tham số: Graphics g, biến mã phím int k, và biến boolean focus chỉ định là có thực hiện thao tác với textfield này không
 26     public void paint(Graphics g, int k, boolean focus) {
 27         g.setFont(f);
 28         this.focus = focus;
 29         //nếu có tác động focus==true thì cho thực hiện vẽ chuỗi theo mã phím
 30         if (focus && cr() - lp > rr) {
 31             add(k);
 32         }
 33         //các hàm vẽ liên quan đến việc vẽ chuỗi s ra màn hình
 34         int slen = f.stringWidth(s);
 35         int kh = slen - w;
 36         g.setColor(bgcolor);
 37         g.fillRect(x, y + fh, w, fh);
 38         g.drawString(title + ":", x, y, Graphics.TOP | Graphics.LEFT);
 39         g.setColor(tcolor);
 40         g.setClip(x, y + fh, w, fh);
 41         g.drawString(s + (focus ? "|" : ""), x - (kh > 0 ? kh : 0), y + fh, Graphics.TOP | Graphics.LEFT);
 42 
 43 
 44     }
 45 
 46     void add(int k) {
 47         //nếu key là -3(phím qua trái) thì cho xóa kí tự
 48         if (k == -3 && s.length() > 0) {
 49             s = s.substring(0, s.length() - 1);
 50             lk = k;
 51             lp = cr();
 52         } else if (k == -6) {//nếu key là -6 thì thôi không tác động đến textfield này nữa
 53             focus = false;
 54         } else {
 55             //tìm vị trí của phím bấm từ 0 đến 9, do phím 0 có mã phím là 48 nên ta lần lượt trừ cho 48 sẽ tương ứng với vị trí của bảng kí tự trong mảng chuổi ac
 56             int sk = k - 48;
 57             //nếu như sk lớn hơn 0 thì cho thực hiện tiếp, tương đương là bấm các phím từ 0->9
 58             if (sk >= 0) {
 59                 //nếu thời gian hiện tại trừ lp(lần nhấn sau cùng) <800 và phím nhấn lần này giống với phím bấm lần sau cùng thì cho tăng np (index cần lấy của kí tự trong chuỗi).
 60                 if (cr() - 800 < lp && lk == sk) {
 61                     np++;
 62                     if (np == ac[sk].length()) {
 63                         np = 0;
 64                     }
 65                     s = s.substring(0, s.length() - 1);
 66                     s += ac[sk].charAt(np);
 67                 } else {//ngược lại thì cho thêm vào kí tự thích hợp với phím bấm(kí tự đầu tiên tương ứng các mảng giá trị)
 68                     np = 0;
 69                     s += ac[sk].charAt(np);
 70                 }
 71                 //đặt mả phím sau cùng và lk (phím bấm sau cùng) và thời gian bấm sau cùng lp (lần nhấn sau cùng)
 72                 lk = sk;
 73                 lp = cr();
 74             }
 75 
 76         }
 77     }
 78 //hàm cr() trả lại thời gian hiện thời
 79     long cr() {
 80         return System.currentTimeMillis();
 81     }
 82 }
 83 
 84 class canvas extends Canvas {
 85 //tạo một biến textfield mới, với tiêu đề là "nhập văn bản", ở tọa độ (0,120) và chiều rông màn hình
 86     textfield tf = new textfield("nhập văn bản", 0, 120, 40);
 87     int w = getWidth(), h = getHeight(), k = 0;
 88 
 89     public canvas() {
 90     }
 91 
 92     public void paint(Graphics g) {
 93         g.setColor(0);
 94         g.fillRect(0, 0, w, h);
 95         //thực hiện lệnnh vẽ textfield ra màn hình lên Graphics g và với mã phím k
 96         tf.paint(g, k, true);
 97         k=0;
 98         repaint();
 99     }
100 
101     public void keyPressed(int k) {
102         this.k = k;
103     }
104 
105     public void keyReleased(int k) {
106         this.k = 0;
107     }
108 }
• ở đây chúng ta chỉ cần lưu ý là trong textfield.java có các biến đảm nhận thời gian như là lp, để xác định lần nhấn phím sau cùng mà người dùng nhấn. sau đó so sánh với giá trị thời gian hiện tại lấy từ hàm cr(), nếu như mà hai giá trị này chênh nhau quá 800ms thì cho cộng vào chuỗi một kí tự mới tương ứng với index 0 trong giá trị của phím trong mảng chuỗi ac. Còn nếu như mà thấy thời gian chênh nhau giữa lp và cr() trong 800ms trở lại và mã phím cũng là mã phím nhấn sau cùng thì cho tăng index lấy kí tự trong mã phím hiện tại và kết quả là thay đổi kí tự vừa mới ghi lúc nãy chứ không thêm kí tự mới nào. • Tải jar •Tải zip

Không có nhận xét nào:

Đăng nhận xét