1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Lập trình trên di động với J2ME

129 1 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 129
Dung lượng 1,35 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Cấu trúc

  • I. Giới thiệu về J2ME (5)
    • 1. Lịch sử (5)
    • 2. Lý do chọn J2ME (5)
    • 3. Kiến trúc của J2ME (5)
    • 4. Giới thiệu MIDP (8)
    • 5. Môi trường phát triển J2ME (9)
  • II. Các thành phần giao diện ở mức cao của ứng dụng MIDP (13)
    • 1. Đối tượng Display, Displayable và Screens (13)
    • 2. Thành phần Form và Items (14)
    • 3. Thành phần List, Textbox, Alert, và Ticker (25)
  • III. Các thành phần giao diện ở mức thấp của ứng dụng MIDP (33)
    • 1. Các hàm API ở mức thấp (33)
    • 2. Lớp Canvas (33)
    • 3. Lớp Graphics (42)
    • 4. Các hàm API dùng để lập trình Game (58)
  • IV. Xử lý sự kiện (59)
    • 1. Đối tượng Command (59)
    • 2. Đối tượng Item (60)
    • 3. Ví dụ (60)
  • V. Record Management System (62)
    • 1. Persistent Storage Through the Record Store (62)
    • 2. Các vấn đề liên quan đến RMS (64)
    • 3. Các hàm API trong RMS (64)
    • 4. Duyệt Record với RecordEnumeration (74)
    • 5. Sắp xếp các record với interface RecordComparator (75)
    • 6. Searching with RecordFilter (91)
    • 7. Notification of Changes with RecordListener (103)
    • 8. Exception Handling (107)
  • VI. The Generic Connection Framework (108)
    • 1. Những protocol được hỗ trợ trong GCF (108)
    • 2. Hỗ trợ giao thức HTTP trong MIDP (113)
    • 3. Accessing a Java servlet (122)

Nội dung

Giới thiệu về J2ME a Giới thiệu các thành phần trong nền tảng J2ME: Định nghĩa về Configuration Cấu hình: là đặc tả định nghĩa một môi trường phần mềm cho một dòng các thiết bị được phâ

Giới thiệu về J2ME

Lịch sử

J2ME được phát triển dựa trên kiến trúc Java Card, Embedded Java và Personal Java của Java 1.1, nhằm tối ưu cho các thiết bị nhỏ gọn Khi Java 2 ra đời, Sun Microsystems đã thay thế Personal Java bằng Java 2 Micro Edition (J2ME), nền tảng chuyên biệt cho các thiết bị có hạn chế về bộ nhớ và hiệu suất J2ME là giải pháp lý tưởng cho các thiết bị di động, máy tính nhúng và các thiết bị thông minh nhỏ nhắn, mang lại khả năng lập trình linh hoạt và tối ưu hóa hiệu quả hoạt động.

Lý do chọn J2ME

Java ban đầu được thiết kế dành cho các máy với tài nguyên bộ nhớ hạn chế, giúp tối ưu hóa hiệu suất và khả năng hoạt động trên các thiết bị có hạn chế về phần cứng Thị trường của J2ME sau đó đã mở rộng ra cho nhiều chủng loại thiết bị khác nhau, từ điện thoại di động đến các thiết bị cầm tay, tạo ra khả năng phát triển phần mềm đa dạng và phù hợp với nhiều nền tảng.

• Các lọai thẻ cá nhân như Java Card

• Máy điện thoại di động

• Máy PDA (Personal Digital Assistant - thiết bị trợ giúp cá nhân)

• Các hộp điều khiển dành cho tivi, thiết bị giải trí gia dụng …

Kiến trúc của J2ME

Phần này sẽ trình bày kiến trúc tổng quát của nền tảng Java

J2ME (Java 2 Platform, Micro Edition) là nền tảng phát triển phần mềm dành cho các thiết bị di động và phần cứng có khả năng hạn chế về tài nguyên Trong đó, các thành phần chính của J2ME bao gồm các cấu hình (Configurations), Profiles và Java APIs phù hợp với từng loại thiết bị Cấu hình (Configuration) là đặc tả định nghĩa một môi trường phần mềm cho một dòng thiết bị cụ thể, phân loại dựa trên các đặc tính như bộ xử lý, bộ nhớ và khả năng xử lý của thiết bị đó Điều này giúp các nhà phát triển tối ưu hóa ứng dụng phù hợp với từng loại thiết bị di động khác nhau trong nền tảng J2ME.

• Kiểu và số lượng bộ nhớ

• Kiểu và tốc độ bộ vi xử lý

Đây là đặc tả kỹ thuật quan trọng, buộc các nhà sản xuất thiết bị như Samsung, Nokia phải tuân thủ đầy đủ theo các tiêu chuẩn do Sun quy định Việc này giúp lập trình viên dựa vào môi trường lập trình nhất quán, đảm bảo các ứng dụng được phát triển có thể hoạt động độc lập với thiết bị tối đa Ví dụ, một nhà phát triển game cho điện thoại Samsung có thể dễ dàng điều chỉnh mã nguồn để chạy trên điện thoại Nokia với tối thiểu các sửa đổi cần thiết.

Hiện nay Sun đã đưa ra 2 dạng Configuration:

CLDC (Connected Limited Device Configuration - Cấu hình thiết bị kết nối giới hạn) được thiết kế nhằm phục vụ thị trường các thiết bị cấp thấp như điện thoại di động và PDA có bộ nhớ khoảng 512 KB Do hạn chế về tài nguyên bộ nhớ, CLDC tích hợp với Java không dây (Java Wireless), cho phép người dùng mua và tải về các ứng dụng Java như Midlet một cách dễ dàng.

CDC (Connected Device Configuration) được thiết kế để tối ưu hóa cho các thiết bị có khả năng mạnh hơn dòng thiết bị CLDC nhưng vẫn chưa đạt đến mức của hệ thống máy để bàn sử dụng J2SE Những thiết bị này thường có bộ nhớ lớn hơn, thường trên 2MB, và bộ xử lý nhanh hơn, phù hợp cho các sản phẩm như PDA cao cấp, điện thoại web và các thiết bị gia dụng thông minh trong gia đình.

Cả 2 dạng Cấu hình kể trên đều chứa máy ảo Java (Java Virtual Machine) và tập hợp các lớp (class) Java cơ bản để cung cấp một môi trường cho các ứng dụng J2ME Tuy nhiên, bạn chú ý rằng đối với các thiết bị cấp thấp, do hạn chế về tài nguyên như bộ nhớ và bộ xử lý nên không thể yêu cầu máy ảo hổ trợ tất cả các tính năng như với máy ảo của J2SE, ví dụ, các thiết bị thuộc CLDC không có phần cứng yêu cầu các phép tính toán dấu phẩy động, nên máy ảo thuộc CLDC không được yêu cầu hỗ trợ kiểu float và double

Bảng dưới là sự so sánh các thông số kỹ thuật của CDC và CLDC

Profile (nguồn pin) là phần mở rộng của cấu hình, được xây dựng bằng cách thêm các class để bổ trợ chức năng cho từng thiết bị chuyên biệt Cả hai cấu hình đều có các profile liên quan, cho phép sử dụng lẫn nhau dựa trên các class được định nghĩa trong các profile này Mỗi profile định nghĩa một tập hợp các class riêng biệt, khiến cho việc chuyển đổi một ứng dụng Java giữa các profile hoặc nền tảng khác nhau thường không khả thi Do đó, một ứng dụng Java viết cho một profile cụ thể thường không thể chạy trên các thiết bị hỗ trợ profile khác hoặc trên các nền tảng khác như J2SE hay J2EE Các profile tiêu biểu trong Java ME giúp tối ưu hóa khả năng hỗ trợ đa dạng thiết bị và nền tảng.

Mobile Information Device Profile (MIDP) là một profile giúp bổ sung các tính năng như hỗ trợ kết nối và giao diện người dùng vào CLDC, chủ yếu hướng đến điện thoại di động có màn hình hạn chế và dung lượng lưu trữ giới hạn MIDP cung cấp giao diện người dùng đơn giản và các chức năng mạng dựa trên HTTP, giúp tối ưu hóa cho thiết bị di động Đây là profile phổ biến nhất trong lĩnh vực Wireless Java, vì nó là nền tảng cơ bản cho lập trình Java trên các máy di động.

• PDA Profile: tương tự MIDP, nhưng với thị trường là các máy PDA với màn hình và bộ nhớ lớn hơn

• Foundation Profile: cho phép mở rộng các tính năng của CDC với phần lớn các thư viện của bộ Core Java2 1.3

Ngoài ra còn có Personal Basis Profile, Personal Profile, RMI Profile, Game Profile.

Giới thiệu MIDP

MIDP (Mobile Information Device Profile) là profile được thiết kế riêng cho các thiết bị di động, đóng vai trò quan trọng trong phát triển ứng dụng J2ME Nó cung cấp các chức năng cơ bản phù hợp cho hầu hết các dòng điện thoại di động và PDA phổ biến, giúp mở rộng khả năng của các thiết bị này Tuy nhiên, MIDP không phải là giải pháp phù hợp cho mọi lập trình viên bởi vì nó được tối ưu hóa cho các thiết bị có cấu hình thấp, đòi hỏi phải xem xét kỹ lưỡng các tính năng phù hợp để phát triển ứng dụng hiệu quả.

MIDP cung cấp và những giới hạn của nó b) Những chức năng MIDP không thực hiện được:

Phép tính dấu phẩy động (floating point) yêu cầu nhiều tài nguyên CPU, gây khó khăn cho các thiết bị di động có bộ xử lý hạn chế Chính vì lý do này, hầu hết các CPU trên thiết bị di động không hỗ trợ phép tính này, và do đó, MIDP cũng không cung cấp hỗ trợ cho phép tính dấu phẩy động.

• Bộ nạp class (Class Loader)

• Hỗ trợ từ khóa finalize() như trong J2SE: Việc “dọn dẹp“ tài nguyên trước khi nó bị xóa được đẩy về phía các lập trình viên

• Hỗ trợ hạn chế thao tác bắt lỗi

• Phần lớn các thư viện API cho Swing và AWT không thể sử dụng được trong MIDP

Các thiết bị J2ME không hỗ trợ các tính năng quản lý file và thư mục, điều này có thể khiến bạn ngạc nhiên, nhưng thực tế chúng không có khả năng lưu trữ như ổ cứng thông thường Tuy nhiên, bạn vẫn có thể lưu trữ dữ liệu quan trọng khi tắt máy nhờ vào hệ thống quản lý ghi lại (Record Management System - RMS), được Sun phát triển để cung cấp khả năng lưu trữ dữ liệu cho các thiết bị này Các chức năng của MIDP được thiết kế để hỗ trợ lưu trữ và quản lý dữ liệu hiệu quả trên các thiết bị Java ME.

Các lớp và kiểu dữ liệu trong Java vẫn giữ nguyên nhiều đặc điểm quen thuộc, chẳng hạn như các lớp trong gói java.util như Stack, Vector, Hashtable và Enumeration Những thành phần này đóng vai trò quan trọng trong việc xây dựng các ứng dụng Java hiệu quả và linh hoạt, giúp lập trình viên dễ dàng quản lý dữ liệu và tối ưu hóa hiệu suất.

Chương trình MIDP dành riêng để hỗ trợ đối tượng Display, đảm nhận nhiệm vụ quản lý việc hiển thị dữ liệu trên màn hình điện thoại Đây là thành phần quan trọng trong việc hiển thị thông tin chính xác và rõ ràng cho người dùng, đảm bảo trải nghiệm người dùng tốt hơn.

• Hỗ trợ Form và các giao diện người dùng

• Hỗ trợ Timer và Alert

• Cung cấp tính năng Record Management System (RMS) cho việc lưu trữ dữ liệu

Vào tháng 11 năm 2003, Sun Microsystems giới thiệu MIDP 2.0 và cung cấp nhiều tính năng mới cải tiến so với phiên bản MIDP 1.0 Những nâng cấp đáng chú ý bao gồm khả năng hỗ trợ nhiều tính năng đa dạng hơn, nâng cao hiệu suất và trải nghiệm người dùng trên các thiết bị di động Việc ra mắt MIDP 2.0 đã đánh dấu bước tiến lớn trong phát triển nền tảng Java cho điện thoại di động, mở ra nhiều cơ hội mới cho các nhà phát triển ứng dụng.

Chúng tôi đã nâng cấp các tính năng bảo mật quan trọng để đảm bảo an toàn tối đa cho người dùng Cải tiến nổi bật bao gồm việc hỗ trợ giao thức HTTPS để tải xuống qua mạng an toàn hơn, giúp bảo vệ dữ liệu khỏi các mối đe dọa từ bên ngoài Ngoài ra, hệ thống kiểm soát kết nối giữa thiết bị di động và máy chủ được cập nhật, yêu cầu người dùng phải có sự chấp thuận rõ ràng trước khi các chương trình có thể kết nối tới server, tăng cường bảo mật và quyền kiểm soát của người dùng.

MIDP 2.0 đã mở rộng khả năng hỗ trợ đa phương tiện bằng cách thêm các API hỗ trợ Multimedia Một trong những cải tiến nổi bật của phiên bản này là bộ API media, cung cấp các chức năng liên quan đến âm thanh, giúp nâng cao trải nghiệm người dùng trên các thiết bị di động Các API media của MIDP 2.0 chủ yếu tập trung vào khả năng xử lý âm thanh qua Mobile Media API (MMAPI), đem lại nền tảng vững chắc cho phát triển ứng dụng đa phương tiện trên đội ngũ thiết bị di động cảm ứng.

Trong MIDP 2.0, các tính năng của Form đã được mở rộng đáng kể, với nhiều cải tiến quan trọng trong API javax.microedition.lcdui, đặc biệt là trong phần Form và Item Những cập nhật này mang lại khả năng tùy chỉnh và linh hoạt hơn trong việc phát triển giao diện người dùng trên các thiết bị di động Java Những thay đổi lớn này không chỉ nâng cao trải nghiệm người dùng mà còn giúp các nhà phát triển dễ dàng tối ưu hóa ứng dụng của mình trên nền tảng MIDP 2.0.

Sun nhận thấy tiềm năng lớn của thị trường game trên thiết bị di động và đã phát triển Game API để hỗ trợ lập trình viên Trong MIDP 1.0, các lập trình viên phải tự viết mã để quản lý nhân vật và đồ họa, dẫn đến tăng kích thước file và dễ gặp lỗi Với sự ra đời của Game API trong MIDP 2.0, không chỉ các nhà phát triển game mà còn các lập trình viên sử dụng các tính năng đồ họa cao cấp hưởng lợi, nhờ vào khả năng quản lý các lớp (layer) như trong các trò chơi đua xe, giúp đơn giản hóa quá trình lập trình và nâng cao trải nghiệm người dùng Ngoài ra, Game API còn cung cấp các chức năng quản lý thao tác bàn phím, tối ưu hóa khả năng tương tác và điều khiển trong game.

Hỗ trợ kiểu ảnh RGB là một cải tiến quan trọng dành cho các nhà phát triển MIDP, giúp biểu diễn hình ảnh dưới dạng mảng số nguyên Điều này cho phép MIDlet thao tác trực tiếp với dữ liệu hình ảnh, tối ưu hóa quá trình xử lý hình ảnh trên các thiết bị di động Việc này không chỉ nâng cao hiệu suất mà còn mở rộng khả năng sáng tạo trong phát triển ứng dụng, đáp ứng tốt hơn các yêu cầu về đồ họa và trải nghiệm người dùng.

Môi trường phát triển J2ME

J2ME là môi trường phát triển ứng dụng phổ biến dành cho các thiết bị di động, với nhiều nền tảng khác nhau phù hợp với từng hãng điện thoại Mỗi nhà sản xuất đều cung cấp môi trường phát triển riêng để tối ưu hóa khả năng vận hành của các ứng dụng trên thiết bị của họ Trong bài viết này, chúng tôi sẽ giới thiệu về toolkit của Sun Technologies – J2ME, một trong những nền tảng phát triển ứng dụng di động hàng đầu, giúp các lập trình viên tạo ra các ứng dụng linh hoạt và đa dạng cho điện thoại di động Java.

Wireless Toolkit Địa chỉ download chương trình: http://java.sun.com/j2me/download.html Ngoài ra bạn cần phải có J2SDK 1.4 trở lên

Sau khi cài đặt bạn chạy chương trình tại:

Giao diện của chương trình:

Sau khi hoàn thành các bước chuẩn bị, bạn có thể bắt đầu viết mã nguồn đầu tiên Nhấp vào nút "New Project" để tạo dự án mới, sau đó nhập tên dự án và lớp (Class) mong muốn, ví dụ như "TestMidlet", để bắt đầu phát triển ứng dụng của mình một cách dễ dàng và chuyên nghiệp.

Bạn không cần phải đặt tên class trùng với tên dự án trong quá trình phát triển Trên cửa sổ chương trình sẽ hiển thị các thông báo liên quan đến việc tạo các thư mục cần thiết để xây dựng và thực thi mã nguồn một cách hiệu quả Việc này giúp đảm bảo quá trình phát triển phần mềm diễn ra thuận lợi và tránh các lỗi không đáng có liên quan đến tên lớp hoặc thư mục.

Hãy để ý thư mục : “E:\WTK22\apps\Example\src”, đây sẽ là nơi chứa source của ứng dụng

You can use any text editor to write your code in Java ME, such as importing javax.microedition.lcdui.* and javax.microedition.midlet.* packages Create a MIDlet class that extends MIDlet and implements CommandListener to handle user commands For example, initialize a Form with the title "Lap trinh voi J2ME," add a message like "Hello world!, MIDP!" to the form, and include an "Exit" command to allow users to terminate the application Setting the command listener ensures the app responds appropriately to user inputs, making it a simple and effective way to develop mobile applications using J2ME.

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

} public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void commandAction(Command c, Displayable s) { notifyDestroyed();

Sau đó copy source này vào thư muc nói trên Rồi tiến hành build và run chương trình

Vòng đời của một MIDlet

Midlet là một phần mềm nhỏ trong hệ sinh thái Java ME, tương tự như các Applet trong J2SE, và luôn kế thừa từ javax.microedition.midlet để đảm bảo tính tương thích Hàm quan trọng nhất trong mọi Midlet là startApp(), có nhiệm vụ khởi tạo và bắt đầu hoạt động của ứng dụng Việc triển khai hàm này giúp Midlet có thể bắt đầu chạy một cách hiệu quả trên các thiết bị di động.

Trong quá trình vận hành, mỗi Midlet không chỉ có phương thức startApp() để khởi động, mà còn có pauseApp() và destroyApp() để xử lý các trạng thái tạm dừng và thoát ứng dụng Các hàm này sẽ được gọi tự động khi người dùng chọn dừng hoặc thoát chương trình, đảm bảo quản lý tài nguyên hiệu quả và trải nghiệm người dùng mượt mà.

Các thành phần giao diện ở mức cao của ứng dụng MIDP

Đối tượng Display, Displayable và Screens

Trong phát triển ứng dụng MIDlet, chỉ có một đối tượng Display duy nhất đại diện cho giao diện người dùng Đối tượng này chịu trách nhiệm cung cấp thông tin về các khả năng trình bày của thiết bị, như hỗ trợ màu sắc, và cung cấp các phương thức để yêu cầu hiển thị các thành phần giao diện Đối tượng Display đóng vai trò thiết yếu trong quản lý việc hiển thị nội dung trên thiết bị, đảm bảo các thành phần trình bày phù hợp và hiệu quả.

Mặc dù mỗi MIDlet chỉ có một đối tượng Display duy nhất, nhưng bên trong MIDlet có thể có nhiều thành phần giao diện người dùng như Forms, TextBoxes, và ChoiceGroups được hiển thị trên thiết bị.

Trong Java ME, một đối tượng Displayable đại diện cho thành phần có thể hiển thị trên thiết bị MIDP gồm hai lớp con của lớp Displayable là Screen và Canvas, trong đó Screen thường đại diện cho các giao diện người dùng như màn hình chính hoặc các hộp thoại, còn Canvas cho phép xử lý đồ họa tùy chỉnh Mối quan hệ giữa các lớp này thể hiện rõ trong sơ đồ, giúp người lập trình hiểu cách xây dựng và quản lý giao diện của ứng dụng di động phù hợp chuẩn SEO.

Lớp Screen không đơn thuần là một yếu tố hiển thị trên thiết bị, mà còn là nền tảng để các thành phần giao diện cấp cao kế thừa và trình bày nội dung Các thành phần này, chính là các phần tử hiển thị trực tiếp trên màn hình, được xây dựng dựa trên lớp Screen để đảm bảo khả năng hiển thị và cấu trúc hợp lý Mối quan hệ giữa lớp Screen và các thành phần thể hiện ở cấp cao sẽ được mô tả rõ trong hình ảnh minh họa, giúp ta hiểu rõ hơn về cấu trúc và chức năng của hệ thống hiển thị.

Các thành phần giao diện ở mức cao

Tóm lại, phần này chỉ giới thiệu hệ thống phân cấp đối tượng dùng để thể hiện giao diện người dùng trong MIDP.

Thành phần Form và Items

Trong phần này, chúng tôi giới thiệu các thành phần hiển thị trên một Form – một khung chứa các thành phần giao diện người dùng được kế thừa từ lớp Item Các thành phần này đóng vai trò quan trọng trong việc tạo lập các form chuyên nghiệp và dễ sử dụng trên thiết bị, giúp tối ưu trải nghiệm người dùng và phù hợp với các tiêu chuẩn thiết kế UI/UX.

Thành phần DateField cung cấp một phương tiện trực quan để thao tác đối tượng

Trong Java, lớp java.util.Date được sử dụng để đại diện cho ngày tháng và giờ dựa trên thời gian tính theo milliseconds kể từ ngày 1 tháng 1 năm 1970 Khi tạo đối tượng DateField, bạn cần xác định rõ liệu người dùng chỉ được phép chỉnh sửa ngày, giờ hoặc cả hai để phù hợp với yêu cầu của ứng dụng Việc kiểm soát này giúp nâng cao trải nghiệm người dùng và đảm bảo tính chính xác của dữ liệu ngày tháng và giờ trong hệ thống.

Các phương thức dựng của lớp DateField gồm:

DateField(String label, int mode) DateField(String label, int mode, TimeZone timeZone)

Các mode tương ứng của lớp DateField gồm:

DateField.DATE_TIME: cho phép thay đổi ngày giờ DateField.TIME: chỉ cho phép thay đổi giờ

DateField.DATE: chỉ cho phép thay đổi ngày

Ví dụ: private DateField dfAlarm;

// Tạo một đổi tượng DateField với nhãn, cho phép thay đổi cả ngày và giờ dfAlarm = new DateField("Set Alarm Time", DateField.DATE_TIME); dfAlarm.setDate(new Date());

This article introduces a sample program demonstrating the use of the DateField component in Java ME The code imports essential libraries such as java.util.*, javax.microedition.midlet.*, and javax.microedition.lcdui.* to facilitate MIDlet development and user interface design The DateFieldTest class extends MIDlet and implements ItemStateListener and CommandListener interfaces, showcasing how to create interactive mobile applications that handle user input and commands effectively This example serves as a practical reference for developers looking to implement date selection features in Java ME applications.

{ private Display display; // Reference to display object private Form fmMain; // Main form private Command cmExit; // Exit MIDlet private DateField dfAlarm; // DateField component public DateFieldTest() { display = Display.getDisplay(this);

// The main form fmMain = new Form("DateField Test");

// DateField with todays date as a default dfAlarm = new DateField("Set Alarm Time", DateField.DATE_TIME); dfAlarm.setDate(new Date());

// All the commands/buttons cmExit = new Command("Exit", Command.EXIT, 1);

// Add to form and listen for events fmMain.append(dfAlarm); fmMain.addCommand(cmExit); fmMain.setCommandListener(this); fmMain.setItemStateListener(this);

} public void startApp () { display.setCurrent(fmMain);

} public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void itemStateChanged(Item item) {

System.out.println("Date field changed.");

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

Các thành phần giao diện ở mức cao b) Gauge

Gauge là một thành phần giao diện phổ biến dùng để hiển thị mức độ hoàn thành của một công việc hoặc mục tiêu cụ thể Có hai loại Gauge chính: loại tương tác, cho phép người dùng thao tác và điều chỉnh dữ liệu, và loại không tương tác, chỉ dùng để hiển thị trạng thái mà không cho phép chỉnh sửa Sử dụng Gauge giúp cung cấp hình ảnh rõ ràng về tiến trình, nâng cao trải nghiệm người dùng và tối ưu hóa quản lý dự án.

Loại đầu cho phép người dùng thay đổi Gauge linh hoạt, phù hợp với nhiều nhu cầu khác nhau Tuy nhiên, loại 2 yêu cầu nhà phát triển cập nhật Gauge để đảm bảo hoạt động chính xác Dưới đây là hàm dựng của lớp Gauge, giúp hiểu rõ hơn về cách thức tạo và quản lý Gauge trong hệ thống Do đó, việc lựa chọn loại đầu phù hợp đóng vai trò quan trọng trong tối ưu hóa hiệu suất và khả năng tùy biến của ứng dụng.

Gauge(String label, boolean interactive, int maxValue, int initialValue)

Ví dụ: private Gauge gaVolume; // Điều chỉnh âm lượng gaVolume = new Gauge("Sound Level", true, 100, 4);

This article provides a sample program demonstrating how to use the Gauge class in Java ME development The code imports necessary MIDlet and LCDUI libraries and defines an InteractiveGauge class that extends MIDlet and implements CommandListener Key components include initializing display and form objects, creating a command for exiting the application, and implementing a Gauge component for volume adjustment This example illustrates how to effectively incorporate gauges into mobile applications to enhance user interaction.

// Create the gauge and exit command gaVolume = new Gauge("Sound Level", true, 50, 4); cmExit = new Command("Exit", Command.EXIT, 1);

// Create form, add commands, listen for events fmMain = new Form(""); fmMain.addCommand(cmExit); fmMain.append(gaVolume); fmMain.setCommandListener(this);

// Called by application manager to start the MIDlet public void startApp() { display.setCurrent(fmMain);

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

{ if (c == cmExit) { destroyApp(false); notifyDestroyed();

Một thành phần StringItem được dùng để hiển thị một nhãn hay chuỗi văn bản

Người dùng không thể thay đổi nhãn hay chuỗi văn bản khi chương trình đang chạy

StringItem không nhận ra sự kiện Phương thức dựng của lớp StringItem

StringItem(String label, String text)

This article provides an example of using the `StringItem` object in Java ME, showcasing how to create and manipulate UI elements within a MIDlet The code illustrates initializing display and form objects, adding a `StringItem` for messages, and implementing commands such as changing the label and exiting the application By demonstrating these core components, the article highlights essential techniques for developing user interfaces with Java ME, ensuring effective content for SEO related to Java mobile development.

// Create text message and commands siMsg = new StringItem("Website: ", "www.IBM.com"); cmChange = new Command("Change", Command.SCREEN, 1); cmExit = new Command("Exit", Command.EXIT, 1);

// Create Form, add Command and StringItem, listen for events fmMain = new Form("StringItem Test"); fmMain.addCommand(cmExit); fmMain.addCommand(cmChange); fmMain.append(siMsg); fmMain.setCommandListener(this);

// Called by application manager to start the MIDlet public void startApp() { display.setCurrent(fmMain);

Các thành phần giao diện ở mức cao public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == cmChange) {

// Change label siMsg.setLabel("Section: ");

// Change text siMsg.setText("developerWorks");

// Remove the command fmMain.removeCommand(cmChange);

} else if (c == cmExit) { destroyApp(false); notifyDestroyed();

TextField là một thành phần nhập liệu cơ bản, giúp người dùng dễ dàng nhập văn bản với các tùy chọn như chỉ định nhãn, giới hạn số ký tự tối đa và loại dữ liệu được phép nhập Ngoài ra, TextField còn hỗ trợ chức năng nhập mật khẩu, trong đó các ký tự nhập vào sẽ được che bằng ký tự mặt nạ để đảm bảo an toàn và bảo mật thông tin người dùng.

Phương thức dựng của lớp TextField

TextField(String label, String text, int maxSize, int constraints)

Thành phần thứ 3 constraints là thành phần mà chúng ta quan tâm, vì nó là phương tiện để xác định loại dữ liệu nào được phép nhập vào TextField

MIDP định nghĩa các tham số ràng buộc sau cho thành phần TextField:

• ANY: cho phép nhập bất kỳ ký tự nào

• EMAILADDR: chỉ cho phép nhâp vào các địa chỉ email hợp lệ

• NUMERIC: chỉ cho phép nhập số

• PHONENUMBER: Chỉ cho phép nhập số điện thoại

• URL: Chỉ cho phép nhập các ký tự hợp lệ bên trong URL

• PASSWORD: che tất cả các ký tự nhập vào

Dưới đây là đoạn mã minh họa việc sử dụng thành phần TextField import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class TextFieldTest extends MIDlet implements CommandListener

The application initializes by creating a display object and a main form, setting the foundation for user interaction It incorporates commands such as 'cmTest' to retrieve content from the textfield and 'cmExit' to exit the MIDlet, ensuring seamless user control A TextField component, 'tfText,' is included for user input, enabling dynamic interaction within the application.

// Create commands cmTest = new Command("Get Contents", Command.SCREEN, 1); cmExit = new Command("Exit", Command.EXIT, 1);

// Textfield for phone number tfText = new TextField("Phone:", "", 10, TextField.PHONENUMBER);

// Create Form, add Commands and textfield, listen for events fmMain = new Form("Phone Number"); fmMain.addCommand(cmExit); fmMain.addCommand(cmTest); fmMain.append(tfText); fmMain.setCommandListener(this);

// Called by application manager to start the MIDlet public void startApp() { display.setCurrent(fmMain);

} public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == cmTest) {

System.out.println("TextField contains: " + tfText.getString());

} else if (c == cmExit) { destroyApp(false); notifyDestroyed();

Các thành phần giao diện ở mức cao trong lập trình Mobile bao gồm việc áp dụng nhiều ràng buộc trên đối tượng TextField để nâng cao tính năng và phù hợp với yêu cầu người dùng Đoạn mã mẫu cho thấy cách thêm một ràng buộc thứ hai như ràng buộc số điện thoại hoặc mật khẩu, ví dụ: `tfText = new TextField("Phone:", "", 10, TextField.PHONENUMBER | TextField.PASSWORD);` Ngoài ra, còn có thành phần ChoiceGroup, giúp người dùng lựa chọn các tùy chọn phù hợp trong giao diện người dùng.

Thành phần ChoiceGroup cho phép người dùng chọn từ một danh sách đầu vào đã được định nghĩa trước ChoiceGroup có 2 loại:

• multi-selection(cho phép chọn nhiều mục): nhóm này có liên quan đến các checkbox

The exclusive selection group pertains to radio buttons, allowing users to select only one option within the group An example implementation of this using ChoiceGroup demonstrates how to create a single-choice interface in Java ME applications Below is sample code illustrating the use of ChoiceGroup with radio buttons, utilizing classes like MIDlet, ItemStateListener, and CommandListener to handle user interactions effectively.

This code snippet defines key variables for a mobile application, including references to display and form objects, commands for exiting and viewing selections, and indices for managing user choices The class constructor initializes the display object, setting up the user interface components These elements facilitate user interaction within the app, enabling features like preference selection through a ChoiceGroup and seamless navigation using commands Proper initialization of display and form objects is essential for creating an intuitive and responsive mobile user experience.

// Create a multiple choice group cgPrefs = new ChoiceGroup("Preferences", Choice.MULTIPLE);

This article discusses key preferences such as replacing tabs with spaces, saving bookmarks, and detecting file types to enhance user experience It includes options like "Select All" for efficient management and features essential commands like "Exit" for closing the application and "View" for accessing content on the screen Implementing these settings optimizes usability and streamlines navigation within the software.

// Create Form, add components, listen for events fmMain = new Form(""); choiceGroupIndex = fmMain.append(cgPrefs); fmMain.addCommand(cmExit); fmMain.addCommand(cmView); fmMain.setCommandListener(this); fmMain.setItemStateListener(this);

} public void startApp() { display.setCurrent(fmMain);

} public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == cmView) { boolean selected[] = new boolean[cgPrefs.size()];

// Fill array indicating whether each element is checked cgPrefs.getSelectedFlags(selected); for (int i = 0; i < cgPrefs.size(); i++) System.out.println(cgPrefs.getString(i) + (selected[i] ? ": selected" : ": not selected"));

} else if (c == cmExit) { destroyApp(false); notifyDestroyed();

} } public void itemStateChanged(Item item) { if (item == cgPrefs) {

// Is "Select all" option checked ? if (cgPrefs.isSelected(selectAllIndex)) {

// Set all checkboxes to true for (int i = 0; i < cgPrefs.size(); i++) cgPrefs.setSelectedIndex(i, true);

// Remove the check by "Select All" cgPrefs.setSelectedIndex(selectAllIndex, false);

Các thành phần giao diện ở mức cao

Spacer là thành phần vô hình dùng để định vị chính xác vị trí của các đối tượng khác trên màn hình hiển thị, giúp tạo khoảng trắng rõ ràng theo chiều dọc và chiều ngang Bạn có thể dễ dàng thiết lập chiều dài và chiều rộng của Spacer để kiểm soát khoảng cách giữa các thành phần một cách chính xác Vì Spacer không có khả năng hiển thị nên nó không xử lý các sự kiện bấm hay tương tác nào, phù hợp để bố trí các thành phần mà không làm ảnh hưởng đến trải nghiệm người dùng.

Thành phần CustomItem cho phép bạn tạo ra các thành phần Item tùy chỉnh theo ý muốn, mang lại sự linh hoạt và sáng tạo cho giao diện của bạn These custom items đều có thể tích hợp vào các biểu mẫu (Form) như các Item tiêu chuẩn, giúp tăng tính tương tác và phù hợp với nhu cầu riêng của dự án Ngoài ra, các thành phần này còn có khả năng nhận biết và xử lý các sự kiện, đảm bảo chức năng hoạt động chính xác và mượt mà trên giao diện người dùng.

Thành phần List, Textbox, Alert, và Ticker

Trong phần này, chúng ta nghiên cứu các đối tượng chính của giao diện cấp cao trong ứng dụng MIDP như ListBox, TextBox, Alert và Ticker, nhằm hiểu rõ cách chúng hoạt động và tích hợp trong ứng dụng Ngoài ra, chúng ta cũng xem xét lại cấu trúc phân cấp các thành phần trình bày trên thiết bị để nắm bắt toàn diện về cách các thành phần giao diện được tổ chức và tối ưu hóa trong quá trình thiết kế ứng dụng.

Danh sách (List) trong Java ME thể hiện các lựa chọn theo ba dạng chính: chọn nhiều, chọn một và dạng không tường minh Các List không tường minh thường được dùng để hiển thị thực đơn các lựa chọn một cách linh hoạt và trực quan Ví dụ, đoạn mã dưới đây minh họa cách sử dụng danh sách không tường minh trong ứng dụng Java ME, giúp người dùng dễ dàng chọn lựa từ các tùy chọn khác nhau Việc sử dụng List trong Java ME giúp tối ưu hóa trải nghiệm người dùng, phù hợp cho các ứng dụng di động có hạn chế về giao diện và tài nguyên.

// Create the Commands cmExit = new Command("Exit", Command.EXIT, 1); try

Các thành phần giao diện ở mức cao

{ // Create array of image objects Image images[] = {Image.createImage("/next.png"), Image.createImage("/previous.png"), Image.createImage("/new.png")};

// Create array of corresponding string objects String options[] = {"Next", "Previous", "New"};

// Create list using arrays, add commands, listen for events lsDocument = new List("Document Option:", List.IMPLICIT, options, images);

// If you have no images, use this line to create the list // lsDocument = new List("Document Option:", List.IMPLICIT, options, null); lsDocument.addCommand(cmExit); lsDocument.setCommandListener(this);

System.err.println("Unable to locate or read png file");

} } public void startApp() { display.setCurrent(lsDocument);

} public void destroyApp(boolean unconditional) {

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

// If an implicit list generated the event if (c == List.SELECT_COMMAND) { switch (lsDocument.getSelectedIndex()) { case 0:

System.out.println("Next selected"); break; case 1:

System.out.println("Previous selected"); break; case 2:

System.out.println("New selected"); break;

} } else if (c == cmExit) { destroyApp(false); notifyDestroyed();

TextBox được sử dụng để cho phép nhập nhiều dòng, phù hợp cho các trường cần dữ liệu dài hoặc nhiều nội dung Các thành phần TextBox và TextField có những ràng buộc giống nhau trong việc xác định loại nội dung được phép nhập như ANY, EMAIL, URI, giúp kiểm soát chính xác dữ liệu nhập vào Dưới đây là phương thức dựng của một TextBox, cung cấp các cấu hình cần thiết để xây dựng một ô nhập liệu đa dòng phù hợp cho ứng dụng của bạn.

TextBox(String title, String text, int maxSize, int constraints)

This article provides an illustrative code example demonstrating how to use a TextBox in Java ME development The sample code shows the implementation of a MIDlet class named `TextBoxTest`, which incorporates essential UI components such as the `Display` object and a main `TextBox` It also includes a command object for exiting the application, highlighting key elements needed to create an interactive text input interface in mobile applications.

// Create the Commands Notice the priorities assigned cmExit = new Command("Exit", Command.EXIT, 1); tbClip = new TextBox("Textbox Test", "Contents go here ",125, TextField.ANY); tbClip.addCommand(cmExit); tbClip.setCommandListener(this);

} public void startApp() { display.setCurrent(tbClip);

Các thành phần giao diện ở mức cao

{ } public void destroyApp(boolean unconditional) {

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

Một Alert đơn giản là một hộp thoại rất nhỏ Có 2 loại Alert:

• Modal: là loại hộp thoại thông báo được trình bày cho đến khi người dùng ấn nút đồng ý

• Non-modal: là loại hộp thoại thông báo chỉ được trình bày trong một số giây nhất định Các phương thức dựng của Alert:

Alert(String title) Alert(String title, String alertText, Image alertImage, AlertType alertType)

AlertType là thành phần sử dụng âm thanh để thông báo cho người dùng về các sự kiện quan trọng Ví dụ, bạn có thể tích hợp AlertType để phát một đoạn âm thanh cảnh báo khi có lỗi xảy ra, giúp người dùng nhận biết nhanh chóng và phản ứng kịp thời Việc sử dụng âm thanh trong AlertType nâng cao trải nghiệm người dùng bằng cách truyền đạt thông báo một cách rõ ràng và trực quan.

Thành phần AlertType bao gồm 5 loại âm thanh định sẵn là: thông báo, xác nhận, báo lỗi, thông báo và cảnh báo

Ta thấy các phương thức dựng của Alert cho biết là Alert có thể bao gồm 1 tham chiếu đến một đối tượng AlertType

This article demonstrates how to use Alert and AlertType in Java ME applications, featuring code that showcases the implementation of alerts within a MIDlet The sample includes initializing display objects, creating a main form, and handling user commands such as exiting the application By integrating alerts and choice groups, the code provides an effective way to enhance user interaction and improve the overall functionality of Java ME mobile applications.

// Create an exclusive (radio) choice group cgSound = new ChoiceGroup("Choose a sound", Choice.EXCLUSIVE);

This article discusses appending sound options such as "Info," "Confirmation," "Warning," "Alarm," and "Error" without associated images, enhancing user notifications Additionally, it introduces a command labeled "Exit," designed to facilitate user exit actions within an application Incorporating these sound options and commands improves user experience by providing clear, context-specific auditory feedback and intuitive navigation controls.

// Create Form, add components, listen for events fmMain = new Form(""); fmMain.append(cgSound); fmMain.addCommand(cmExit); fmMain.setCommandListener(this); fmMain.setItemStateListener(this);

} public void startApp() { display.setCurrent(fmMain);

} public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == cmExit)

} } public void itemStateChanged(Item item) {

Alert al = null; switch (cgSound.getSelectedIndex()) { case 0: al = new Alert("Alert sound", "Info sound", null, AlertType.INFO); break;

The user interface components operate at a higher level by creating different alert sounds based on specific cases For example, case 1 initializes an alert with a "Confirmation sound," while case 2 uses a "Warning sound." Case 3 features an "Alarm sound," and case 4 employs an "Error sound," all of which enhance user notifications and improve user experience These alert components are configured using the Alert class with parameters for sound type, message, and alert severity, ensuring effective communication within the application.

// Wait for user to acknowledge the alert al.setTimeout(Alert.FOREVER);

// Display alert, show main form when done display.setCurrent(al, fmMain);

Thành phần Ticker đuợc dùng để thể hiện một đoạn chuỗi chạy theo chiều ngang

Thành phần Ticker có duy nhất một tham số là đoạn văn bản hiển thị, giúp truyền đạt thông tin một cách rõ ràng và hấp dẫn Tốc độ và chiều cuốn của Ticker được tùy chỉnh dựa trên cài đặt của từng thiết bị, mang lại trải nghiệm mượt mà và phù hợp cho người dùng mọi nền tảng Việc hiểu rõ cách cấu hình Ticker là chìa khóa để tối ưu hóa hiệu quả truyền thông và nâng cao sự tương tác của người xem.

Phương thức dựng của Ticker

Trong cấu trúc phân cấp các thành phần trên thiết bị, Ticker không phải là lớp con của lớp Screen mà thay vào đó, Ticker được xem như một biến của lớp Screen Điều này có nghĩa là bạn có thể gắn Ticker vào bất kỳ lớp con nào của lớp Screen, mang lại tính linh hoạt trong việc tùy biến giao diện người dùng.

Dưới đây là đoạn mã minh họa việc sử dụng một Ticker import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class TickerTest extends MIDlet implements CommandListener

This article showcases a Java MIDlet application featuring a user interface with engaging elements The application initializes key components such as a Display object, a List of products, a Ticker to highlight sale promotions, and an Exit command for user navigation The List displays product options like a Wicker Chair and a Coffee Table, enhancing user interaction through implicit choice handling Meanwhile, the Ticker prominently advertises ongoing sales, such as "Real Imitation Cuban Cigars 10 for $10," effectively capturing user attention Overall, the code exemplifies how to create an interactive mobile app interface with dynamic notifications and straightforward navigation, optimized for mobile environments.

} public void startApp() { display.setCurrent(lsProducts);

} public void destroyApp(boolean unconditional) {

} public void commandAction(Command c, Displayable s) { if (c == List.SELECT_COMMAND) { switch (lsProducts.getSelectedIndex()) { case 0:

System.out.println("Chair selected"); break; case 1:

System.out.println("Table selected"); break;

Các thành phần giao diện ở mức cao else if (c == cmExit) { destroyApp(true); notifyDestroyed();

Các thành phần giao diện ở mức thấp của ứng dụng MIDP

Các hàm API ở mức thấp

Các hàm API cấp cao cung cấp đầy đủ thành phần để xây dựng giao diện người dùng, nhưng lại thiếu phương tiện để vẽ trực tiếp lên thiết bị thể hiện, gây hạn chế cho các ứng dụng Ví dụ, hầu hết các nhà phát triển game di động cần khả năng vẽ các đường thẳng và hình dạng để tích hợp vào quá trình phát triển, do đó, thiếu khả năng này làm giới hạn đáng kể khả năng sáng tạo và chức năng của các ứng dụng.

Các hàm API cấp cao giúp tạo ra giao diện cho các ứng dụng theo chuẩn, đảm bảo tính nhất quán và dễ sử dụng Trong khi đó, các hàm API cấp thấp cho phép thể hiện các ý tưởng sáng tạo của người phát triển một cách linh hoạt hơn Sự kết hợp giữa hai loại API này là chìa khóa để xây dựng các ứng dụng mạnh mẽ, chất lượng và phù hợp với tiêu chuẩn.

Canvas và Graphics là hai lớp quan trọng trong các hàm API cấp thấp, đóng vai trò cốt lõi trong việc vẽ và xử lý đồ họa Canvas hoạt động như một khung vẽ, cho phép lập trình viên có khả năng tùy chỉnh vẽ lên thiết bị trình bày và xử lý các sự kiện liên quan đến đồ họa Trong khi đó, lớp Graphics cung cấp các công cụ vẽ cơ bản như drawRoundRect() và drawString(), giúp tạo ra các thành phần trực quan phong phú và đa dạng hơn cho ứng dụng của bạn.

Lớp Canvas

Lớp Canvas cung cấp một khung vẽ cho phép tạo ra giao diện tùy biến người dùng

Lớp này cung cấp nhiều phương thức để xử lý sự kiện, vẽ ảnh và hiển thị chuỗi trên thiết bị hiển thị Các chức năng chính gồm xử lý sự kiện, quản lý vẽ ảnh, và hiển thị chuỗi giúp tối ưu hóa quá trình xử lý hình ảnh và giao diện người dùng Các phương thức này đóng vai trò quan trọng trong việc làm cho ứng dụng tương tác hiệu quả và mượt mà hơn.

• Vẽ lên trên đối tượng Canvas

• Xử lý các sự kiện hành động

• Xử lý các sự kiện phím nhấn

• Xử lý sự kiện hành động của Game

Chúng ta sẽ phát triển hai ứng dụng MIDlet để minh họa khả năng của lớp Canvas trong xử lý sự kiện con trỏ Ứng dụng KeyMapping giúp chụp, nhận diện và xử lý mã phím nhấn cùng các sự kiện liên quan đến game, giúp người dùng hiểu rõ cách xử lý sự kiện bàn phím trong ứng dụng Java ME Trong khi đó, ứng dụng ScratchPad thể hiện cách thao tác các sự kiện con trỏ để tạo ra một chương trình vẽ đường thẳng đơn giản, góp phần làm rõ hệ thống trục tọa độ và cách xử lý sự kiện con trỏ trong lập trình di động.

Mục tiêu đầu tiên của chúng ta là làm quen với hệ thống trục tọa độ để có thể làm việc hiệu quả với thiết bị trình bày Hệ thống tọa độ cho lớp Canvas có tâm tọa độ nằm ở điểm trên bên trái của thiết bị hiển thị, giúp dễ dàng xác định vị trí các đối tượng Trong hệ thống này, giá trị của x tăng dần từ trái sang phải, còn giá trị của y tăng dần từ trên xuống dưới, đảm bảo tính trực quan trong quá trình vẽ Độ dày của bút vẽ được thiết lập bằng một điểm ảnh, giúp tạo ra các đường nét chính xác và rõ ràng trên màn hình.

Các thành phần giao diện ở mức thấp

Các phương thức sau đây sẽ giúp xác định chiều rộng và chiều cao của canvas:

• int getWidth(): xác định chiều rộng của canvas

Phương thức `int getHeight()` giúp xác định chiều cao của canvas, phản ánh toàn bộ diện tích khung vẽ trên thiết bị trình bày Chiều rộng và chiều cao của canvas đại diện cho diện tích khả dụng để vẽ trên thiết bị, và phần mềm trên thiết bị MIDP sẽ trả về kích thước lớn nhất có thể phù hợp với thiết bị đó Để bắt đầu, bạn cần tạo một đối tượng Canvas để tiến hành các thao tác vẽ và hiển thị nội dung.

Bước đầu tiên để làm việc với một lớp Canvas là tạo ra một lớp thừa kế từ lớp

Canvas class TestCanvas extends Canvas implements CommandListener { private Command cmdExit;

display = Display.getDisplay(this); cmdExit = new Command("Exit", Command.EXIT, 1); addCommand(cmdExit); setCommandListener(this);

} } TestCanvas canvas = new TestCanvas(this); c) Vẽ trên đối tượng Canvas

Phương thức paint của lớp Canvas cho phép bạn vẽ các hình dạng, hình ảnh và xuất chuỗi một cách linh hoạt Đoạn mã ví dụ bên dưới minh họa cách xóa màn hình bằng cách sử dụng màu trắng trong phương thức paint Việc này giúp đảm bảo màn hình luôn sạch sẽ trước khi vẽ các nội dung mới, nâng cao hiệu quả và chất lượng hiển thị trên giao diện đồ họa của bạn.

// Set background color to white g.setColor(255, 255, 255);

// Fill the entire canvas g.fillRect(0, 0, getWidth(), getHeight());

Trong quá trình vẽ đồ họa trong Java, chúng ta có thể sử dụng một tham chiếu đến đối tượng Graphics bên trong phương thức paint() để thực hiện công việc vẽ chính xác Việc này giúp đảm bảo các yếu tố đồ họa hiển thị được chính xác trên giao diện người dùng Đồng thời, các sự kiện hành động (Action Events) đóng vai trò quan trọng trong xử lý tương tác của người dùng, giúp chương trình phản hồi linh hoạt và hiệu quả.

Like other components such as Form, List, and TextBox, a Canvas can also handle Commands You can process Command events on a Canvas just as you do with other components The following code example demonstrates how to handle Command events on a Canvas component: class TestCanvas extends Canvas implements CommandListener.

display = Display.getDisplay(this); cmdExit = new Command("Exit", Command.EXIT, 1); addCommand(cmdExit); setCommandListener(this);

} public void commandAction(Command c, Displayable d) { if (c == cmdExit)

Các thành phần giao diện ở mức thấp e) Mã phím

Trong quá trình xử lý các hành động từ các phím mềm, Canvas có khả năng truy cập đến 12 mã phím, đảm bảo tính tương thích cao trên mọi thiết bị MIDP Các mã phím này luôn luôn có sẵn trên tất cả các thiết bị hỗ trợ MIDP, đảm bảo bạn có thể kiểm soát dễ dàng các tương tác người dùng qua các phím mềm một cách hiệu quả và nhất quán.

The article details five methods for handling key inputs: `void keyPressed(int keyCode)`, `void keyReleased(int keyCode)`, `void keyRepeated(int keyCode)`, `boolean hasRepeatEvents()`, and `String getKeyName(int keyCode)` These functions enable effective processing of keypad interactions such as numeric keys (`KEY_NUM0` to `KEY_NUM9`), special keys (`KEY_STAR`, `KEY_POUND`), and their corresponding actions in game development Proper utilization of these methods is essential for implementing responsive and intuitive controls in gaming applications, ensuring seamless user experience during gameplay.

MIDP thường được sử dụng để phát triển các trò chơi trên nền Java, giúp tối ưu hóa khả năng tương tác và hiệu suất của game Các hằng số đã được định nghĩa để xử lý các sự kiện liên quan đến trò chơi trong MIDP, đảm bảo các phản hồi nhanh chóng và chính xác trong quá trình chơi Việc sử dụng các hằng số này không những nâng cao trải nghiệm người dùng mà còn giúp lập trình viên dễ dàng quản lý và xử lý các tình huống trong game một cách hiệu quả.

Các giá trị như UP, DOWN, LEFT, RIGHT, FIRE, GAME_A, GAME_B, GAME_C, GAME_D đều được ánh xạ thành các phím mũi tên hoặc các nút bấm tương ứng trên thiết bị di động để điều khiển trò chơi Tuy nhiên, không phải tất cả các thiết bị di động đều có sẵn các phím mũi tên, do đó các hành động trong trò chơi sẽ được ánh xạ vào các nút bấm khác nhau, ví dụ như phím trái có thể được ánh xạ vào phím số 2, phím phải vào phím số 5, và như vậy Một hình minh họa cho thấy các hành động của trò chơi sẽ dựa trên khả năng của các phím chỉ hướng trên thiết bị di động Để xác định các hành động của trò chơi và gọi các phương thức phù hợp, đoạn mã sau sử dụng phương thức keyPressed với tham số keyCode, trong đó switch-case sẽ xử lý các hành động như bắn súng hoặc di chuyển sang phải dựa trên kết quả của getGameAction(keyCode).

} } Một lựa chọn nữa là có thể tạo một tham chiếu cho mỗi hành động của trò chơi thông qua quá trình khởi tạo giá trị cho các biến

// Initialization keyFire = getKeyCode(FIRE); keyRight = getKeyCode(RIGHT); keyLeft = getKeyCode(LEFT);

Các thành phần giao diện ở mức thấp

// Runtime protected void keyPressed(int keyCode) { if (keyCode == keyFire) shoot(); else if (keyCode == keyRight) goRight()

This article demonstrates key functionalities of the Canvas class and how to handle key events in Java ME development It highlights the use of the display object for rendering and managing user interface components The example code showcases creating a custom canvas for capturing key presses, enabling developers to implement interactive applications efficiently By understanding these principles, programmers can enhance their mobile applications with responsive controls and improved user experience.

} protected void startApp() { display.setCurrent( canvas );

} protected void pauseApp() { } protected void destroyApp( boolean unconditional ) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed();

* -*/ class KeyCodeCanvas extends Canvas implements CommandListener { private Command cmExit; // Exit midlet private String keyText = null; // Key code text private KeyCodes midlet;

* Constructor * -*/ public KeyCodeCanvas(KeyCodes midlet) { this.midlet = midlet;

// Create exit command and listen for events cmExit = new Command("Exit", Command.EXIT, 1); addCommand(cmExit); setCommandListener(this);

* Paint the text representing the key code * -*/ protected void paint(Graphics g) {

// Clear the background (to white) g.setColor(255, 255, 255); g.fillRect(0, 0, getWidth(), getHeight());

// Set color and draw text if (keyText != null) {

// Draw with black pen g.setColor(0, 0, 0);

// Center text g.drawString(keyText, getWidth()/2, getHeight()/2, Graphics.TOP | Graphics.HCENTER);

* Command event handling * -*/ public void commandAction(Command c, Displayable d) { if (c == cmExit) midlet.exitMIDlet();

* Key code event handling * -*/ protected void keyPressed(int keyCode) { keyText = getKeyName(keyCode); repaint();

Các thành phần giao diện ở mức thấp

Trong phần này, chúng ta sẽ quản lý các sự kiện con trỏ trong một Canvas để tạo điều kiện thuận lợi cho việc tương tác với thiết bị có dạng con trỏ Các phương thức như hasPointerEvents(), hasPointerMotionEvents(), pointerPressed(int x, int y), pointerReleased(int x, int y), và pointerDragged(int x, int y) hỗ trợ xử lý sự kiện con trỏ một cách hiệu quả, với chức năng được thể hiện rõ qua tên gọi của từng phương thức Phương thức hasPointerMotionEvents() trả về giá trị boolean, xác định xem thiết bị di động có hỗ trợ các sự kiện "nhấp và rê" hay không Ví dụ minh họa dưới đây trình bày cách sử dụng các sự kiện con trỏ để thực hiện một chương trình vẽ đơn giản trên Canvas.

} protected void startApp() { display.setCurrent( canvas );

} protected void pauseApp() { } protected void destroyApp( boolean unconditional ) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed();

ScratchPadCanvas, a class that extends Canvas and implements CommandListener, provides essential features for a digital scratchpad application It includes commands for exiting the midlet (`cmExit`) and clearing the display (`cmClear`), enabling user control and interface management The class maintains coordinate variables (`startx`, `starty`, `currentx`, `currenty`) to track where the user interacts with the canvas, ensuring accurate drawing or editing actions A reference to the parent midlet (`ScratchPad`) allows seamless integration within the application With a `clearDisplay` boolean flag set to true, the class ensures the screen can be efficiently cleared, optimizing the user experience in a mobile environment.

* Constructor * -*/ public ScratchPadCanvas(ScratchPad midlet) { this.midlet = midlet;

// Create exit command and listen for events cmExit = new Command("Exit", Command.EXIT, 1); cmClear = new Command("Clear", Command.SCREEN, 1); addCommand(cmExit); addCommand(cmClear); setCommandListener(this);

* Draw line based on start and ending points * -*/ protected void paint(Graphics g) {

// Clear the background (to white) if (clearDisplay) { g.setColor(255, 255, 255); g.fillRect(0, 0, getWidth(), getHeight()); clearDisplay = false; startx = currentx = starty = currenty = 0; return;

} // Draw with black pen g.setColor(0, 0, 0);

Các thành phần giao diện ở mức thấp

// Draw line g.drawLine(startx, starty, currentx, currenty);

// New starting point is the current position startx = currentx; starty = currenty;

* Command event handling * -*/ public void commandAction(Command c, Displayable d) { if (c == cmExit) midlet.exitMIDlet(); else if (c == cmClear) { clearDisplay = true; repaint();

* Pointer pressed * -*/ protected void pointerPressed(int x, int y) { startx = x; starty = y;

* Pointer moved * -*/ protected void pointerDragged(int x, int y) { currentx = x; currenty = y; repaint();

Lớp Graphics

Chúng ta sử dụng đối tượng Graphics để vẽ lên một Canvas a) Hỗ trợ màu

Ứng dụng MIDP có duy nhất một đối tượng Display, dùng để truy xuất thông tin về màn hình hiển thị hiện tại, như số màu hỗ trợ và các phương thức yêu cầu hiển thị đối tượng Đối tượng này quản lý việc hiển thị của thiết bị và điều khiển nội dung sẽ được hiển thị ra ngoài Phương thức isColor() giúp xác định thiết bị có hỗ trợ hiển thị màu hay không, trong khi đó, numColors() cung cấp số lượng màu được hỗ trợ nếu có Các phương thức như setColor() và getColor() cho phép thiết lập và truy xuất màu sắc, còn các phương thức getRedComponent(), getGreenComponent(), và getBlueComponent() giúp lấy giá trị màu cụ thể Ngoài ra, setGrayScale() và getGrayScale() cho phép điều chỉnh và lấy thông tin về chế độ màu xám của màn hình.

Bạn có thể xác định màu sắc bằng hai phương pháp chính Phương pháp đầu tiên là sử dụng một số nguyên đại diện cho ba giá trị của màu đỏ, xanh lá cây và xanh dương, mỗi màu sử dụng 8 bit để biểu thị Phương pháp thứ hai là xác định từng thành phần màu riêng biệt, giúp bạn kiểm soát chính xác hơn các giá trị màu theo từng phần.

Trong quá trình lưu giữ màu sắc, giá trị màu được chia thành các phần cụ thể theo thứ tự rõ ràng Màu đỏ chiếm 8 bit đầu tiên từ bên trái, phản ánh mức độ của màu đỏ trong màu tổng thể Tiếp theo, 8 bit dành riêng cho màu xanh lá cây, cho phép điều chỉnh độ sáng của sắc thái này Cuối cùng, 8 bit còn lại chứa thông tin về màu xanh dương, giúp tạo nên màu sắc chính xác và sống động trong hình ảnh kỹ thuật số.

Dưới đây sẽ hướng dẫn bạn cách thiết lập màu chỉ sử dụng một số nguyên: int red = 0, green = 128, blue = 255;

Và bạn có thể xác định màu bằng cách thiết lập giá trị cho 3 tham số: g.setColor(red, green, blue); b) Loại nét vẽ

Bạn có thể chọn nét khi vẽ đường thẳng, cung và hình chữ nhật trên thiết bị hiển thị bằng các phương thức như setStrokeStyle(int style), giúp bạn tùy chỉnh loại nét vẽ phù hợp Trong lớp Graphics, có hai kiểu nét vẽ chính được định nghĩa là nét chấm (Graphics.DOTTED) và nét liền (Graphics.SOLID), cho phép bạn dễ dàng thao tác với các loại đường nét khác nhau Để vẽ cung, bạn cũng có thể sử dụng phương thức này để thiết lập kiểu nét trước khi vẽ, đảm bảo hình dạng hiển thị chính xác theo ý muốn.

Khi vẽ một cung, bạn có thể chọn vẽ chỉ đường viền hoặc tô màu bên trong để tạo hiệu ứng phù hợp Bắt đầu bằng cách xác định chiều bao quanh bên ngoài của hình hộp chữ nhật tưởng tượng, giúp dễ dàng hình dung và định vị các điểm vẽ Góc bắt đầu đóng vai trò quan trọng trong việc xác định vị trí bắt đầu vẽ khung, trong đó giá trị 0 được đặt tại thời điểm 3 giờ theo hệ thống đo góc Giá trị góc dương được tính theo chiều ngược lại, giúp kiểm soát chính xác hướng vẽ và tạo ra các cung hình học chính xác theo yêu cầu.

Các thành phần giao diện ở mức thấp theo chiều kim đồng hồ thể hiện vị trí và góc của cung Góc của cung chỉ ra số độ được vẽ tính từ góc ban đầu, đi theo hướng ngược chiều kim đồng hồ Ví dụ minh họa: đoạn mã `g.drawArc(10, 10, 100, 100, 0, 150);` yêu cầu vẽ một cung nằm trong hình chữ nhật có tọa độ điểm trái trên là (10, 10) với chiều dài và chiều rộng lần lượt là 100, bắt đầu từ góc 0 độ và kết thúc tại 150 độ.

There are several methods used to draw arc segments in Java ME, such as `drawArc()` and `fillArc()`, which allow developers to create both outline and filled arc shapes The `drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)` method is used to render an outlined arc, while `fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)` is used to draw a filled arc segment An example implementation demonstrates how these functions can be used to draw an arc, utilizing Java ME classes like `MIDlet`, `Display`, and custom `Canvas` This approach highlights how to effectively use `drawArc()` and `fillArc()` methods within a MIDlet to create various arc-based graphics in mobile applications.

} protected void startApp() { display.setCurrent( canvas );

{ } protected void destroyApp( boolean unconditional ) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed();

* -*/ class ShapesCanvas extends Canvas implements CommandListener { private Command cmExit; // Exit midlet private DrawShapes midlet; public ShapesCanvas(DrawShapes midlet) { this.midlet = midlet;

// Create exit command and listen for events cmExit = new Command("Exit", Command.EXIT, 1); addCommand(cmExit); setCommandListener(this);

* Draw shapes * -*/ protected void paint(Graphics g) {

// Clear background to white g.setColor(255, 255, 255); g.fillRect(0, 0, getWidth(), getHeight());

// Start at 3 o'clock and rotate 150 degrees g.drawArc(10, 10, 100, 100, 0, 150);

// Start at 12 o'clock and rotate 150 degrees

Các thành phần giao diện ở mức thấp

// Change the size of the bounding box // Start at 12 o'clock and rotate 150 degrees // g.drawArc(15, 45, 30, 70, 90, 150);

} public void commandAction(Command c, Displayable d) { if (c == cmExit) midlet.exitMIDlet();

Hình chữ nhật trong lập trình có thể được vẽ với viền bao quanh hoặc tô màu bên trong, và có thể có 4 góc vuông hoặc tròn, phù hợp với nhiều nhu cầu thiết kế đồ họa Các phương thức phổ biến để vẽ hình chữ nhật bao gồm drawRect để vẽ hình rỗng, fillRect để tô màu bên trong, cũng như các phiên bản bo góc như drawRoundRect và fillRoundRect giúp tạo các hình chữ nhật với góc tròn Đặc biệt, khi vẽ hình chữ nhật có góc tròn, cần xác định các tham số arcWidth và arcHeight để điều chỉnh độ sắc nét của các cung tròn, trong đó giá trị lớn hơn thể hiện cung tròn rõ nét hơn Việc lựa chọn kiểu hình chữ nhật phù hợp giúp nâng cao tính thẩm mỹ và tối ưu trải nghiệm người dùng trong các dự án thiết kế đồ họa.

Phần quan trọng tiếp theo là cách sử dụng font chữ được hỗ trợ bởi giao diện cấp thấp của ứng dụng MIDP, giúp tối ưu hóa trải nghiệm người dùng Các phương thức dựng của lớp Font cung cấp các công cụ cần thiết để tùy biến và sử dụng font chữ một cách linh hoạt trong ứng dụng di động Việc hiểu rõ các phương thức này giúp phát triển ứng dụng hiệu quả, nâng cao tính thẩm mỹ và khả năng hiển thị của nội dung Đây là kiến thức quan trọng để tối ưu hóa khả năng hiển thị và trải nghiệm người dùng trên nền tảng MIDP.

Font getFont(int face, int style, int size) Font getFont(int fontSpecifier)

Font getDefaultFont() Một số thuộc tính của lớp Font FACE_SYSTEM

STYLE_PLAIN STYLE_BOLD STYLE_ITALIC STYLE_UNDERLINED

SIZE_SMALL SIZE_MEDIUM SIZE_LARGECác tham số kiểu dáng có thể được kết hợp thông qua toán tử hay Ví dụ

Font font = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD | Font.STYLE_ITALIC, Font.SIZE_MEDIUM);

Khi bạn có một tham chiếu đến đối tượng Font, có thể truy vấn các thuộc tính của nó như mặt chữ, kiểu dáng, kích thước, và các đặc tính định dạng như in đậm, in nghiêng hoặc gạch chân bằng các phương thức như getFace(), getStyle(), getSize(), isPlain(), isBold(), isItalic(), và isUnderlined() Kích thước của font chữ được xác định dựa trên chiều cao của font và chiều rộng của một chuỗi ký tự trong font đó tính bằng điểm ảnh Các phương thức hỗ trợ tương tác với đối tượng Font bao gồm getHeight(), getBaselinePosition(), charWidth(), charsWidth(), stringWidth(), và substringWidth(), giúp đo lường kích thước và vị trí của ký tự hay chuỗi ký tự Điểm neo (anchor point) cho phép bạn xác định tọa độ x, y của chuỗi ký tự được hiển thị, giúp định vị chính xác vị trí đặt chuỗi trong hình chữ nhật bao quanh nó.

Có 6 điểm neo được định nghĩa trước, 3 theo chiều dọc và 3 theo chiều thẳng đứng, Khi xác định điểm neo để vẽ chuỗi (các điểm neo thường được sử dụng thành từng cặp), bạn phải chọn một điểm hoành độ và một điểm tung độ Các điểm neo được định nghĩa như ở dưới đây

LEFT (Bên trái) HCENTER (Chính giữa của chiều ngang) RIGHT (Bên phải)

TOP (Ở trên) BASELINE (Đường thẳng cơ sở) BOTTOM (Ở dưới)

Các thành phần giao diện ở mức thấp

Khi sử dụng điểm neo thì bạn cần phải chỉ ra tọa độ x, y của hình chữ nhật bao quanh Ví dụ g.drawString("developerWorks", 0, 0 , Graphics.TOP | Graphics.LEFT);

Hình dưới đây mô tả kết quả của hàm trên

Bằng cách thay đổi điểm neo, chúng ta có thể điều chỉnh vị trí hiển thị của chuỗi ký tự trên thiết bị di động, giúp tối ưu hóa trải nghiệm người dùng Ví dụ minh họa cho thấy khi thay đổi điểm neo, vị trí của chuỗi ký tự cũng sẽ thay đổi theo, như hình dạng đoạn mã: g.drawString("developerWorks", 0, 0 , Graphics.TOP | Graphics.HCENTER); thể hiện cách vẽ chuỗi ký tự với các tùy chọn căn chỉnh khác nhau Việc kiểm soát điểm neo giúp dễ dàng tùy chỉnh vị trí của các chuỗi ký tự trong quá trình thiết kế ứng dụng di động.

After understanding fonts and anchor points, you can render character strings on the screen using several methods: void drawChar(char character, int x, int y, int anchor), void drawChars(char[] data, int offset, int length, int x, int y, int anchor), void drawString(String str, int x, int y, int anchor), and void drawSubstring(String str, int offset, int len, int x, int y, int anchor) These functions allow precise control over text placement and display in your application.

Ví dụ: protected void paint(Graphics g) {

// Get center of display int xcenter = getWidth() / 2, ycenter = getHeight() / 2;

// Choose a font g.setFont(Font.getFont(Font.FACE_SYSTEM, Font.STYLE_ITALICS, Font.SIZE_MEDIUM));

// Specify the center of the text (bounding box) using the anchor point g.drawString("developerWorks", xcenter, ycenter, Graphics.BASELINE | Graphics.HCENTER);

This article demonstrates how to use fonts and display text on devices by illustrating a Java MIDlet example It highlights key components such as creating a display, form for font preferences, and a canvas to render text in the selected font The sample code initializes the display, font preferences form, and canvas to effectively showcase font customization and text rendering on mobile devices.

} protected void showCanvas() { display.setCurrent(cvFont);

} protected void pauseApp() { } protected void destroyApp( boolean unconditional ) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed();

Các thành phần giao diện ở mức thấp

* Draw text using specified Font

The provided code snippet showcases the implementation of a FontCanvas class in Java, which extends Canvas and implements CommandListener for user interactions This class manages font properties such as face, style, and size, and displays the text "developerWorks" using the preferred font settings It also includes commands like cmExit for exiting the application and cmPrefs for accessing preferences, with a reference to the main FontViewer midlet to facilitate communication within the application.

// Create commands and listen for events cmExit = new Command("Exit", Command.EXIT, 1); cmPrefs = new Command("Prefs", Command.SCREEN, 2); addCommand(cmExit); addCommand(cmPrefs); setCommandListener(this);

* Draw text * -*/ protected void paint(Graphics g) {

// Clear the display g.setColor(255, 255, 255); // White pen g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(0, 0, 0); // Black pen

// Use the user selected font preferences g.setFont(Font.getFont(face, style, size));

// Draw text at center of display g.drawString(text, getWidth() / 2, getHeight() / 2, Graphics.BASELINE | Graphics.HCENTER);

} protected void setFace(int face) { this.face = face;

} protected void setStyle(int style)

} protected void setSize(int size) { this.size = size;

} public void setText(String text) { this.text = text;

} public int getFace() { return face;

} public int getStyle() { return style;

} public int getSize() { return size;

} public void commandAction(Command c, Displayable d) { if (c == cmExit) midlet.exitMIDlet(); else if (c == cmPrefs) midlet.display.setCurrent(midlet.fmPrefs);

* Form that allows user to select font preferences

* -*/ import javax.microedition.lcdui.*; public class PrefsForm extends Form implements CommandListener, ItemStateListener

{ private FontViewer midlet; // Main midlet private Command cmBack, // Back to canvas cmSave; // Save new font prefs

Các hàm API dùng để lập trình Game

Các hàm API dành để lập trình game trong MIDP 2.0 là những công cụ quan trọng giúp phát triển các trò chơi có phần đồ họa phong phú và đa dạng Những hàm này thuộc gói javax.microedition.lcdui.game, cung cấp các phương tiện cần thiết để xây dựng các trò chơi chạy trên môi trường Java ME Việc sử dụng API Game trong MIDP 2.0 giúp nhà phát triển dễ dàng tạo ra các ứng dụng game có hiệu ứng đồ họa mượt mà và trải nghiệm người dùng hấp dẫn.

GameCanvas là một lớp gần giống với lớp Canvas nhưng chuyên dùng để phát triển các trò chơi, cung cấp nền tảng để tạo giao diện người dùng trong lĩnh vực game development Nó có vùng nhớ riêng biệt, tách biệt với vùng nhớ màn hình cho mỗi thể hiện, giúp quản lý trạng thái trò chơi hiệu quả hơn GameCanvas còn tích hợp các phương tiện để xác định trạng thái các phím trò chơi, tối ưu hóa trải nghiệm người dùng trong các ứng dụng game Đây là lớp trừu tượng mở rộng từ lớp Canvas, định nghĩa các phương thức cần thiết để xây dựng các trò chơi đa dạng và chuyên sâu hơn.

Layer là một lớp trừu tượng dùng để thể hiện các đối tượng trực quan trong trò chơi, giúp tổ chức và quản lý các thành phần đồ họa một cách rõ ràng Sprite là lớp con của Layer, chuyên dùng để hiển thị các hình ảnh, bao gồm cả các dãy khung ảnh để tạo hiệu ứng chuyển động mượt mà Việc sắp xếp các khung ảnh theo thứ tự giúp tạo ra hiệu ứng chuyển động của nhân vật hoặc đối tượng trong game Ngoài ra, các phép biến đổi như quay và lật ảnh có thể áp dụng lên đối tượng Sprite để tạo hiệu ứng đa dạng và sinh động hơn trong trò chơi Cấu trúc của hai lớp này bao gồm: public abstract class Layer và public class Sprite extends Layer, giúp xây dựng các thành phần trực quan linh hoạt và dễ mở rộng.

TiledLayer là một lớp giống như bảng tính, trong đó mỗi ô đại diện cho một tấm ảnh, thường được sử dụng để hiển thị các phần tử trực quan lớn như nền trong trò chơi Để đơn giản hóa việc vẽ nhiều lớp trong trò chơi, API cung cấp lớp LayoutManager, chứa danh sách các đối tượng Layers theo thứ tự và xác định khu vực cần vẽ lại, giúp quản lý việc thể hiện các lớp một cách hiệu quả Lớp LayerManager, mở rộng từ Object, đóng vai trò quan trọng trong việc điều phối và xử lý các lớp trong quá trình lập trình trò chơi, đảm bảo các yếu tố được thể hiện đúng trật tự và đúng khu vực.

Xử lý sự kiện

Record Management System

The Generic Connection Framework

Ngày đăng: 01/11/2022, 15:41

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w