Java Course - 國立交通大學資訊工程學系NCTU Department of

Download Report

Transcript Java Course - 國立交通大學資訊工程學系NCTU Department of

Programming in Java
J2ME
汪益賢 蔡文能
交通大學資訊工程學系
http://www.csie.nctu.edu.tw/~tsaiwn/java/
交通大學資訊工程系蔡文能
第1頁
Java
J2ME
Outline
Java ME
Java ME Architecture
Java ME Specification
Learning J2ME
 CLDC 1.0 / MIDP 2.0
 APIs
User Interface (lcdui)
Input/Output (RMS)
Networking
練習:Calculator or Monty Hall (手機版)
交通大學資訊工程系
9-第2頁
Java
J2ME
Java ME (formerly J2ME)
Java Platform, Micro Edition
 Provides a robust, flexible environment for applications running on
a broad range of other embedded devices
Mobile phones
PDAs
TV set-top boxes
Printers
Applications based on Java ME specifications are written
once for a wide range of devices, yet exploit each device’s
native capabilities.
 Java Mobile Games
交通大學資訊工程系
9-第3頁
Java
J2ME
Java ME Games
The most popular application
 Java-enabled devices grow rapidly.
 Java mobile games almost become the name of Java mobile
applications.
Nokia Snake
交通大學資訊工程系
ThinkNewIdea MJ16
JoyPark-Rich
9-第4頁
Java
交通大學資訊工程系
J2ME
9-第5頁
Java
J2ME
3D Mobile Java Game
交通大學資訊工程系
9-第6頁
Java
J2ME
Pac-Manhattan
http://www.pacmanhattan.com/
交通大學資訊工程系
9-第7頁
Java
J2ME
Java ME Architecture
VMs
Configurations
Profiles
Optional Packages
交通大學資訊工程系
9-第8頁
Java
J2ME
Java Platform Editions
交通大學資訊工程系
9-第9頁
Java
J2ME
J2ME Architecture

Source: http://www.j2mer.idv.tw
多層次的架構 (一堆很容易搞混的名詞)
基本上,把 Profile, Configuration 都當作是 Package 來思考
交通大學資訊工程系
9-第10頁
Java
J2ME
VMs for Java ME
KVM (K Virtual Machine) for CLDC
 16-bit or 32-bit processor with a clock speed of 16MHz or higher
 At least 160KB memory (128KB for VM and the CLDC library +
32KB for runtime heap space)
 Low power consumption (battery)
 Wireless with limited bandwidth
JVM (Java Virtual Machine) for CDC





32-bit processor
More than 512KB memory + 128KB runtime heap space
Unlimited power supply
Fast network
Target devices: smartphones, TV set-top boxes, and so on.
交通大學資訊工程系
9-第11頁
Java
J2ME
Configurations
Specifies the Java programming language features
supported.
Specifies the Java virtual machine features supported.
Specifies the basic Java libraries and APIs supported.
Two configurations are defined:
 CLDC (Connected, Limited Device Configuration)
 CDC (Connected Device Configuration)
交通大學資訊工程系
9-第12頁
Java
J2ME
Profiles
Provide specific APIs for a certain device type.
 CLDC
MID Profile (Mobile Information Device Profile)
 Screen resolution: 96x54. Memory: 256KB for MIDP components,
128KB runtime space, 8KB persistent space.
PDA Profile
 Screen resolution: 160x160.
 CDC
Foundation Profile
 No GUI
Personal Basis Profile
 Lightweight component
Personal Profile
 Full AWT and Applet (No Swing and Java 2D)
交通大學資訊工程系
9-第13頁
Java
J2ME
Optional Packages
A set of technology-specific APIs that extends the
functionality of a Java application environment.
 Ex:
Wireless Messaging API (WMA)
 For CLDC 1.0 / MIDP 2.0
 Provides access to wireless communication resources like Short Message
Service (SMS).
Mobile Media API (MMAPI)
 For CLDC 1.0 / MIDP 1.0
 Provides audio, video and other time-based multimedia support.
JDBC
 For CDC / FP 1.0
交通大學資訊工程系
9-第14頁
Java
J2ME
Focused Specifications in This Course
The CLDC Specification
 Currently version 1.1 (JSR 139)
 No Floating point in version 1.0 (CLDC 1.0 不支援實數)
The MIDP Specification
 Currently version 2.0 (JSR 118)
Note that JSR (Java Specification Request) is the actual
description of proposed and final specifications for a new
Java API that is submitted to the JCP (Java Community
Process). (註: JSR 類似 RFC)
交通大學資訊工程系
9-第15頁
Java
J2ME
Relationship between CDC/CLDC and J2SE
J2SE
交通大學資訊工程系
CDC
CLDC
9-第16頁
Java
J2ME
The CLDC Specification
Java language and VM features
Security
 Classfile verification
Reduced APIs
 Core Java libraries (java.lang.*, java.util.*)
 IO
 Networking
交通大學資訊工程系
9-第17頁
Java
J2ME
Constraints on Java Language Specification
No floating point (float and double)
 But CLDC 1.1 support floating point
No finalization (Object.finalize())
Limited error handling
交通大學資訊工程系
9-第18頁
Java
J2ME
Constraints on KVM
No JNI
No user-defined class loader
No reflection
No thread groups and daemon threads
No weak references
 java.lang.ref.WeakReference
交通大學資訊工程系
9-第19頁
Java
J2ME
Classfile Verification
交通大學資訊工程系
9-第20頁
Java
J2ME
Sun Java Wireless Toolkit for CLDC Buffer
Overflow Vulnerabilities
http://www.vupen.com/english/advisories/2008/3439
Two vulnerabilities have been identified in Sun Java Wireless Toolkit
(WTK) for CLDC (Connected Limited Device Configuration), which
could be exploited by local attackers to gain elevated privileges. These
issues are caused by unspecified buffer overflow errors which may
allow a malicious program downloaded and executed in the WTK to
execute arbitrary code with the privileges of the WTK process.
Affected: Sun Java Wireless Toolkit for CLDC version 2.5.2 and prior.
Solution: Upgrade to Sun Java Wireless Toolkit for CLDC version
2.5.2_01 :
http://java.sun.com/products/sjwtoolkit/
交通大學資訊工程系
9-第21頁
Java
J2ME
The MIDP Specification
Application Life-cycle Management
User Interface
Event Handling
Record Management System (RMS)
交通大學資訊工程系
9-第22頁
Java
J2ME
MID Profile
MIDP 1.0 Packages:




javax.microedition.lcdui.*
javax.microedition.rms.*
javax.microedition.midlet.*
javax.microedition.io.*
MIDP 2.0 Added Packages:




java.microedition.lcdui.game.*
javax.microedition.media.*
javax.microedition.media.control.*
javax.microedition.pki.*
MIDP 2.0 supports socket connection that is not available in 1.0.
交通大學資訊工程系
9-第23頁
Java
J2ME
Constraints on Libraries
Only majority of the class libraries are included.
 ex:
No java.io.BufferedReader/Writer,
java.io.FileReader/Writer/
InputStream/OutputStream
No java.awt.*
…
交通大學資訊工程系
9-第24頁
Java
J2ME
Hardware Consideration
The screen size is small.
Different mobile devices have different constraints.
 Different screen size.
 Different Input Method
No mouse
ITU keyboard (0~9, *, #, 上下左右, …)
Touch pad
 Different available memory
交通大學資訊工程系
9-第25頁
Java
J2ME
Learning Java ME (CLDC 1.0 / MIDP 2.0)
Development Environment
 Sun Java Wireless Toolkit (currently WTK 2.5.2)
http://java.sun.com/products/sjwtoolkit/
 The Wireless Toolkit has been integrated into Java ME SDK 3.0.
Deployment
Your First MIDP Program
 class HelloMidlet extends MIDlet
交通大學資訊工程系
9-第26頁
Java
J2ME
Sun Java Wireless Toolkit
A toolbox for developing wireless applications that are
based on CLDC and MIDP.
 Cell phones
 Mainstream personal digital assistants
 Other small mobile devices
The toolkit includes the




Emulation environments
Performance optimization and tuning features
Documentation
Examples
交通大學資訊工程系
9-第27頁
Java
J2ME
Deployment
There are two ways to deploy a MIDlet suite.
 Direct uses some direct connection between the device and the
development platform
commonly cable, infrared, or Bluetooth link
 Over-The-Air provisioning (OTA) uses the device’s built-in
browser to install a MIDlet suite from a remote server
交通大學資訊工程系
9-第28頁
Java
J2ME
JAD and JAR Files
The basic components of any MIDlet suite you will deliver
 Java Application Descriptor (JAD) file
the location and size of the JAR file
the configuration and profile requirements
attributes
 Java Archive (JAR) file
在 product deployment 主題中討論
交通大學資訊工程系
9-第29頁
Java
J2ME
Your First MIDP Program: Hello MIDP
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class HelloMidlet extends MIDlet implements CommandListener
{
private Form mainForm;
public HelloMidlet() //no-argument constructor
{
mainForm = new Form("HelloMIDlet");
mainForm.append(new StringItem(null, "Hello, MIDP!"));
mainForm.addCommand(new Command("Exit", Command.EXIT, 0));
mainForm.setCommandListener(this);
}
protected void startApp()
{
Display.getDisplay(this).setCurrent(mainForm);
}
protected void pauseApp() {}
protected void destroyApp(boolean b) {}
public void commandAction(Command c, Displayable s)
{
notifyDestroyed(); //destroy the MIDlet
}
}
交通大學資訊工程系
9-第30頁
Java
J2ME
The Life Cycle of A MIDlet
When a MIDlet begins execution, the
application management software (AMS) first
calls the zero-argument constructor to create a
new instance of the MIDlet. Then, the AMS
places the MIDlet in the Paused state.
startApp()
 shift the MIDlet to the Active state
 allocate resources, such as record stores, network
connections, and UI components.
pauseApp()
 The MIDlet is not being terminated, but it should
release some resources.
destroyApp(boolean b)
 The MIDlet is terminated. Release any resources
acquired.
交通大學資訊工程系
9-第31頁
Java
J2ME
Controlling the MIDlet State
notifyPaused() – enter the Paused state.
notifyDestroyed() – inform the AMS that the MIDlet can now
be considered Destroyed.
destroyApp(boolean b)
 If this boolean is true, the MIDlet will be in the Destroyed state when
destroyApp() returns.
 If this boolean is false, the MIDlet can request not to enter the Destroyed
state by throwing a MIDletStateChangeException.
交通大學資訊工程系
9-第32頁
Java
J2ME
Essential APIs
User Interface (lcdui)
 javax.microedition.lcdui
 High-Level API: Form, Alert/List/TextBox
 Low-Level API: Canvas/GameCanvas, Font/Graphics/Image
 Sound
Input/Output (RMS)
Networking
 HttpConnection
 StreamConnection
 SocketConnection
交通大學資訊工程系
9-第33頁
Java
J2ME
Essential APIs
1. User Interface
The GUI classes included in the MIDP are not based on AWT/Swing.
 The AWT is designed for desktop computers and optimized for these devices,
such as window management.
 The AWT assumes certain user interaction models, such as mouse.
The MIDP UI consists of two APIs.
 High-Level API
Portability
 Gives you little control over its look and feel
Implemented by subclasses of the Screen class
 Low-Level API
Control of graphic elements and input events
Implemented by the Canvas and Graphics classes
All the UI classes are placed in the javax.microedition.lcdui package.
交通大學資訊工程系
9-第34頁
Java
J2ME
javax.microedition.lcdui Package
交通大學資訊工程系
9-第35頁
Java
J2ME
The MIDP GUI Programming Model
The Display class is the display manager
 Instantiated for each active MIDlet
 Provides information about the device’s display capabilities.
Only one screen can be visible at a time, and the user can traverse only
through the items on that screen.
 A screen is made visible by calling the Display.setCurrent() method.
There are three types of screens:
 Screens that encapsulate a complex user interface component
Alert, List, or TextBox (High-level API)
 Generic screens
Form (High-level API)
 Screens used within the context of the low-level API
Canvas (Low-level API)
交通大學資訊工程系
9-第36頁
Java
J2ME
Example of High-Level API
GuiTest.java
 Screens that encapsulate a complex user interface component
TextBox
List
Alert
 Generic screens
Form
交通大學資訊工程系
9-第37頁
Java
J2ME
GuiTests: Main Menu (List)
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class GuiTests extends MIDlet implements CommandListener {
private List mainMenu;
private static final Command exitCommand = new Command("Exit", Command.STOP, 2); //priority:2
public GuiTests() {
mainMenu = new List("Test Components", Choice.IMPLICIT);
mainMenu.append("Test TextBox", null);
mainMenu.append("Test List", null);
mainMenu.append("Test Alert", null);
mainMenu.append("Test Form", null);
mainMenu.addCommand(exitCommand);
mainMenu.setCommandListener(this); //見下一頁
mainMenu.setTicker(new Ticker(“Test GUI Components”)); //跑馬燈
showMainMenu();
}
public void startApp() {}
public void pauseApp() {}
/*略*/
private void showMainMenu() {
Display.getDisplay(this).setCurrent(mainMenu);
currentMenu = "Main";
}
}
交通大學資訊工程系
9-第38頁
Java
GuiTests: TextBox
J2ME
public class GuiTests extends MIDlet implements CommandListener {
private TextBox textBoxf = new TextBox("Enter Some Text:", "", 10, TextField.ANY);
private static final Command backCommand = new Command("Back", Command.BACK, 0); //priority:0
private String currentMenu;
public GuiTests() {
textBox.addCommand(backCommand);
textBox.setCommandListener(this);
textBox.setTicker(new Ticker("Testing TextBox")); //跑馬燈
}
private void showTextBox() {
textBox.setString("");
Display.getDisplay(this).setCurrent(textBox);
currentMenu = "input";
}
public void commandAction(Command c, Displayable d) {
List down = (List)Display.getDisplay(this).getCurrent();
switch(down.getSelectedIndex()) {
case 0: showTextBox(); break;
case 1: showList(); break;
case 2: showAlert(); break;
case 3: showForm(); break;
}
}
}
交通大學資訊工程系
9-第39頁
Java
GuiTests: List
J2ME
public class GuiTests extends MIDlet implements CommandListener {
private List list = new List("Choose Items", Choice.MULTIPLE);
private static final Command backCommand = new Command("Back", Command.BACK, 0); //priority:0
public GuiTests() {
list.addCommand(backCommand);
list.setCommandListener(this);
list.setTicker(new Ticker("Testing List"));
list.append("Item 1", null);
list.append("Item 2", null);
list.append("Item 3", null);
}
private void showList() {
Display.getDisplay(this).setCurrent(list);
currentMenu = "list";
}
public void commandAction(Command c, Displayable d) {
List down = (List)Display.getDisplay(this).getCurrent();
switch(down.getSelectedIndex()) {
case 0: showTextBox(); break;
case 1: showList(); break;
case 2: showAlert(); break;
case 3: showForm(); break;
}
}
交通大學資訊工程系
9-第40頁
}
Java
J2ME
GuiTests: Alert
public class GuiTests extends MIDlet implements CommandListener {
private Alert soundAlert = new Alert("sound Alert");
private void showAlert() {
soundAlert.setType(AlertType.ERROR);
soundAlert.setString("** ERROR **");
Display.getDisplay(this).setCurrent(soundAlert); //Play Sound
}
}
交通大學資訊工程系
9-第41頁
Java
GuiTests: Form (1/2)
J2ME
public class GuiTests extends MIDlet implements CommandListener {
private Form form = new Form("Form for Stuff");
private Gauge gauge = new Gauge("Progress Bar", false, 20, 9);
private DateField date = new DateField("Today's date: ", DateField.DATE);
private TextField textfield = new TextField("TextField Label", "abc", 12, 0);
private ChoiceGroup choice = new ChoiceGroup("choice", Choice.EXCLUSIVE,
new String[]{"choice 1", "choice 2"}, null);
private static final Command backCommand = new Command("Back", Command.BACK, 0); //priority:0
private static final Command mainMenuCommand = new Command("Main", Command.SCREEN, 1);
private static final Command exitCommand = new Command("Exit", Command.STOP, 2); //priority:2
private String currentMenu;
public GuiTests() {
form.append(new Spacer(2, 2));
form.append(new StringItem("label", "text"));
form.append(choice);
form.append(gauge);
form.append(textfield);
form.append(date);
form.addCommand(backCommand);
form.addCommand(mainMenuCommand);
form.addCommand(exitCommand);
form.setCommandListener(this);
}
//接下頁
交通大學資訊工程系
9-第42頁
Java
GuiTests: Form (2/2)
J2ME
//接上頁
private void showForm() {
Display.getDisplay(this).setCurrent(form);
java.util.Date now = new java.util.Date();
date.setDate(now);
currentMenu = "form";
}
public void commandAction(Command c, Displayable d) {
String label = c.getLabel();
if(label.equals("Exit")) {
try { destroyApp(true); }
catch(Exception e) {}
} else if(label.equals("Back")) {
if(currentMenu.equals("form")) {
int index = choice.getSelectedIndex();
mainMenu.setTitle("Form choice: " + index + " text:" + textfield.getString());
}
showMainMenu();
} else if(label.equals("Main")) {
showMainMenu();
} else {/*略*/}
}
}
交通大學資訊工程系
9-第43頁
Java
J2ME
Low-level APIs
Canvas
 Not component and container architecture
 It is really a canvas.
GameCanvas
 Add double buffering support.
 MIDP 2.0
Graphics
Font
Image
交通大學資訊工程系
9-第44頁
Java
J2ME
Using Graphics
(0,0)
The Graphics object is obtained in the paint()
method of the Canvas class.
The Graphics class is similar to that of AWT,
but with limited capabilities.
x
Canvas
 Two basic kinds of drawing
Primitive graphics (shapes and text)
PNG Images (opaque, transparent, and translucent)
 Provides a drawing context
(width-1, height-1)
y
The current drawing area
The current drawing color
The Coordinate System
The Two Forms of the Canvas’s repaint() Method
public void repaint()
public void repaint(int x, int y, int width, int height)
交通大學資訊工程系
9-第45頁
Java
J2ME
Painting Shapes and Text
The Graphics class can draw the following kinds of shapes:
 Lines: drawLine()
 Triangle: fillTriangle() MIDP 2.0
 Rectangles: drawRect(), fillRect()
 Round-edged rectangles:
drawRoundRect(), fillRoundRect()
 Arcs: drawArc(), fillArc()
 Text:
drawChar(), drawChars(),
drawString(), drawSubstring()
交通大學資訊工程系
9-第46頁
Java
J2ME
Using Fonts
static Font getFont(int face, int style, int size);
 Face: FACE_SYSTEM, FACE_MONOSPACE, or FACE_PROPORTIONAL
 Style: STYLE_PLAIN or a combination of STYLE_BOLD, STYLE_ITALIC, and
STYLE_UNDERLINED
 Size: SIZE_SMALL, SIZE_MEDIUM, or SIZE_LARGE
Font font1 = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_ITALIC | Font.STYLE_BOLD,
Font.SIZE_LARGE);
Font font2 = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_UNDERLINED, Font.SIZE_SMALL);
Font font3 = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
protected void paint(Graphics g){
g.setFont(font1); g.drawString("Proportional", 10, 10, anchor);
g.setFont(font2); g.drawString("Monospace", 10, 35, anchor);
g.setFont(font3); g.drawString("Default Font", 10, 60, anchor);
}
Get font information:
getBaseLinePosition()
Enjoy J2ME
getHeight()
stringWidth()
交通大學資訊工程系
9-第47頁
Java
J2ME
Anchor
The drawing of text and images is based on “anchor points.”
Anchor points are used to minimize the amount of computation
required when placing text.
void drawString(String text, int x, int y, int anchor);
boolean drawImage(Image img, int x, int y, int anchor);
 Anchor value (bit mask)
LEFT
Horizontal:
LEFT, HCENTER, RIGHT
Vertical:
TOP, VCENTER, BASELINE, BOTTOM
EX: Graphics.LEFT | Graphics.TOP
HCENTER
RIGHT
TOP
VCENTER
BASELINE
BOTTOM
交通大學資訊工程系
9-第48頁
Java
J2ME
Using Images
Loading Images
Displaying Images
Performing Animation
Double Buffering
交通大學資訊工程系
9-第49頁
Java
J2ME
Loading Images
Using the Image.createImage() static methods
 It is easy to get an Image object if image data is in PNG format.
Image Types:
 Immutable images: cannot obtain Graphics object from them
createImage(String pngFileName)
createImage(Image source, int x, int y, int w, int h, int transform)
createImage(InputStream stream)
createImage(Image source)
createImage(byte[] data, int imageOffset, int imageLength)
createRGBImage(int[] rgb, int w, int h, boolean processAlpha)
 Mutable images: can obtain Graphics object from them
createImage(int w, int h)
交通大學資訊工程系
9-第50頁
Java
J2ME
Displaying Images
Draw normal sized images
 boolean drawImage(Image img, int x, int y, int
anchor)
Draw rotated, mirrored images
 createImage(srcImage, 0, 0, w, h, transform) MIDP 2.0
Transform constants are defined in Sprite class
 TRANS_NONE, TRANS_MIRROR
 TRANS_ROT90, TRANS_ROT180, TRANS_ROT270
 TRANS_MIRROR_ROT90, TRANS_MIRROR_ROT180, TRANS_MIRROR_ROT270
Draw clipped images
 Use translate() and setClip() of Graphics to perform.
Draw scaled images
 No support!
交通大學資訊工程系
9-第51頁
Java
J2ME
Translation and Clipping
Translates the origin of the graphics context to
the given point.
(-a,-b)
(0,0)
translate(int x, int y)
x
Sets the current clip to the specified rectangle.
Rendering operations have no effect outside of
the clipping area.
Canvas
h
w
setClip(int x, int y, int w, int h)
(width-a-1, height-b-1)
y
After call g.translate(a, b)
and g.setClip(0, 0, w, h)
交通大學資訊工程系
9-第52頁
Java
J2ME
Performing Animation
Creating the Animation Loop
 Every program needs an animation loop to perform animation by
drawing at regular intervals.
 This loop should be in its own thread and never be in the
paint() method.
duke0.png, duke1.png, … , duke9.png
交通大學資訊工程系
9-第53頁
Java
J2ME
Double Buffering
MIDP 1.0
 Do it by yourself.
if(offImage == null)
{
offImage = Image.createImage(getWidth(), getHeight());
offG = offImage.getGraphics();
}
//performing painting
g.drawImage(offImage, 0, 0, Graphics.TOP | Graphics.LEFT);
MIDP 2.0
 The GameCanvas class do it for you.
flushGraphics();
flushGraphics(int x, int y, int w, int h);
交通大學資訊工程系
9-第54頁
Java
J2ME
Animation Canvas (1/3)
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class AnimationMidlet extends MIDlet
{
private AnimationCanvas canvas;
public AnimationMidlet()
{
try { canvas = new AnimationCanvas(); } catch(Exception e) {}
}
public void startApp()
{
Display.getDisplay(this).setCurrent(canvas);
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
}
交通大學資訊工程系
9-第55頁
Java
J2ME
Animation Canvas (2/3)
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
public class AnimationCanvas extends Canvas {
private int dukeIndex = 0;
private Image[] duke = new Image[10];
private Image[] dukeMirrored = new Image[10];
private Image offImage;
private Graphics offG;
public AnimationCanvas() throws Exception {
for(int i = 0; i < duke.length; i++) {
duke[i] = Image.createImage("/res/duke" + i + ".png"); //immutable image
dukeMirrored[i] = Image.createImage(duke[i], 0, 0, duke[i].getWidth(),
duke[i].getHeight(), Sprite.TRANS_ROT180); //製造旋轉後的圖
}
new MyThread().start(); //產生一個 thread 來執行動畫
}
protected void paint(Graphics g) {
if(offImage == null) {
offImage = Image.createImage(this.getWidth(), this.getHeight()); //mutable image
offG = offImage.getGraphics();
}
//清除背景
offG.setColor(255, 255, 255);
offG.fillRect(0, 0, this.getWidth(), this.getHeight());
//接下頁
交通大學資訊工程系
9-第56頁
Java
J2ME
Animation Canvas (3/3)
//接上頁
offG.drawImage(duke[dukeIndex], 0, 0, Graphics.TOP | Graphics.LEFT);
offG.drawImage(dukeMirrored[dukeIndex], 0, 70, Graphics.TOP | Graphics.LEFT);
drawClippedDuke(offG, 60, 0); //繪製切割過的圖
g.drawImage(offImage, 0, 0, Graphics.TOP | Graphics.LEFT);
}
private void drawClippedDuke(Graphics g, int x, int y) {
g.setClip(x, y, duke[dukeIndex].getWidth()/2, duke[dukeIndex].getHeight()); //設定clipper
g.drawImage(duke[dukeIndex], x, y, Graphics.TOP | Graphics.LEFT);
g.setClip(0, 0, this.getWidth(), this.getHeight()); //恢復
}
class MyThread extends Thread {
public void run() {
while(true) {
dukeIndex = (dukeIndex + 1) % duke.length;
repaint();
//等待100 milliseconds,等於每秒更新10次
try { Thread.sleep(100); }
catch(Exception e) {}
}
}
}
}
交通大學資訊工程系
9-第57頁
Java
J2ME
Processing Input Events
The Canvas class defines the following ITU Key codes:





KEY_NUM{0-9}
KEY_STAR (*)
KEY_POUND (#)
UP, DOWN, LEFT, RIGHT (logic key event)
GAME_{A-D} (logic key event)
Override the following method to process key events:
 For keyboard:
keyPressed(), keyRepeated(), keyReleased()
Use getGameAction() to get logic key event
 For touch pad:
pointerPressed(), pointerDragged(), pointerReleased()
交通大學資訊工程系
9-第58頁
Java
J2ME
Example: Key Events (1/2)
public class AnimationCanvas extends Canvas {
private int x = 30, y = 60;
private int code = 0;
private int action = 0;
private long interval = 100L;
private boolean bAnimation = true;
protected void paint(Graphics g)
{
if(offImage == null)
{
offImage = Image.createImage(this.getWidth(), this.getHeight());
offG = offImage.getGraphics();
}
offG.setColor(255, 255, 255);
offG.fillRect(0, 0, this.getWidth(), this.getHeight());
offG.setColor(0, 0, 0);
offG.drawImage(duke[dukeIndex], x, y, Graphics.TOP | Graphics.LEFT);
offG.drawImage(dukeMirrored[dukeIndex], x, y + 70, Graphics.TOP | Graphics.LEFT);
drawClippedDuke(offG, x + 60, y);
offG.drawString("code = " + code + " action = " + action + " interval = " + interval,
0, 0, Graphics.TOP | Graphics.LEFT);
g.drawImage(offImage, 0, 0, Graphics.TOP | Graphics.LEFT);
}
//接下頁
交通大學資訊工程系
9-第59頁
Java
J2ME
Example: Key Events (2/2)
class MyThread extends Thread {
public void run() {
while(true) {
if(bAnimation) { dukeIndex = (dukeIndex + 1) % duke.length; repaint(); }
try { Thread.sleep(interval); } catch(Exception e) {}
}
}
}
protected void keyPressed(int keyCode) {
code = keyCode;
action = getGameAction(keyCode);
switch(action) {
case UP: y -= 5; break;
case DOWN: y += 5; break;
case LEFT: x -= 5; break;
case RIGHT: x += 5; break;
}
switch(code) {
case KEY_NUM0: case KEY_NUM1: case KEY_NUM2:
case KEY_NUM3: case KEY_NUM4: case KEY_NUM5:
case KEY_NUM6: case KEY_NUM7: case KEY_NUM8:
case KEY_NUM9: interval = (keyCode - KEY_NUM0 + 1) * 50; break;
case KEY_STAR: bAnimation = !bAnimation; break;
}
}
}
交通大學資訊工程系
9-第60頁
Java
J2ME
Playing Sound
MIDP 1.0 does not specifies any relative APIs!
 Use vendor specified APIs to play sound.
 Use alert sound defined in AlertType class.
INFO, WARNING, ERROR, ALARM, CONFIRMATION
Ex: AlertType.INFO.playSound(Display display)
MIDP 2.0
 Use javax.microedition.media.Player to play sound.
Wave
MIDI
交通大學資訊工程系
9-第61頁
Java
J2ME
Example: Sound Player
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.media.*;
import java.io.*;
public class SoundMidlet extends MIDlet {
public SoundMidlet() {
try { //MIDP 2.0
Player player;
InputStream is = getClass().getResourceAsStream("/res/start.wav");
player = Manager.createPlayer(is, "audio/X-wav");
player.prefetch(); //把聲音資料預先讀到 buffer 中,這樣開始播放時不會 delay
//player.setLoopCount(-1); //一直重複播放
player.start();
Thread.sleep(3000);
} catch(Exception e) {}
}
public void startApp() {
Display.getDisplay(this).setCurrent(canvas);
//MIDP 1.0
AlertType.INFO.playSound(Display.getDisplay(this));
}
}
交通大學資訊工程系
9-第62頁
Java
J2ME
Guidelines for Programming UI for MID
Devices
Make the MIDlets’ user interface simple and easy to use.
Use the high-level API so your MIDlets are portable across handheld
devices.
If your application requires you to use the low-level API, keep to the
platform-independent part of the low-level API. This means your
MIDlets should not assume any other keys than defined in the the
Canvas class.
MIDlets should not depend on any specific screen size; they should
query the size of the display and adjust accordingly.
Entering data through a handheld device can be tedious. If possible,
provide a list of choices that the user can select from.
交通大學資訊工程系
9-第63頁
Java
J2ME
Essential APIs
2. Input/Output in MIDP
Review IO classes in Java SE
 Byte streams are used to read and write binary data such as
images and sounds.
 Character streams can handle any 16-bit characters in the
Unicode character set.
However, neither CLDC nor MIDP provides APIs for
access to file systems on mobile devices or external
memory cards.
 Not all MIDP devices have file systems, and
 the creators of those that do may not want to expose them to
applications.
交通大學資訊工程系
9-第64頁
Java
J2ME
Character Stream Family in MIDP
交通大學資訊工程系
9-第65頁
Java
J2ME
Byte Stream Family in MIDP
System.in
System.out
System.err
交通大學資訊工程系
9-第66頁
Java
J2ME
Alternatives to File IO
The alternative to FileInputStream
 getClass().getResourceAsStream(file) returns an
InputStream instance.
 Example:
InputStream inputStream =
getClass().getResourceAsStream("myPicture.jpg");
How about FileOutputStream?
 MIDP Record Management System (RMS)
交通大學資訊工程系
9-第67頁
Java
J2ME
MIDP RMS
Record Management System (RMS) is a persistent storage
for MIDlets.
 In Java SE, they are JDBC and Object Serialization APIs.
RMS consists of a collection of records.
 Data written into those records will remain persistent after the
MIDlet exits.
 When you invoke the MIDlet again, it can retrieve data from the
persistent record store.
RMS APIs provides the following functionality:
 Manipulate (add and remove) records within a record store.
 Share records in the same application.
 MIDP 2.0 allows you to share records in different applications.
交通大學資訊工程系
9-第68頁
Java
J2ME
Using RMS (1/2)
Package: javax.microedition.rms
Usages:
 Open a Record Store
RecordStore db = RecordStore.openRecordStore("name", true);
the name is case sensitive, and cannot be more than 32 characters long.
true means that create the record store if not exist.
 Create a New Record (ID is started from 1)
byte[] data = textfield.getString().getBytes();
int id = db.getNextRecordID(); //取得新增資料時,會被指定的 ID
db.addRecord(data, 0, data.length); //新增資料,ID 是 db 指定的
交通大學資訊工程系
9-第69頁
Java
J2ME
Using RMS (2/2)
 Read Data from the Record Store
byte[] data = db.getRecord(1); //取得 ID = 1 的資料
if(data != null)
{
textfield.setString(new String(data));
}
 Delete a Record from the Record Stroe
Use record ID to deleted the record
db.deleteRecord(1); //刪除 ID = 1 的資料
交通大學資訊工程系
9-第70頁
Java
J2ME
Example: RMS
import javax.microedition.rms.*;
public class RmsTests extends MIDlet implements CommandListener {
private RecordStore db;
public RmsTests() {
try {
db = RecordStore.openRecordStore("mydb", true);
System.out.println("SizeAvailable = " + db.getSizeAvailable());
System.out.println("Size = " + db.getSize());
First time output:
System.out.println("Num of Records " + db.getNumRecords());
SizeAvailable = 996689
System.out.println("Next Record ID " + db.getNextRecordID());
Size = 48
if(db.getNumRecords() == 1) {
Num of Records 0
byte[] data = db.getRecord(1);
Next Record ID 1
if(data != null) textfield.setString(new String(data));
Second time output:
}
SizeAvailable = 996737
} catch(Exception e) {}
Size = 80
}
Num of Records 1
public void destroyApp(boolean unconditional) {
Next Record ID 2
byte[] data = this.textfield.getString().getBytes();
try {
if(db.getNumRecords() == 0) db.addRecord(data, 0, data.length);
else db.setRecord(1, data, 0, data.length);
} catch(Exception e) {}
}
}
交通大學資訊工程系
9-第71頁
Java
J2ME
Essential APIs
3. Network
Package: javax.microedition.io
MIDP 1.0
 HttpConnection
 StreamConnection
MIDP 2.0
 HttpsConnection
 SocketConnection
Use Connector to open connection
c = (StreamConnection)Connector.open(“http://localhost/index.html”);
c = (SocketConnection)Connector.open("socket://localhost:4444");
交通大學資訊工程系
9-第72頁
Java
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import java.io.*;
public class HttpMidlet extends MIDlet {
private TextBox t;
public HttpMidlet() {
try {
String url = "http://java.sun.com:80/j2se/1.5.0/docs/api/java/net/URL.html";
StreamConnection c = null;
InputStream s = null;
StringBuffer b = new StringBuffer();
try {
c = (StreamConnection)Connector.open(url);
s = c.openInputStream();
int ch;
while((ch = s.read()) != -1) b.append((char)ch);
t = new TextBox("hello....",
b.toString().substring(0, 1024), 1024, 0);
} finally {
if(s != null) s.close();
if(c != null) c.close();
}
} catch(Exception e) {}
}
public void startApp() { Display.getDisplay(this).setCurrent(t); }
}
J2ME
Example: URL Reader
交通大學資訊工程系
9-第73頁
Java
J2ME
Example: Echo Client MIDlet
import javax.microedition.midlet.*;
import javax.microedition.io.*;
import java.io.*;
public class EchoClientMidlet extends MIDlet {
public EchoClientMidlet() {
try {
SocketConnection sc = (SocketConnection)Connector.open("socket://localhost:4444");
sc.setSocketOption(SocketConnection.LINGER, 5);
InputStream is = sc.openInputStream();
OutputStream os = sc.openOutputStream();
os.write("hello\n".getBytes());
int ch = 0;
while(ch != -1) System.out.print((char)is.read());
is.close();
os.close();
sc.close();
} catch(Exception e) {}
}
public void startApp() {}
public void pauseApp() {}
Output:
public void destroyApp(boolean unconditional) {}
hello
}
交通大學資訊工程系
9-第74頁
Java
J2ME
練習: Monty Hall
1.
2.
3.
4.
5.
6.
7.
8.
9.
使用 MIDlet
可選3 ~6 個門
按鍵1~6表示要打開門的編號
某個門有寶藏,找到時,獲得獎金,且全部的門都要打開(贏)
某個門裡面是炸彈,打開時立刻結束遊戲(輸)
獎金:門的數量*100。第一次開門就找到寶藏,可以全拿。每多
開一次門,獎金就會減半。看到提示炸彈訊息時,獎金也會減半
。獎金可以累計,但不能低於0
(進階+10)必須防止畫面閃爍
(進階+10)顯示動畫
(進階+10)播放音效
交通大學資訊工程系
9-第75頁
Java
J2ME
練習:Calculator
1.
2.
3.
4.
5.
6.
7.
8.
使用 MIDlet
提供整數的"加法、減法、乘法、除法"。輸入數值最多8位數
加減乘除都是立即運算,不需要管四則運算
運算過程若發生錯誤,要顯示錯誤訊息。如 overflow、除數為 0
、輸入過大的數等等
按鍵對應:0~9, # 清除, 上下左右對應到+,-,*,/
(進階+10)支援 M+, M-, Mr, Mc 的功能
(進階+10)支援小數運算
(進階+10)*鍵連按切換 +, -, *, /
交通大學資訊工程系
9-第76頁
Java
J2ME
Introduction to Java Programming
謝謝捧場
http://www.csie.nctu.edu.tw/~tsaiwn/java/
蔡文能
交通大學資訊工程系
9-第77頁