Screensaver on J2ME or Back to the past. Part one
Good day!
Outside the third of January, and the soul of the matter requires to write some program. Without thinking, I remembered that once offered adjustment the author of a topic Splash Screen on J2ME, and then doubts about what to write, finally dispelled. Today I invite you to plunge into the world of "normal dialer" and to write the application — it would just be a screensaver.
For a start you should install necessary software development. I think no need to explain what you need to put yourself on a PC to compile and run our application, because on the Internet this manual can be found in five seconds. Here, for example. Personally, I compile all source code applications for J2ME on "private dialer". Yes, Yes, there are craftsmen in the Russian land, who ported the compiler preverification on the J2ME platform.
After everything is installed, it would be nice to remember the theory itself, ranging from J2ME device application and ending with the directives of the Manifesto of our application. However, if you don't know what it is, don't worry — a bit of theory on the development of J2ME applications will be reviewed in this topic.
Generally, the application in J2ME is called a MIDlet. Why so you will learn next.
App for J2ME is nothing but a class inherited from the class MIDlet from the package javax.microedition.midlet. This class is the "heart" MIDlet'a. In our class we have to declare three methods, necessary for the functioning of our application:
the
The fact that this method is specified as necessary for implementation in a time as practical use it carries. Methods startApp() and pauseApp() used by most AMS, and destroyApp() — no. Traditionally, typically the block of this function looks like the following:
the
As you can see, end of life cycle of applications manages the notifyDestroyed(), not destroyApp(). Anyway, the purpose of the past will remain a mystery. Not to digress, and move on.
The next step in the implementation of our application is to obtain a reference to the object Display package javax.microedition.lcdui. As you might guess, this is done to be able to operate the screen forms (the javax.microedition.lcdui.Form) or canvas (the javax.microedition.lcdui.Canvas) and switch between them. Get a link we can as follows:
the
It's done, move on to the next step.
Immediately want to note that with the advent of class GameCanvas — he's started to replace normal Canvas due to the impossibility of double bufferization out of the box, as such the last. Therefore, as a canvas, I suggest to use GameCanvas. No sooner said than done.
GameCanvas and Canvas differ just only in two ways: the first has already been specified (this is double buffersize), and the second is the need for a method Declaration paint in the latter. For clarity, we give the following implementation code of the canvas using the Canvas:
the
In the method paint() we perform the entire rendering of graphics primitives. This approach is not particularly effective for many reasons, one of which is the desire to separate the logic.
GameCanvas allows us to put the logic in other methods, classes etc. like this:
the
Then I made a mistake: did not declare the object Graphics somewhere inside the Declaration of the class itself in place of variable declarations, i.e. the code should look like the following:
the
Something like that. That's it — the necessary knowledge base to implement the plan we have. Go!
Our application will consist of several classes:
Welcome! midlet.java:
the
Then the canvas midletCanvas.java:
the
Next is the timer midletTimerTask.java:
the
And finally, the implementation of the selection of random numbers random.java
the
My sources don't want to compile. Rather, they are compiled, but is not what I want. Late at night, so yours truly had to take not their source. I apologize for the code formatting — corrected tomorrow.
Compilation and preverification. This step I leave to you.
I suggest you Tinker with that file and it is located in the directory META-INF. After all, if we make a screensaver, then it needs to conduct himself accordingly. Unfortunately, this behavior is only available phones from Sony Ericsson. Let's add the following line:
the
We made it possible to download our screensaver as a background image. For this you need to throw the MIDlet in the phone. Then go to "Applications", find our. The next step is pressing the right soft key and select "As background. the picture". Choose to eat. You will see the following
The source code you can take on Pastebin. here they are:
midlet.java
midletCanvas.java
midletTimerTask.java
random.java
That's all. Just for a few steps we have written a MIDlet. In our days J2ME gradually goes nowhere and perhaps you have already left a similar tube, but so far Oracle does support — who knows, whether there will be. I hope you found it interesting.
See you soon!
Article based on information from habrahabr.ru
Introduction
Outside the third of January, and the soul of the matter requires to write some program. Without thinking, I remembered that once offered adjustment the author of a topic Splash Screen on J2ME, and then doubts about what to write, finally dispelled. Today I invite you to plunge into the world of "normal dialer" and to write the application — it would just be a screensaver.
so let's get started
For a start you should install necessary software development. I think no need to explain what you need to put yourself on a PC to compile and run our application, because on the Internet this manual can be found in five seconds. Here, for example. Personally, I compile all source code applications for J2ME on "private dialer". Yes, Yes, there are craftsmen in the Russian land, who ported the compiler preverification on the J2ME platform.
After everything is installed, it would be nice to remember the theory itself, ranging from J2ME device application and ending with the directives of the Manifesto of our application. However, if you don't know what it is, don't worry — a bit of theory on the development of J2ME applications will be reviewed in this topic.
Anatomy of J2ME applications
Generally, the application in J2ME is called a MIDlet. Why so you will learn next.
javax.microedition.midlet.MIDlet
App for J2ME is nothing but a class inherited from the class MIDlet from the package javax.microedition.midlet. This class is the "heart" MIDlet'a. In our class we have to declare three methods, necessary for the functioning of our application:
the
public void startApp() {
// this method is called at startup of our application
}
public void pauseApp() {
// this method is called when our device receives a call, SMS, etc.
}
public void destroyApp(boolean unconditional) {
// this method is called when it is invoked.
// now explain...
}
The fact that this method is specified as necessary for implementation in a time as practical use it carries. Methods startApp() and pauseApp() used by most AMS, and destroyApp() — no. Traditionally, typically the block of this function looks like the following:
the
public void destroyApp(boolean unconditional) {
notifyDestroyed(); // this method closes our app
}
As you can see, end of life cycle of applications manages the notifyDestroyed(), not destroyApp(). Anyway, the purpose of the past will remain a mystery. Not to digress, and move on.
javax.microedition.lcdui.Display
The next step in the implementation of our application is to obtain a reference to the object Display package javax.microedition.lcdui. As you might guess, this is done to be able to operate the screen forms (the javax.microedition.lcdui.Form) or canvas (the javax.microedition.lcdui.Canvas) and switch between them. Get a link we can as follows:
the
Display dsp = Display.getDisplay(this); // like this...
It's done, move on to the next step.
javax.microedition.lcdui.game.GameCanvas
Immediately want to note that with the advent of class GameCanvas — he's started to replace normal Canvas due to the impossibility of double bufferization out of the box, as such the last. Therefore, as a canvas, I suggest to use GameCanvas. No sooner said than done.
GameCanvas and Canvas differ just only in two ways: the first has already been specified (this is double buffersize), and the second is the need for a method Declaration paint in the latter. For clarity, we give the following implementation code of the canvas using the Canvas:
the
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
public class OurCanvas extends Canvas { // inherit from the Canvas
public void paint(Graphics g) {
int w = getWidth(); // get the screen height
g.setColor(0xffffff); // set the color of the brush
g.fillRect(0,0,w,h); // fill the selected area with specified color
}
}
In the method paint() we perform the entire rendering of graphics primitives. This approach is not particularly effective for many reasons, one of which is the desire to separate the logic.
GameCanvas allows us to put the logic in other methods, classes etc. like this:
the
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
public class OurCanvas extends GameCanvas implements Runnable { // inherited from GameCanvas and implement Runnable interface that is used by the Thread class
public void run() {
Graphics g = getGraphics(); // get a reference to the Graphics object
// with which we draw these graphics primitives
int w = getWidth(); // get the screen height
int h = getHeight(); // about the width, do not forget
g.setColor(0xffffff); // set the color of the brush
g.fillRect(0,0,w,h); // fill the selected area with specified color
}
}
Then I made a mistake: did not declare the object Graphics somewhere inside the Declaration of the class itself in place of variable declarations, i.e. the code should look like the following:
the
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
public class OurCanvas extends GameCanvas implements Runnable {
Graphics g = getGraphics();
int w = getWidth();
int h = getHeight();
public void run() {
g.setColor(0xffffff);
g.fillRect(0,0,w,h);
isSomethingDone();
}
public void isSomethingDone() {
g.setColor(0xababab);
g.drawLine(25,25,125,125);
}
}
Something like that. That's it — the necessary knowledge base to implement the plan we have. Go!
Go to design
Our application will consist of several classes:
Welcome! midlet.java:
the
import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.*;
import java.util.Timer;
public class midlet extends MIDlet {
Timer timer;
midletTimerTask task;
midletCanvas canvas;
public midlet () {
canvas = new midletCanvas(this); // create the canvas
timer = new Timer ();
task = new midletTimerTask (canvas); // and the task to be executed
timer.scheduleAtFixedRate(task,10,10); // every 10 milliseconds
// 10 MS - very little. So we cause the repaint method will check
// finished drawing the previous screen, use the flag in
}
protected void startApp() { // directly pass control to the canvas
Display.getDisplay(this).setCurrent (canvas);
}
protected void pauseApp() {}
protected void destroyApp(boolean unconditional) {}
public void exitMIDlet() {
notifyDestroyed();
}
}
Then the canvas midletCanvas.java:
the
import javax.microedition.lcdui.*;
midletCanvas class extends Canvas {
midlet midlet;
random random;
static int [] PlasmaTab = { //color table plasma - 256 elements
32,32,33,34,35,35,36,37,38,39,39,40,41,42,42,43,
44,45,45,46,47,47,48,49,49,50,51,51,52,52,53,54,
54,55,55,56,56,57,57,58,58,59,59,59,60,60,60,61,
61,61,62,62,62,62,63,63,63,63,63,63,63,63,63,63,
63,63,63,63,63,63,63,63,63,63,62,62,62,62,62,61,
61,61,60,60,60,59,59,58,58,58,57,57,56,56,55,54,
54,53,53,52,52,51,50,50,49,48,48,47,46,46,45,44,
43,43,42,41,40,40,39,38,37,37,36,35,34,33,33,32,
31,30,30,29,28,27,26,26,25,24,23,23,22,21,20,20,
19,18,17,17,16,15,15,14,13,13,12,11,11,10,10, 9,
9, 8, 7, 7, 6, 6, 5, 5, 5, 4, 4, 3, 3, 3, 2, 2,
2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2,
2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9,
9,10,11,11,12,12,13,14,14,15,16,16,17,18,18,19,
20,21,21,22,23,24,24,25,26,27,28,28,29,30,31,31
};
//Of course, I have not manually filled the table, and the received
//according to the law 32* (1+ sin (x*(2*pi/255)), bringing everything to whole numbers
static int Delta = 6; //cell size of the plasma pixels
static int Yold_pos=0, Yold_asp=0, Xold_pos=0, Xold_asp=0;
int Ynew_pos, Ynew_asp, Xnew_pos, Xnew_asp, x, y, Color;
static int Width, Height; //Width and height of the screen
static boolean in = false; //redraw
Graphics gbuffer; //and this is for
Image screen; //double buffering
public midletCanvas (midlet midlet) {
this.midlet = midlet;
Random = new random ();
setFullScreenMode (true); //the Only operator profile MIDP 2.0
Width = getWidth ();
Height = getHeight ();
screen=Image.createImage(Width,Height);
gbuffer=screen.getGraphics(); //draw gbuffer going on,
draw (gbuffer); //and then simultaneously display it on a canvas!
}
void draw (Graphics g) { //draw to another buffer the plasma state
in = true;
Ynew_pos = Yold_pos;
Ynew_asp = Yold_asp;
for (y=0; y<Height; y+=Delta) {
Xnew_pos = Xold_pos;
Xnew_asp = Xold_asp;
for (x=0; x<Width; x+=Delta) {
Color = PlasmaTab[Ynew_pos]+ PlasmaTab[Ynew_asp]+
PlasmaTab[Xnew_pos]+ PlasmaTab[Xnew_asp];
g.setColor(((255-Color)<<16 | Color<<8 | 128+(Color>>1)));
g.fillRect (x,y,Delta,Delta);
Xnew_pos += 1;
if (Xnew_pos > 255) Xnew_pos=0;
Xnew_asp += 7;
if (Xnew_asp > 255) Xnew_asp=0;
Ynew_pos += 2;
if (Ynew_pos > 255) Ynew_pos=0;
Ynew_asp += 1;
if (Ynew_asp > 255) Ynew_asp=0;
}
Xold_pos -= 2;
if (Xold_pos<0) Xold_pos=255;
Xold_asp += Random.get(8);
if (Xold_asp > 255) Xold_asp=0;
Yold_pos += 4;
if (Yold_pos > 255) Yold_pos=0;
Yold_asp -= Random.get(6);
if (Yold_asp<0) Yold_asp=255;
in = false;
}
protected void paint (Graphics g) {
if (in == true) return; //If we still can redraw
g.drawImage(screen,0,0,0);
draw (gbuffer);
}
public void keyPressed(int keyCode) {
switch (keyCode) { //Exit button #
case Canvas.KEY_POUND:
midlet.exitMIDlet();
break;
}
}
}
Next is the timer midletTimerTask.java:
the
import java.util.TimerTask;
import javax.microedition.midlet.MIDlet;
class midletTimerTask extends TimerTask {
midletCanvas canvas;
public midletTimerTask (midletCanvas canvas) {
this.canvas = canvas;
}
public final void run() {
canvas.repaint();
}
}
And finally, the implementation of the selection of random numbers random.java
the
import java.util.Date;
import java.util.Random;
class random { //a Class that wraps a random number generator
private Random r;
private Date d;
public random () {
d = new Date ();
r = new Random (d.getTime());
}
public int get (int max) { //a random number from the range [0,max-1]
int n=r.nextInt()%max;
return (n<0 ? -n : n);
}
}
the Scandals, intrigues, investigation
My sources don't want to compile. Rather, they are compiled, but is not what I want. Late at night, so yours truly had to take not their source. I apologize for the code formatting — corrected tomorrow.
Next trick
Compilation and preverification. This step I leave to you.
MANIFEST.MF
I suggest you Tinker with that file and it is located in the directory META-INF. After all, if we make a screensaver, then it needs to conduct himself accordingly. Unfortunately, this behavior is only available phones from Sony Ericsson. Let's add the following line:
the
SEMC StandbyApplication: Y
What we do
We made it possible to download our screensaver as a background image. For this you need to throw the MIDlet in the phone. Then go to "Applications", find our. The next step is pressing the right soft key and select "As background. the picture". Choose to eat. You will see the following
Here's what happened
All you need
The source code you can take on Pastebin. here they are:
midlet.java
midletCanvas.java
midletTimerTask.java
random.java
Opinion
That's all. Just for a few steps we have written a MIDlet. In our days J2ME gradually goes nowhere and perhaps you have already left a similar tube, but so far Oracle does support — who knows, whether there will be. I hope you found it interesting.
See you soon!
Комментарии
Отправить комментарий