Lớp Graphics
Chúng ta sử dụng đối tượng Graphics để vẽ lên một Canvas. Một ứng dụng MIDP chỉ có một đối tượng Display. Đối tượng này đuợc dùng để lấy thông tin của màn hình hiển thị hiện tại, ví dụ như số màu hỗ trợ và các phương ...
Chúng ta sử dụng đối tượng Graphics để vẽ lên một Canvas.
Một ứng dụng MIDP chỉ có một đối tượng Display. Đối tượng này đuợc dùng để
lấy thông tin của màn hình hiển thị hiện tại, ví dụ như số màu hỗ trợ và các phương
thức để yêu cầu các đối tượng được hiển thị. Đối tượng Display đơn giản là một bộ
quản lý sự hiển thị của thiết bị và điều khiển những gì sẽ được hiển thị ra trên thiết bị.
boolean isColor()
int numColors()
Phương thức đầu tiên cho biết thiết bị có hỗ trợ hiển thị màu hay không. Nếu có thì phương thức thứ 2 sẽ được gọi để xác định số màu được hỗ trợ. Các phương thức tiếp theo dưới đây để lấy về màu và thiết lập màu ưa thích của bạn.
void setColor(int RGB)
void setColor(int red, int green, int blue)
int getColor()
int getBlueComponent() int getGreenComponent() int getRedComponent()
void setGrayScale(int value)
int getGrayScale()
Chú ý bạn có thể xác định màu bằng 2 cách. Cách 1: bạn có thể xác định một số nguyên đại diện cho 3 giá trị của màu là đỏ, xanh lá cây và xanh dương với 8 bit cho mỗi màu. Hay cách 2 là bạn có thể dùng từng tham số riêng biệt để xác định mỗi màu. Khi sử dụng một giá trị để lưu giữ màu, thì màu đỏ sẽ chiếm 8 bit đầu kể từ bên trái, tiếp theo là 8 bit dành cho màu xanh lá cây, sau cùng là màu xanh dương.
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;
...
g.setColor((red << 16) | (green << 8) | blue);
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ạ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ị. Dưới đây là các phương thức dùng để thiết lập loại nét vẽ
int getStrokeStyle()
void setStrokeStyle(int style)
Hai kiểu nét vẽ được định nghĩa trong lớp Graphics là nét chấm, và nét liền
g.setStrokeStyle(Graphics.DOTTED); hay g.setStrokeStyle(Graphics.SOLID);
Khi vẽ một cung, bạn có thể vẽ nó chỉ có đường bao xung quanh hay yêu cầu nó được tô bên trong. Bạn có thể bắt đầu bằng cách chỉ định chiều bao quanh bên ngoài của một hình hộp chữ nhật tưởng tượng. Góc bắt đầu xác định vị trí bắt đầu vẽ khung, với giá trị 0 được xác định tại thời điểm 3 giờ. Giá trị dương tính theo ngược
chiều kim đồng hồ. Góc của cung chỉ ra rằng có bao nhiêu độ được vẽ tính từ góc ban đầu, đi theo ngược chiều kim đồng hồ. Để hiểu rõ những phần này chúng ta hãy cùng xem1 ví dụ sau:
g.drawArc(10, 10, 100, 100, 0, 150);
Đoạn mã trên yêu cầu vẽ một cung, cung này được bao bởi một hình chữ nhật có tọa độ điểm trái trên là (10, 10), chiều rộng và chiều dài là 100, góc bắt đầu là 0, góc kết thúc là 150
Một số các phương thức dùng để vẽ cung
void drawArc(int x, int y, int awidth, int height, int startAngle, int arcAngle) void fillArc(int x, int y, int awidth, int height, int startAngle, int arcAngle) Dưới đây là đoạn mã minh họa viêc sử dụng các hàm trên để vẽ một cung import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class DrawShapes extends MIDlet
{
private Display display; // The display
private ShapesCanvas canvas; // Canvas
public DrawShapes()
{
display = Display.getDisplay(this);
canvas = new ShapesCanvas(this);
}
protected void startApp()
{
display.setCurrent( canvas );
}
protected void pauseApp()
{ }
protected void destroyApp( boolean unconditional )
{ }
public void exitMIDlet()
{
destroyApp(true);
notifyDestroyed();
}
}
/*--------------------------------------------------
* Class ShapesCanvas
*
* Draw arcs
*-------------------------------------------------*/
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());
// Black pen
g.setColor(0, 0, 0);
// Start at 3 o'clock and rotate 150 degrees
g.drawArc(10, 10, 100, 100, 0, 150);
// Fill the arc
// g.fillArc(10, 10, 100, 100, 0, 150);
// Start at 12 o'clock and rotate 150 degrees
// g.drawArc(10, 10, 100, 100, 90, 150);
// 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();
}
}
Cũng giống như cung thì hình chữ nhật có thể chỉ được vẽ viền bao quanh hoặc tô bên trong. Bên cạnh đó bạn có thể vẽ hình chữ nhật đó có 4 góc là tròn hoặc là vuông. Dưới đây là một số phương thức để vẽ hình chữ nhật:
void drawRect(int x, int y, int awidth, int height)
void drawRoundRect(int x, int y, int awidth, int height, int arcWidth, int arcHeight)
void fillRect(int x, int y, int awidth, int height)
void fillRoundRect(int x, int y, int awidth, int height, int arcWidth, int arcHeight)
Khi vẽ hình chữ nhật có 4 góc là tròn thì bạn phải xác định đường kính theo chiều ngang(arcWidth) và đường kính theo chiều dọc(arcHeight). Những tham số này được định nghĩa độ sắc nét của cung theo mỗi chiều. Giá trị càng lớn thể hiện một cung tăng dần, ngược lại là một đường cong hẹp
Phần sau đây cũng quan trọng không kém 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. Sau đây là một số các phương thức dựng của lớp Font
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 FACE_MONOSPACE FACE_PROPORTIONAL
STYLE_PLAIN STYLE_BOLD STYLE_ITALIC STYLE_UNDERLINED
SIZE_SMALL SIZE_MEDIUM SIZE_LARGE
Cá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);
Sau khi bạn có một tham chiếu đến một đối tượng Font, bạn có thể truy vấn nó để
xác định thông tin của các thuộc tich của nó.
int getFace() int getStyle() int getSize()
boolean isPlain() boolean isBold() boolean isItalic() boolean isUnderlined()
Kích thước của các font chữ được xác định bởi chiều cao của font chữ, bề dài tính bằng điểm ảnh của một chuỗi ký tự trong một font xác định. Một số các phương thức sau hỗ trợ khi tương tác với một đối tương font
int getHeight()
int getBaselinePosition()
int charWidth(char ch)
int charsWidth(char[] ch, int offset, int length)
int stringWidth(String str)
int substringWidth(String str, int offset, int length)
Để xác định tọa độ x, y của chuỗi ký tự được hiển thị, thì điểm neo cho phép bạn chỉ ra vị trí muốn đặt tọa độ x, y trên hình chữ nhật bao quanh chuỗi ký tự
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
Chiều ngang
LEFT (Bên trái)
HCENTER (Chính giữa của chiều ngang) RIGHT (Bên phải)
Chiều dọc
TOP (Ở trên)
BASELINE (Đường thẳng cơ sở) BOTTOM (Ở dưới)
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ể thay đổi vị trí hiển thị của chuỗi ký tự trên thiết bị di động. Ví dụ tiếp theo chúng ta sẽ minh họa tiếp khi thay đổi điểm neo thì vị trí của chuỗi ký tự cũng thay đổi theo:
g.drawString("developerWorks", 0, 0 , Graphics.TOP | Graphics.HCENTER);
Sau khi tìm hiểu về font và các điểm neo, bạn đã có thể vẽ chuỗi ký tự ra màn hình thông qua một số các phương thức sau:
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)
void drawSubstring(String str, int offset, int len, int x, int y, int anchor)
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);
}
Tiếp theo là ví dụ minh họa việc sử dung font và xuất chuỗi ra thiểt bị hiển thị
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class FontViewer extends MIDlet
{
protected Display display; // The display
protected PrefsForm fmPrefs; // Form to choose font prefs
protected FontCanvas cvFont; // Canvas to display text (in preferred font)
public FontViewer()
{
display = Display.getDisplay(this);
cvFont = new FontCanvas(this);
fmPrefs = new PrefsForm("Preferences", this);
}
protected void startApp()
{
showCanvas();
}
protected void showCanvas()
{
display.setCurrent(cvFont);
}
protected void pauseApp()
{ }
protected void destroyApp( boolean unconditional )
{ }
public void exitMIDlet()
{
destroyApp(true);
notifyDestroyed();
}
}
/*--------------------------------------------------
* FontCanvas.java
*
* Draw text using specified Font
*-------------------------------------------------*/
import javax.microedition.lcdui.*;
class FontCanvas extends Canvas implements CommandListener
{
private int face, // Font face
style, // style
size; // size
private String text = "developerWorks"; // Text to display in preferred font
private Command cmExit; // Exit midlet
private Command cmPrefs; // Call the preferences form
private FontViewer midlet; // Reference to the main midlet
public FontCanvas(FontViewer midlet)
{
this.midlet = midlet;
// 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)
{
this.style = 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);
}
}
/*--------------------------------------------------
* PrefsForm.java
*
* 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
protected ChoiceGroup cgFace, // Font face cgStyle, // style
cgSize; // size
protected TextField tfText; // Text string to display on canvas
// (with the requested font prefs)
private int face = 0, // Values for font attributes
style = 0, // that are obtained from the choicegroups
size = 0;
private String text = null; // Value for text string from the textfield
public PrefsForm(String title, FontViewer midlet)
{
// Call the form constructor
super(title);
// Save reference to MIDlet so we can
// access the display manager class
this.midlet = midlet;
// Commands
cmSave = new Command("Save", Command.SCREEN, 1);
cmBack = new Command("Back", Command.BACK, 2);
// Exclusive choice group for font face
cgFace = new ChoiceGroup("Face Options", Choice.EXCLUSIVE);
cgFace.append("System", null);
cgFace.append("Monospace", null);
cgFace.append("Proportional", null);
// Multiple choice group for font style
cgStyle = new ChoiceGroup("Style Options", Choice.MULTIPLE);
cgStyle.append("Plain", null);
cgStyle.append("Bold", null);
cgStyle.append("Italic", null);
cgStyle.append("Underlined", null);
// Exclusive choice group for font size
cgSize = new ChoiceGroup("Size Options", Choice.EXCLUSIVE);
cgSize.append("Small", null);
cgSize.append("Medium", null);
cgSize.append("Large", null);
// Textfield for text to display on canvas
tfText = new TextField("", "developerWorks", 20, TextField.ANY);
// Create form contents and listen for events
append(cgFace);
append(cgStyle);
append(cgSize);
append(tfText);
addCommand(cmSave);
addCommand(cmBack);
setCommandListener(this);
setItemStateListener(this);
}
/*--------------------------------------------------
* Command event handling
*-------------------------------------------------*/
public void commandAction(Command c, Displayable s)
{
if (c == cmSave)
{
// Set the values in canvas class to those selected here
midlet.cvFont.setFace(face);
midlet.cvFont.setStyle(style);
midlet.cvFont.setSize(size);
// Make sure we aren't passing a null value
midlet.cvFont.setText(tfText.getString() !=
null ? tfText.getString() : "developerWorks");
}
// No specific check needed for "Back" command
// Always return to the canvas at this point
midlet.showCanvas();
}
public void itemStateChanged(Item item)
{
if (item == cgFace)
{
switch (cgFace.getSelectedIndex())
{
case 0:
face = Font.FACE_SYSTEM;
break;
case 1:
face = Font.FACE_MONOSPACE;
break;
case 2:
face = Font.FACE_PROPORTIONAL;
break;
}
}
else if (item == cgStyle)
{
boolean[] b = new boolean[4];
cgStyle.getSelectedFlags(b);
style = 0;
// STYLE_PLAIN has a value of 0
// No need to check for b[0]
// If bold selected
if (b[1])
style = Font.STYLE_BOLD;
// If italic selected
if (b[2])
style |= Font.STYLE_ITALIC;
// If underlined selected
if (b[3])
style |= Font.STYLE_UNDERLINED;
}
else if (item == cgSize)
{
switch (cgSize.getSelectedIndex())
{
case 0:
size = Font.SIZE_SMALL;
break;
case 1:
size = Font.SIZE_MEDIUM;
break;
case 2:
size = Font.SIZE_LARGE;
break;
}
}
else if (item == tfText)
{
text = tfText.getString();
}
}
}
cung cấp 1 phương thức dùng để vẽ ảnh:
drawImage(Image img, int x, int y, int anchor)
Chúng ta cũng áp dụng từng bước khi vẽ ảnh cũng giống như khi xuất chuỗi ra màn hình. Đối với cả 2 thì chúng ta đều phải bắt đầu bằng việc thiết lập tọa độ x, y cũng như điểm neo. Danh sách các điểm neo cho việc hiển thị ảnh cũng không khác mấy so với việc xuất chuỗi, tuy nhiên không giống với việc xuất chuỗi thì một bức ảnh có một điểm trung tâm. Ví thế VCENTERđược thay thế cho gia trị BASELINE khi làm việc với ảnh
Ch i ề u ng a ng
LEFT (Bên trái)
HCENTER (Điểm chính giữa theo chiều ngang) RIGHT (Bên phải)
Ch i ề u d ọc
TOP (Điểm trên)
VCENTER (Điểm chính giữa theo chiều dọc) BOTTOM (Bên dưới
Trong các phần trước, chúng ta đã tạo ra các ứng dụng MIDP cho việc trình bày một tấm ảnh đọc từ một nguồn tài nguyên là một tập tin. Loại ảnh này không cho phép thay đổi, và vì vậy còn được biết với tên là “ảnhkhôngthểthayđổi”. Đối với ví dụ sau đây, chúng ta sẽ tạo ra một tấm ảnh từ những đống tạp nham, chúng ta sẽ cấp phát bộ nhớ cho tấm ảnh, để lấy tham chiếu đến một đối tượng Graphics, và chúng ta sẽ tự vẽ nội dung tấm ảnh. Loại ảnh này còn được biết với một cái tên là “ảnhcóthể biến thayđỏiđược”
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class DrawImage extends MIDlet
{
private Display display; // The display
private ImageCanvas canvas; // Canvas
public DrawImage()
{
display = Display.getDisplay(this);
canvas = new ImageCanvas(this);
}
protected void startApp()
{
display.setCurrent( canvas );
}
protected void pauseApp()
{ }
protected void destroyApp( boolean unconditional )
{ }
public void exitMIDlet()
{
destroyApp(true);
notifyDestroyed();
}
}
/*--------------------------------------------------
* Class ImageCanvas
*
* Draw mutable image
*-------------------------------------------------*/
class ImageCanvas extends Canvas implements CommandListener
{
private Command cmExit; // Exit midlet
private DrawImage midlet;
private Image im = null;
private String message = "developerWorks";
public ImageCanvas(DrawImage midlet)
{
this.midlet = midlet;
// Create exit command and listen for events
cmExit = new Command("Exit", Command.EXIT, 1);
addCommand(cmExit);
setCommandListener(this);
try
{
// Create mutable image
im = Image.createImage(100, 20);
// Get graphics object to draw onto the image
Graphics graphics = im.getGraphics();
// Specify a font face, style and size
Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
graphics.setFont(font);
// Draw a filled (blue) rectangle, with rounded corners
graphics.setColor(0, 0, 255);
graphics.fillRoundRect(0,0, im.getWidth()-1, im.getHeight()-1, 20, 20);
// Center text horizontally in the image. Draw text in white
graphics.setColor(255, 255, 255);
graphics.drawString(message,
(im.getWidth() / 2) - (font.stringWidth(message) / 2),
(im.getHeight() / 2) - (font.getHeight() / 2),
Graphics.TOP | Graphics.LEFT);
}
catch (Exception e)
{
System.err.println("Error during image creation");
}
}
/*--------------------------------------------------
* Draw mutable image
*-------------------------------------------------*/
protected void paint(Graphics g)
{
// Clear the display
g.setColor(255, 255, 255);
g.fillRect(0, 0, getWidth(), getHeight());
// Center the image on the display
if (im != null)
g.drawImage(im, getWidth() / 2, getHeight() / 2,
Graphics.VCENTER | Graphics.HCENTER);
}
public void commandAction(Command c, Displayable d)
{
if (c == cmExit)
midlet.exitMIDlet();
}
}
clip() và translate() là 2 phương thức của lớp Graphics. Một vùng hiển thị được cắt xén được định nghĩa là khu vực hiển thị của thiết bị di động, vùng này sẽ được cập nhật trong suốt thao tác vẽ lại. Dưới đây là một số phương thức hỗ trợ cho việc xén một vùng hiển thị
void setClip(int x, int y, int awidth, int height) void clipRect(int x, int y, int awidth, int height) int getClipX()
int getClipY()
int getClipWidth()
int getClipHeight()
translate() là một phương thức được sử dụng có liên quan đến hệ thống trục tọa độ. Chúng ta có thể tịnh tiến hệ trục tọa độ đến một điểm x, y khác. Một số phương thức hỗ trợ cho việc tịnh tiến hệ trục tọa độ
void translate(int x, int y)
int getTranslateX()
int getTranslateY()