Java ME String FX
Article Metadata
Tested with
Devices(s): Nokia 5310 XPress Music
Compatibility
Device(s): all MIDP2 compliant devices. Symbian devices
Article
Created: reflexus@ig.com.br
(08 Oct 2011)
Last edited: hamishwillee
(17 Oct 2011)
This example demonstrates a simple String FX bouncing Screen Saver in Java ME. It draws a bouncing string on the screen (like the ball in arkanoid/breakout games) with a nice FX.
It requires an understanding of Java ME basics and simple threading.
Code
The code is self-explanatory (commented).
- Just put your message String s, and let it go!
- 0 Key: show/hide fps.
import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
public class Midlet extends MIDlet {
private Display d;
private Canvas c;
public Midlet() {
c = new Canvas();
}
public void startApp() {
d = Display.getDisplay(this);
d.setCurrent(c); // it will implicitly call c.showNotify()
}
public void pauseApp() {
//
}
public void destroyApp(boolean destroy) {
notifyDestroyed();
}
}
/* Brought to you by: JavaMan (GRP). reflexus@ig.com.br
* Enjoy!!!
*/
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
public class Canvas extends GameCanvas implements Runnable {
// A new Graphics object is created and returned each time this method is called; therefore,
// the needed Graphics object should be obtained once, and reused in the app.
private final Graphics g = getGraphics();
private final Font font = Font.getFont(Font.FONT_STATIC_TEXT);
private Thread t;
private int x, y; // coordinates
private boolean h; // h = true, increase x else decrease x
private boolean v; // v = true, increase y else decrease y
private byte vel = 2; // velocity
private byte dist = 26; // elastic distance in pixels
private byte cont; // timing. it is incremented each cycle.
//private byte i; // avoid memory waste
private boolean elastic;
private int canvasWidth, canvasHeight;
private boolean running;
private boolean pause;
private static final String s = "JAVA ME. By GRP.";
private int charsWidth; // total s width, in pixels (s.length() dependant)
private int charHeight; // char height, in pixels (always the same)
// cicles = frames per second
private boolean showFPS;
private int fps;
private int cyclesThisSecond;
private long lastFPSTime;
public Canvas() {
super(true);
setFullScreenMode(true);
canvasWidth = getWidth();
canvasHeight = getHeight();
h = false; // going left
v = true; // going down
y = 0;
x = dist*vel; // (0)zero is default
cont = (byte)(dist);
charsWidth = font.charsWidth(s.toCharArray(), 0, s.length());
if (charsWidth>canvasWidth) System.out.println("Warning: String s is too big!\n");
charHeight = font.getHeight();
/*g.setColor(0, 0, 0);
g.fillRect(0, 0, canvasWidth, canvasHeight);*/
}
// override the javax.microedition.lcdui.Canvas method
public void keyPressed(int keyCode) {
// RIGHT_SOFTKEY
if (keyCode == -7) {
//if (!pause) pause(); else resume();
}
else
// LEFT_SOFTKEY
if (keyCode == -6) {
//if (pause) resume();
}
else if (keyCode == this.KEY_NUM0) {
showFPS = !showFPS; // boolean inversion
}
}
// start our thread by calling the run() method
public void start() {
running = true;
t = new Thread(this);
t.start();
}
// stop our thread
public void stop() {
running = false;
t = null;
}
// system soft notification when it is hidden by another app or incoming call.
// it is wise to release resources here, for example, an active media (subtype Player)
public void hideNotify() {
stop();
}
// system soft notification when it comes into view
public void showNotify() {
start();
}
// implements the java.lang.Runnable method
public void run() {
while (running) {
// clear screen
g.setColor(0, 0, 0);
g.fillRect(0, 0, canvasWidth, canvasHeight);
// fps
if (System.currentTimeMillis() - lastFPSTime > 1000) {
lastFPSTime = System.currentTimeMillis();
fps = cyclesThisSecond;
cyclesThisSecond = 0;
} else
cyclesThisSecond++;
// elastic fx
if (!elastic) cont++; else cont--;
if (cont>dist) {
elastic = true;
}
if (cont==-dist) {
elastic = false;
}
//if (cont==-1) cont=0; else
{
// bounce logic
if (h) x+=vel; else x-=vel;
if (v) y+=vel; else y-=vel;
if (x+charsWidth>canvasWidth) h = false;
if (x<0) h = true;
if (y+charHeight>320) v = false;
if (y<0) v = true;
}
// plots
for (byte i=127; i>=0; i--) {
// your fx
}
// draw
for (byte i=5; i>=0; i--) {
g.setColor(255 - i*40, 255 - i*40, 255 - i*40);
g.drawString(s, x - i*cont + i*(cont/2), y - i*cont + i*(cont/2), Graphics.TOP | Graphics.LEFT);
//g.drawString(s, x - i*dist + i*(dist/2), y - i*dist + i*(dist/2), Graphics.TOP | Graphics.LEFT);
}
if (showFPS) g.drawString("fps:"+fps, 0, 0, Graphics.TOP | Graphics.LEFT);
/*g.setColor(255, 255, 255);
g.drawString(s, x, y, Graphics.TOP | Graphics.LEFT);*/
flushGraphics(0, 0, canvasWidth, canvasHeight);
try {
Thread.sleep(0); // max performance
} catch (InterruptedException ex) { }
}
}
}


Hamishwillee - This is incomplete
Hi George
Thank you for this article. As it is clearly incomplete I've added the UnderConstruction template. Can you please update the template with a timestamp for when you plan to complete this. The reason it is incomplete is that it is just a code dump. No one can use this because there isn't any real explanation of who it is for, what it shows - no one will read it if they have to invest time working out whether the code is relevant. Its also worth explaining the code that isn't obvious - for example why did you do something this way rather than another way, what were your design decisions.
I have added the ArticleMetaData template. This states who created the article and when, and its testing and compatibility (ie what devices tested on, what platforms should it work on, what SDK built against.). CAN YOU please update the template with the information because this helps them understand whether the article is likely to be relevant to them ... particularly over time.
I've added in an Abstract. Please put in a 1 sentence explanation of what the code covers and who it is for in particular.
I've added all the code in a code block for readability.
Are there any more appropriate categories?
Please see the Help:Wiki Article Review Checklist for other guidance.
HamishThank you
hamishwillee 03:42, 10 October 2011 (EEST)