Tuesday, March 30, 2010
Sunday, March 28, 2010
fastest browser
The Browser Wars are heating up again. First there was the funeral party for Internet Explorer 6 (let's hope it stays buried), then we had the EU mandate for the Browser Ballot, a feature which has lead to the corrosion of the IE's install base, Firefox overtook Internet Explorer 7, and recently, we saw the release of Opera 10.50 - the self-proclaimed Fastest Browser on Earth... As we were putting up the finishing touches on this article Microsoft released a sneak peek of Internet Explorer 9; and not a moment too soon as you will learn soon.
Opera has long been playing the role of best supporting actor in the browser theater for the past 14 years. The past few years have seen relative upstarts - Mozilla Firefox and Google Chrome - steal market share and mind share from this browser of yore. Popularity notwithstanding, Opera has always been the melting pot for new ideas and features, to which Turbo, and Unite are some of the latest additions. Opera's newest weapon - its brand new JavaScript compiling engine called "Carakan" (pronounced 'Jarakan') is claimed to sprint seven times faster than its previous "Futhark" engine. This definitely makes the browser faster than its predecessors, but how does it compare to its competitors?
When Opera proclaims something as bold as "Earth's Fastest Browser", we had to take a closer look and check the validity of this claim. Its competition is surely not sitting idle: Google Chrome's V8 engine is constantly being improved, as it evident from the performance gains in each dev release; Mozilla is polishing their SpiderMonkey engine with each new version, and en route to creating a new JavaScript engine, and Safari is tweaking its SquirrelFish engine - all trying their best to squeeze every drop from their JavaScript engines. With that in mind, we felt that the browsers needed to go against each other and show us what they've really got.
This article then is purely about which one of our favourite browsers is the Fastest. We haven't covered all the browsers under the sun but certainly all the usual suspects.
To that end, we will take a look at our favourite browsers' performance across two parts. The first part will take you through the tests we will throw at these browsers, describing in detail our reasoning for picking these tests and what to make of their results. In the second part, we shall produce the comparison data and benchmark details with the conclusion crowning the performance winner.
So before spilling out the names of the gladiators, let's checkout the proving-ground and the gauntlet each competitor will run through. Here's the list of tests that each of the browser took (spoiler alert - some failed these tests):
*
Acid 3 Test
This one needs little introduction. Our good-old Acid test is a standard tool for testing a browser's standards-compliance and any browser test is incomplete without it.
*
Dromaeo Test
Once warmed up, we let the browsers battle it out using the Dromaeo tests. This set of tests gives us a detailed break-up of nearly all aspects of JavaScript interpreting, rendering, and CSS rendering performance. The great thing about Dromaeo is that, despite being a Mozilla project, it includes all the tests of the Apple WebKit (SunSpider) and Chrome's (V8) JavaScript tests, besides the Dromaeo tests (Mozilla's own test suite) itself.
Furthermore, it has the CSS Selector test that uses some JavaScript libraries for DOM (Document Object Model) queries and gives us a CSS performance chart. We performed all tests to ensure that the results have as little bias as possible. This is a pretty extensive test, with a very detailed result sheet. While we won't delve into its depths in this discussion, we shall put the links of the detailed comparison data to whet the appetite of the uber-geeks among us.
A note on Internet Explorer 8 here: we could not include Internet Explorer 8 into this test as the browser behaved very erratically. We could not save its test sessions, it failed to complete the entire test on many runs; reporting script alerts often. IE8 did not play nice with Dromaeo and was thus kept out of this round. Considering that these tests used commonly used functions, this ia quite a failure on the browsers part.
*
PeaceKeeper Test
Peacekeeper is a web browser benchmarking service from FutureMark. It takes into account the PC hardware configuration. PeaceKeeper simulates a realistic web surfing workload: JavaScript usage and implementation of the most visited categories of websites such as social networking sites, online video sharing sites, and so on. It also performs an intensive and complex graphics rendering test with the use of the new HTML5 (canvas) implementation for the major browsers.
*
JSNES Speed Test
Lastly, we ran our good-ol' Contra in a JavaScript NES emulator to give our champs a real workout and recorded their frame-rate. Ben Firshman has come up with this cool new emulator for the Nintendo Entertainment System inspired by Matt Westcott's JSSpeccy which runs on the dual-power of JavaScript and HTML5's Canvas element. While describing a browser's performance on his page, Ben mentioned the performance of Google Chrome to be best, with Safari close behind. Firefox's somewhat playable framerate was also noted; but he completely skipped any comment on Opera. We didn't forget though. Every one of the browsers were stress tested using this tool.
We ran all the tests on the same test machine, under the same test conditions.
Now let's take at our champs, while they are warming up for the big battle:
Web browser
Alias
Versions
Microsoft Internet Explorer
IE
8.0.7600.16385
Apple Safari 4
Safari
4.0.4 (531.21.10)
Opera 10.50
Opera
10.50 Build 3296
Google Chrome Stable
Chrome
4.0.249.89
Google Chrome Developer*
Chrome [Dev]
5.0.342.1
Mozilla Firefox
Firefox
3.6
Mozilla Firefox Nightly*
Minefield
3.7a3pre
NOTE: We've also thrown Internet Explorer 9's platform preview into this mix but as Microsoft's licensing restricts us, we cannot publish the benchmarking data. We will suggest how it did across these tests though. We will refer to this preview build as IE9 for the rest of this article.
The test-bed we selected had to strike a delicate balance: it needed to be common enough such that it reflects the "average" computer used to browse and yet it needed to have enough juice to run these applications. We went with a value notebook with the following specs: Intel Core Duo T2300 processor at 1.67GHz on an Intel G945 mainboard, with 1x2GB 667MHz DDR2 Transcend memory and an on-board GMA950 display adapter. Windows 7 was our operating system.
Before we get to our tests The Browser Wars are heating up again. First there was the funeral party for Internet Explorer 6 (let's hope it stays buried), then we had the EU mandate for the Browser Ballot, a feature which has lead to the corrosion of the IE's install base, Firefox overtook Internet Explorer 7, and recently, we saw the release of Opera 10.50 - the self-proclaimed Fastest Browser on Earth... As we were putting up the finishing touches on this article Microsoft released a sneak peek of Internet Explorer 9; and not a moment too soon as you will learn soon. Opera has long been playing the role of best supporting actor in the browser theater for the past 14 years. The past few years have seen relative upstarts - Mozilla Firefox and...
Opera Mini 5 and Opera Mobile 10 released
The final versions of Opera Mini 5 and Opera Mobile 10, have today been released, and can be downloaded from any compatible phone by visiting http://m.opera.com/
Opera has been quite active on the Mobile browser front recently, especially with Opera Mini, which only recently has broken into two new platforms, Windows Mobile and Apple's iPhone OS. Although the Opera Mini browser is still in beta for Android and Windows Mobile, and the iPhone version is still not available.
Now the only platforms Opera Mini is yet to be available for are, Palm's webOS (although that might be underway) and Samsung's Bada. With this Opera's Presto web rendering engine is even more ubiquitous, second only to webkit.
Opera Mini 5 and Opera Mobile 10 bring a host of improvements in the mobile browsers, mainly in their support for tabbed browsing, a download manager, a password manager and a new speed dial with favorite websites. The latest version also brings support for Opera Turbo in Opera Mobile, which further increases speed of this powerful browser.
Browsers and Operating Systems pwned and hacked during Pwn2own;
(ZDI) hacking challenge- Pwn2own 2010, is making things harder for many of the well-known 'secure' browsers and platforms. Hackers have breached the security of Windows 7 and Mac OS X, mostly using browser loopholes. Even the Apple iPhones was not spared.
Security expert Peter Vreugdenhil managed to crack Windows 7 64-bit, using Internet Explorer 8. First he used a bypass for ASLR (Address Space Layout Randomization), a security feature of Windows, and then using this, broke into the Browser. He then used the information gleaned to bypass DEP (Data Execution Prevention) and to gain complete control of the victim's system. The experts from Microsoft present there stated that they weren't aware of this and will soon work towards a fix. Peter said, he used fuzz test logs (a brute force technique) to expose this vulnarability and it took nearly two weeks to code the exploit.
Third time in a row, Charlie Miller successfully exploited a MacBook with the help of Safari's vulnerability. He also used a website, to exploit one of the conference organizer's MacBook. When that person surfed the link of the site with Safari, Miller immediately gained control over his laptop. Miller also used fuzz technique to find the vulnerability, like Peter Vreugdenhil. Details of the whole process has been cloaked for security reasons.
Safari's security holes proved fatal in case of iPhones too. Vincenzo Iozzo (22) and Ralf Philipp Weinmann (32) used one of the vulnerabilities of iPhone Safari to hack into it and hijacked the whole SMS database. This duo made the iPhone 3GS user to browse their specially crafted attack-website with Safari, to gain control on the device. Weinmann explained, a non-root user, named 'mobile' is there in the device's Sandbox, and has certain normal user-like privileges; this user account is what they actually hacked. So basically, everything that the 'mobile' can do, they can do - remotely. The victim felt it like a normal page was loading, while in this 20 sec time span his entire SMS database was stolen. Though the attack did not go smoothly -- the browser crashed after the act. Weinmann said that they can work to fix this issue, so that the process can terminate without any acknowledgment from the user.
Even the Firefox and Opera browsers were under attack. Firefox was tricked with a zero-day vulnerability, on Windows 7. A payload of calc.exe (Calculator) was used, though the Hacker - Nils (a student at the University of Oldenburg, and a researcher of MWR InfoSecurity) reported, it can be switched with any process. This Firefox and Opera attacks are reported to be similar as of the IE8 hacking, though not much light has been put on that matter. Chrome was the only browser that didn't fall for any of these security traps. Miller stated, he finds Chromes sandbox very hard to crack, even though its vulnerability is known. All of the successful hackers won loads of prizes for their achievements. USD 10,000 was the basic prize money for each of the challenges along with the system that they hacked into. Bonus prizes include USD 5,000, 20,000 ZDI points, 25% reward for Pwn2own 2011, 15% prize money bonus for Pwn2own 2011 and free trip to DEFCON at Las Vegas.
Today, on the 26th of March, ZDI (Zero Day Initiative) is supposed to report to the concerning bodies of each of the vulnerable platforms, with details of the attacks and loopholes, so that they can work on to resolve the same. In the meantime, we can only ask you to wait for a security update of your favourite browser (ignore this message if you are a Google Chrome user).
62 hours later Final Fantasy XIII reviewed
Final Fantasy XIII reviewed-----------------------
Square Enix has embarked on the Fabula Nova Crystalis journey with the release of Final Fantasy XIII as the flagship game in the series. While Square Enix has retained some of the series trademark traits that make the game instantly recognizable, there are also some significant shifts with its core-game-play. A traditionalist may find it hard to readily accept some of the changes in the system that has transformed it from being typical turn-based to something that is perched precariously between real-time and turn-based. Besides the combat system — and other elements that are closely related to it — Final Fantasy XIII retains the series' unique style of storytelling and character development.As this game is part of the Fabula Nova Crystalis series of games, the central theme...
Square Enix has embarked on the Fabula Nova Crystalis journey with the release of Final Fantasy XIII as the flagship game in the series. While Square Enix has retained some of the series trademark traits that make the game instantly recognizable, there are also some significant shifts with its core-game-play. A traditionalist may find it hard to readily accept some of the changes in the system that has transformed it from being typical turn-based to something that is perched precariously between real-time and turn-based. Besides the combat system — and other elements that are closely related to it — Final Fantasy XIII retains the series' unique style of storytelling and character development.
As this game is part of the Fabula Nova Crystalis series of games, the central theme revolves around the uncontrollable and over-bearing power of ‘Crystals’ to influence life and politics. Final Fantasy XIII tells the story of two worlds — a land called the Pulse and a tiny planet called Cocoon that hovers over Pulse. The leaders of the two worlds have ensured that their people are extremely fearful and hateful of each other and the real story behind the struggle is revealed through the exploits of the a group of people from both worlds. One cannot help but notice the striking similarities between the game’s story and real-life events following the discovery of Black Gold that affects the world even today.
The game’s protagonist is an ex-member of the local army who goes by the name of Lighting. As the game progresses and events transpire, she joins up with a group of five other characters that share tenuous similarities in the past and are now faced with a common ordeal. A few hours into the game, this group gets marked by the powerful Fal’cie to become the instruments of Cocoon’s destruction. This task pushes the limit of the party’s skills as well as their mental resolve as most of them call Cocoon their home. The game can have a similar effect on the player, and the main plot itself can run into little over 60 hours of game-play. This is mainly because the game’s story develops at a very slow and steady pace, and this is achieved through Square’s trademark in-game cut-scenes and brilliant pre-rendered videos.
Getting marked by the Fal’cie unleashes new and powerful abilities within each of the six party members. One such ability allows a character to specialize in three of the six available classes. These classes will be all too familiar to patrons of role-playing games. Referred to by different names, these roles are that of a melee specialist, a tank, healer and offensive, defensive and de-buffing spell-casters. A maximum of three party members can enter a battle and the player can directly control only one character. As for the other two party members, the player can only control the characters current role (healer, tank, spell-caster, etc) and this referred to as a Paradigm shift.
The player can time the attacks of all the party members to unleash a volley of chain attacks on the enemies for increased damage. When a single enemy is relentlessly attacked, its chain meter begins to fill up. Once this meter is completely filled up the enemy gets ‘staggered’ and this causes each subsequent attack to be substantially more damaging. These Paradigms are central to this game’s combat system and it surprisingly opens up many tactical and strategic options that retain its lustre till the very end.
At the end of a battle the player is rewarded with Cyrstogen Points (CP) along with other possible rewards like items, weapons and potions. CP is used to unlock skills and abilities from a multi-tiered skill-tree specific to each class. Some of these abilities unlock new moves for a character while others improve the character’s stats like hit-points. As mentioned earlier, each character starts-off with three classes that are predetermined by the game. Deep into the storyline, the game unlocks the ability for party members to grow in any of the six classes. Considering the CP cost at higher level, the player will likely have to trade between sticking to original classes or diversify a character into new domains.
During specific point in the game’s storyline, each character gains the ability to summon a personal guardian called Eidolons. Each party member will get a unique Eidolon and only the party leader can summon them at a cost of precious Technique Points. These Technique Points are precious since the only consistent way of earning these is by getting a high rating at the end of each battle. Each of these Eidolons also has something called as a Gestalt Mode that essentially allows the player to ride their summoned guardian and unleash special moves. The summon durations are fairly short, so this ability is mostly used as a trump card in a particularly tough battle.
One of the hallmarks of a good game is the ability to consistently reward the player with something new and Final Fantasy XIII manages to pull this off quite admirably. The first half of the game has the party members scattered in different groups and this time is used to establish the characters in the story. Predetermined party configuration and variety of enemy types keeps things constantly interesting. Then towards the climax of the storyline, the game unlocks a total of 64 side-missions that can be completed before or after beating the game. The game features upgradable weapons and items that can take considerable time and effort and unfortunately, it can be described as daunting at best. This is one feature that sticks out like a sore in what is otherwise a pretty enjoyable experience.
After finishing the main plot, the game unlocks another tier in each of class skill-trees. This is mainly useful to prepare your party for some of the hidden and epic enemy encounters whose hit-points can run into a few millions. Completing some of the side-missions rewards the player with the ability to use a Chocobo as a mount. This further opens up access to new areas and subsequently, new encounters and treasures. All these options easily add another 10 to 20 hours of game-play, taking the total close to 80 hours. This should be exciting for hardcore fans of the genre that do not shy away from long hours and actually revel in it.
As I had mentioned earlier, the Paradigm system is central to the game’s combat system, and you are going to engage in a lot of fighting in this game. This is because the party is constantly on the run and the game has nothing resembling a town or a hub. After you are half-way through the game, the enemy’s hit-points starts getting into range of a million. The key to winning such battles is to understand the enemy’s weaknesses and accordingly selecting the party configuration. Selecting the appropriate Paradigms and shifting between them to adapt to a situation is equally important. This is not a very complex system, but if you fail to properly understand and use it, some battles will be very long and frustrating.
The game’s visuals are shiny and the game runs brilliantly on the PlayStation 3, which is a big plus in itself. The load-times are quite low and I did not notice frame-drops or any other common graphical artifacts. Beside the upgrade system—which I found cumbersome—there is little else that is glaringly wrong with the game. Maybe I should mention that this is an outsider’s view as I am admittedly not a big-fan of JRPG. I remember Grandia II as the only other Japanese RPG that I enjoyed and played several times over.
Programming Mobile Phone Applications in Java
INTRODUCTION:
Welcome to a starters overview on programming mobile phone applications in Java. This Java development uses a different edition of Java, Java 2 Micro Edition. If you have made other Java applications, it will most likely have been in the Standard Edition or Enterprise Edition. Info on getting the Micro Edition if you don't have it will be explained in the HOW TO START section, as well as how to get your programming environment up and running. This type of Java development can be used to create applications for many devices ranging from mobile phone, PDA’s, pagers, and any limited device that supports Java. If you’ve never used this type of development before, it might sound complicated, but it's actually surprisingly easy, made so by the API’s and development environment available to us. In this article (overview) I am only detailing the essential basics, such as drawing, interactions, controls, file handling etc, to get your J2ME programming up and running, and to give you an idea of what J2ME development is about, and hopefully both a nice starting place and future reference. This overview focuses on the coding aspect of J2ME development, information on setting up your device, or info on software to do with installing applications is not covered here.
USER REQUIREMENTS:
Before you start to program wireless device applications in Java, a moderate knowledge AT LEAST is required. Although this is quite easy, it’s not an outright beginner’s topic, if you have only just started to learn Java,gain some experience and familiarity with the language and return when you feel you would like to see more on this type of Java development.
CONFIGURATIONS, PROFILES AND OPTIONAL PACKAGES:
Three things central to J2ME development are Configurations, Profiles and Optional Packages. These things basically define your Java environment, available API’s and the features of Java that you can use when writing applications for your device.
Java defines two Configurations: CLDC and CDC.
The CLDC (Connected Limited Device Configuration) and the CDC (Connected Device Configuration) contain a Java VM (Virtual Machine, usually the KVM for CLDC or CVM for CDC, although any VM adhering to the correct standards will work) to execute bytecode, to have the necessary native code to communicate specifically with the device it’s on, and a set of core classes. There aren’t many core classes defined in the configurations, so the functionality of the J2ME application relies on the additional classes defined in the various profiles and optional packages. The CLDC is the Configuration used for small devices, with little memory (i.e. Mobile Phones) and has a very small set of core classes, only the bare essentials. The CDC is used for more powerful and capable devices, including a fully-featured Java VM and a lot more core classes.
Profiles provide more device-specific classes, to add functionality to your application, such as User Interface (UI) classes. There are several profiles for J2ME development, for both configurations. For CLDC there is the MIDP (Mobile Information Device Profile) which was the original CLDC profile, and now the PDAP (Personal Digital Assistant Profile), which is like a tweaked / improved MIDP that comes in many varieties and is made for more powerful devices. For CDC there is the FP (Foundation Profile), which has more core classes from the Standard Edition of Java, the PBP (Personal Basis Profile) which extends the FP with more UI classes (from the Java 2 Standard Edition AWT Classes). Finally the PP (Personal Profile) adds to the PBP with more UI classes and applet support.
Optional packages provide even more functionality to your program by defining new sets of API’s that don’t really fit into any profile. Profiles may contain more specific API’s, but none of them are optional, i.e. if a device supports a profile, it must support everything defined within that profile. An API for Bluetooth, for example, would fit into the category of an optional package- simply because making it a part of a profile would limit that particular profile to only Bluetooth-enabled devices.
The most common Configuration for simple mobile phones is the CLDC, and the Profile MIDP, hence, this is what this article will cover.
HOW TO START:
Since this is a different type of Java Development, trying to build J2ME projects from your regular IDE might not work (unless it supports wireless development or you get a J2ME plug-in). The easiest way to build J2ME projects used to be with something called the Wireless Tool Kit,If you have the old WTK program (before it was implemented into the SDK) get the 'ktoolbar.exe' program up and running, create a new project and the Toolkit will create all the necessary directories and files for you in it's apps directory, if you have the new J2ME SDK, simply run the main application, it's a fully featured IDE, so create a new project and you’re ready to go. When you create your project, you'll need to make sure you have the settings right- you need the correct MIDP and CLDC versions for your phone. You can set these by choosing the right target platform, and choosing the available options. If you create an application that’s ‘invalid’ when you try to run it on your device, then you are probably trying to use a version of CLDC or MIDP that your device doesn’t support. The J2ME SDK comes with many mobile phone emulators, simulating how your application will run under different phone model environments / constraints. Although this is nice and simple way to test your application, whilst your project / application is under development you should load it onto your device and test it under that environment often. Installing these applications on your phone can differ from model to model. Some phones you can simply drag and drop the .jar and the .jad files where you want them, some phones you can’t. You may want to see if you can get software from your device manufacturer, i.e. Nokia’s ‘Nokia PC Suite’. Some manufacturer software allows you to install your applications in different ‘environments’, this gives you application more or less freedom security-wise.
PORTABILITY
A very important issue with all developed applications is portability, and J2ME development is no different. Not only is there capability difference with this type of development (different MIDP / CLDC versions), there is also device-specific restrictions to take careful note of. These restrictions are things like screen size, amount of keypad buttons, types of buttons, graphical / audio capabilities etc. With these in mind, it is a lot easier to develop for a specific device model but this is not always an option. To create applications that are portable with a wider range of devices, you should be as general as possible . By this I mean that you reference specific details as little as possible. An example of this would be that if your mobile phone that you were creating an application for had a screen of about 200x200, and you wanted to draw (Low-Level UI) a proportioned rectangle of 20x20 (one tenth by one tenth), halfway from the top, and a quarter way from the left, rather than doing this:
CODE :
//g is an object of Graphics
g.drawRect(50, 100, 20, 20); //x, y, width, height
You should do something like this:
CODE :
g.drawRect(this.getWidth()/4, this.getHeight()/2, this.getWidth ()/10, this.getHeight()/10);
In this way, the scene would appear the same on different phone models of different screen sizes, because all the dimensions are adjusted to their environment. This same practice should be carried out as much as possible in all areas of your development. Another thing to consider is that the devices that you’re creating applications for are small / lightweight. I.e. they have little memory and for the most part a slower / lighter processor. For this reason, you must try to program in an efficient manner, so as to ensure your application works well with a range of different phone models. It’s very tempting to implement Runnable (use multithreading) for every class you have that extends Canvas, so you can keep up a constant repaint() (constantly update the screen). This coupled with other classes that rely upon multithreading can slow down your application or cause it to have a different performance on other phone models, so you should try to only use multithreading when it’s absolutely necessary.
PARTS OF A J2ME PROGRAM:
Just as you have Applications for the computer and Applets for the web, you have MIDlets for the wireless device. The entry point for your J2ME program must inherit (extend) MIDlet, but other classes you make don't have to. Like the Applet class, the MIDlet class is abstract, and so has required methods that any class inheriting MIDlet needs to override. These methods are:
CODE :
public void startApp(){
}
public void pauseApp(){
}
public void destroyApp(boolean unconditional){
}
Putting this into perspective, a general MIDlet template would look like this (excluding user-interaction support / multithreading support / Any Display support, added in a nice, common, way to close application through exit()):
CODE :
//File: MyMIDlet.java
import javax.microedition.midlet.*; //MIDlet
import javax.microedition.lcdui.*; //UI
public class MyMIDlet extends MIDlet
{
public MyMIDlet(){
}
public void startApp(){
}
public void pauseApp(){
}
public void destroyApp(boolean unconditional){
}
private void exit() {
System.gc(); //Garbage Collect
destroyApp(false); //Run destroyApp method
notifyDestroyed(); //Let application know it’s now in destroyed //state
}
}
All J2ME classes can be found in javax.microedition.*;
Classes that extend various other abstract J2ME classes (such as Canvas etc) will also have methods that will need to be overwritten.
Already you may notice a problem here- the main class needs to extend MIDlet, which means that it can’t inherit any other superclasses (although it can implement whatever it wants)- so what do we do when we want to draw to the screen and so on? The answer is simple, make different classes for the different ‘screens’ you wish your application to display at various times, have those classes extend the necessary superclass, and then to show them, simple transfer the display focus from the main MIDlet onto the class of the “screen” you wish to show. To transfer focus, the target must be a subclass of ‘Displayable’ (see Display Hierarchy in ADDITIONAL), i.e. a subclass of Screen, Canvas etc.
In the following example, the application enters at MyMIDlet, and then the MyMIDlet class transfers focus onto the MyCanvas class which fills the screen with white and draws a black string. In this way, the MyCanvas class is a ‘screen’, and you can quite easily make different classes to represent different ‘screens’ in your application and transfer focus between them whenever you wish. More on drawing and graphics will be covered in the DRAWING AND GRAPHICS section.
CODE :
//File MyMIDlet.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class MyMIDlet extends MIDlet
{
private Display display;
private MyCanvas canvas;
public MyMIDlet(){
display = Display.getDisplay(this);
canvas = new MyCanvas();
}
public void startApp(){
display.setCurrent(canvas);
}
public void pauseApp(){
}
public void destroyApp(boolean unconditional){
}
}
//File MyCanvas.java
import javax.microedition.lcdui.*;
public class MyCanvas extends Canvas
{
public MyCanvas(){
}
public void paint(Graphics g){
g.setColor(0xFFFFFF);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(0x000000);
g.drawString(“You’re in MyCanvas!”, 20, 20, Graphics.LEFT | Graphics.TOP);
}
}
A finished j2me application consists of two files, a .jar and a .jad. The .jar file holds all the classes, resources and the manifest file, whereas the .jad is a descriptor, i.e. it ‘describes’ the j2me application to the device that will run it. If you are not using an IDE, you will need to package all the necessary files into a jar, and create an appropriate .jad file. (Although it is a lot easier to let the IDE take care of this for you). Here is what a typical .jad file looks like:
CODE :
MIDlet-1:
MIDlet-Jar-Size:
MIDlet-Jar-URL:
MIDlet-Name:
MIDlet-Vendor:
MIDlet-Version:
MicroEdition-Configuration:
MicroEdition-Profile:
To put this into perspective, here’s the current .jad file for my J2ME Sokoban game:
CODE :
MIDlet-1: SokobanMain,/BOX1.png,SokobanMain
MIDlet-Jar-Size: 317218
MIDlet-Jar-URL: SOKOBANv2.jar
MIDlet-Name: SOKOBANv2
MIDlet-Vendor: ELJONTO
MIDlet-Version: 2.0
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-2.0
Wrapping up parts of a J2ME application, you have the main entry class that inherits MIDlet and overrides all abstract methods, and then you have the other application classes who can transfer display focus between them if they are subclasses of Displayable.
DRAWING AND GRAPHICS
MIDlet’s have control over the screen through an object of Display. Each MIDlet can have only one Display object, and it is a superclass for Displayable. Display is used to represent the hardware for the display, whereas Displayable is used as a means of physically displaying something on the screen. Although there can be only one Display object for each MIDlet, there can be many objects of Displayable (because Displayable inherits Display, and all UI classes are beneath Displayable on the UI hierarchy, see Display Hierarchy in ADDITIONAL). This means, that every UI component, be it high level or low level inherits Displayable, and thus can be draw onto the device screen.
There exist two types of UI’s in J2ME, high level and low level. There are two direct subclasses of Displayable, Screen and Canvas. Screen is for high-level UI, and Canvas is for low-level UI. The difference between these is that Screen gives you access to pre-defined controls, such as text boxes, text fields- like the basic ones found in the Java SE awt packages. This gives you easy access to very powerful controls and UI components / elements which are very compatible with a large range of different devices. You can’t, however, draw directly to the screen. This is very limiting for most applications, especially games- where you need direct access to the screen to draw shapes etc. The ability to draw directly to the screen is done through the low-level UI classes of Canvas and Graphics. Canvas is an abstract class, where you need to overwrite the paint method. The paint method in your Canvas class is defined as follows:
CODE :
public void paint(Graphics g){}
This can be used in very much the same fashion as the paint method used in Java Applets, and through the Graphics object you can draw directly onto the screen of the device. There is also a subclass of Canvas called GameCanvas. This is like the regular Canvas class, but has been tweaked a bit for game development. It too, operates at a low level when it comes to drawing and graphics. The GameCanvas class will be discussed in a later article. The default origin (0,0) when drawing to the screen is at the top left of the device screen. Some drawing methods in Graphics take an integer alignment as a parameter (e.g drawString(), drawImage()). The options you have are:
Graphics.LEFT,
Graphics.RIGHT,
Graphics.TOP,
Graphics.BOTTOM,
Graphics.HCENTER,
Graphics.VCENTER,
Graphics.BASELINE.
These are OR’d together to give the alignment position of what you want to draw. I.e., to specify an image should be drawn in the middle of the screen, in the middle of the image:
CODE :
//g is an object of Graphics
g.drawImage(image, this.getWidth()/2, this.getHeight()/2, Graphics.HCENTER | Graphics.VCENTER);
If you’ve ever programmed a Java Applet before (Very unlikely that you haven’t if you’re reading this), then you’ll know that mixing the controls (text fields, text areas, buttons, etc) in the awt packages and drawing directly to the Applet from the paint method work together without any problems. In J2ME development, this is not the case. High-level UI and Low-level UI can’t mix, different ‘screens’ in your application can use different UI levels, but display must be transferred between them, it can’t be on both levels at the same time.
FILE HANDLING:
There are two types of data / file handling in J2ME, the first is like regular data / file handling on your computer, where you open a path, browse directories etc. This is done with the FileConnection API. A large part of Java development is security, therefore, having any application being able to read / write data / files natively on the device would be a huge security risk. This is where problems arise, unless your application is trusted, this type of file handling might request a response from the user every time it tries to read / write data to the file system, and some phone models might not allow it at all. These restrictions are unnecessary if all you want your program to do is save some options, game highs scores, unlocked levels etc. This brings us to the second type of file / data handling, persistent, through the RMS (Record Management Store) API. The RMS reads / writes data through a file / database crossover. Each MIDlet can have any number of RecordStores, and in MIDP version 2.0 MIDlet’s can access other MIDlet’s RecordStores (not discussed in this overview). All data inside the RecordStores are saved as Records, every Record is an array of bytes, and each record has an integer identifier. The RecordStores are protected from corruption by features like automatic synchronization etc, however it is still up to you to control access to the RecordStores in your application. This article will only detail using the RMS method of data / file handling because in most situations, the MIDlet needs to be signed to use the FileConnection API, or be installed in a trusted environment.
PROGRAM ACTION AND INTERACTION
Here I’ll explain how do to the various things in your J2ME application, such as drawing, handling events etc, and in SAMPLE PROGRAMS you can see these concepts as completed demo applications, with complete source code. I am not going to explain every member method for everything I describe here, some are self-explanatory, some you might need to look up, but this section is not a complete reference.
== Catching Keys:
Listening and catching keys (Not commands) in J2ME is done through the low-level UI classes of Canvas or GameCanvas, via the methods:
CODE :
protected void keyPressed(int keyCode){}
protected void keyReleased(int keyCode){}
Where keyCode is the code of the key that has been pressed / released. Key Catching in high-level UI is either handled automatically by the control, or done by catching the softkeys (More on softkeys in next subsection).
If you are creating your own low-level UI controls (e.g. a custom text field) that uses user input via the keypad, the keyCode for keys 0-9 will be the ASCII equivalents (48 - 57) so casting to char ((char)keyCode) will give you the number pressed. The other, non-keypad buttons have a negative keyCode, some of these values can be found here: http://www.j2meforums.com/wiki/index.php/Canvas_Keycodes .
If the Canvas that’s catching keys is being used for a game, using keyCode directly can be annoying, so instead we can use the method getGameAction(), and then choose from the list of statics in javax.microedition.lcdui.Canvas;
Example:
CODE :
//Without using getGameAction()
protected void keyPressed(int keyCode){
if(keyCode == -1){
//Up Pressed
}else if(keyCode == -2){
//Down Pressed
}else if(keyCode == -3){
//Left Pressed
}else if(keyCode == -4){
//Right Pressed
}
}
//Using getGameAction()
protected void keyPressed(int keyCode){
int gameAction = getGameAction(keyCode);
if(gameAction == UP){
//Up Pressed
}else if(gameAction == DOWN){
//Down Pressed
}else if(gameAction == LEFT){
//Left Pressed
}else if(gameAction == RIGHT){
//Right Pressed
}
}
The statics in javax.microedition.lcdui.Canvas that you can use are:
DOWN, FIRE, GAME_A, GAME_B, GAME_C, GAME_D, KEY_NUM0, KEY_NUM1, KEY_NUM2, KEY_NUM3, KEY_NUM4, KEY_NUM5, KEY_NUM6, KEY_NUM7, KEY_NUM8, KEY_NUM9, KEY_POUND, KEY_STAR, LEFT, RIGHT, UP
== Using CommandListener and Soft Keys
Soft Keys are the keys that aren’t part of the numpad, they’re usually situated above the numpad, but underneath the screen (on a typical mobile phone). They are keys such as the navigation joystick, the answer call / hang-up call/ select button etc. You may have noticed that it’s impossible in most case to get control of these for use in your application through the low-level UI key catching methods. There’s a reason for this, these are Command buttons. The other buttons, such as a 0 on the numpad, will always be and represent a 0 on the numpad (in this example). These Command buttons, however, can represent anything you want, from an Exit button, to a Select button, an Options button etc. Another reason is that these must be available to both high and low level UI implementations, and the keyPressed() and keyReleased() methods are a part of Canvas, low level UI.
To make use of these keys, you need to implement the interface CommandListener, and control the actions through:
CODE :
public void commandAction(Command c, Displayable d){}
Where “Command c” is the activated command and “Displayable d” is the Displayable object that activated the command. The class that implements CommandListener and hence has the method commandAction() can control the commands of any Displayable object as long the commandListener for the said object is set to the class implement CommandAction. This means that it is possible to have only one class implementing CommandListener, which controls all commands of all Displayable objects (Canvas, GameCanvas, Form, List etc).
To catch softkeys, you need to create a Command object for each command you want, add the Command objects to the displayable object you want the commands on, and set the commandListener of the displayable object to a CommandListener implementation that has the commandAction() method.
An example of usage, complete code will be in SAMPLE PROGRAMS section:
CODE :
private MyCanvasClass mycanvas;
private Command exitCmd;
…
display = Display.getDisplay(this);
mycanvas = new MyCanvasClass();
exitCmd = new Command(“exit”, Command.EXIT, 0);
…
mycanvas.addCommand(exitCmd);
mycanvas.setCommandListener(this);
display.setCurrent(mycanvas);
…
public void commandAction(Command c, Displayable d){
if(c == exitCmd){
exit();
}
}
The Command constructor takes three parameters, the first being a label, String with the text the command will show. The second being a type, one of:
Command.BACK
Command.CANCEL
Command.EXIT
Command.HELP
Command.ITEM
Command.OK
Command.SCREEN
Command.STOP
The third parameter taken is an Integer priority. The Type and Priority parameters are how you can tell your device which commands should be assigned to what soft keys. For example on my current phone, the Nokia 6300, the command with the highest priority gets assigned to the center soft key, and commands of type Command.EXIT get assigned to the left soft key at the bottom of the screen. If there are more commands than soft keys available, a pop-up menu is automatically created on one of the soft keys, allowing the user to choose the other commands. Note that the command / soft key assignment is different on different devices.
== Predefined Controls and High Level UI Elements
Just like there exist UI controls for you to use in the java applet awt packages, there also exist similar controls in the J2ME lcdui packages. These UI controls are High level UI, because they are below the Screen class on the Display hierarchy (Display Hierarchy in ADDITIONAL), and cannot be mixed with low level UI access, as I mentioned earlier. Because these controls are High-level UI, you have very limited access when it comes to displaying them. This makes them very portable and a good option for creating an interface for the user to input data, but a bad option for game development, or any application where you’d like to have full control over the screen and appearances.
On the High-Level UI hierarchy directly underneath Screen are the classes Alert, List, TextBox and Form. All of these use the whole display. The ‘Ticker’ control, however, isn’t a control; it’s a variable in the Screen class.
-Alert
An Alert is essentially a very simple dialog box. It can have text, pictures and a sound warning. Alerts can either run until the user acknowledges it, or it can run for a pre-determined amount of time. When an alert finishes it will return focus to the last Displayable object that held focus (I.E. the Displayable object that ‘called’ it). However, if you want to transfer focus to a different displayable object when the alert finishes, add the other Displayable object as a parameter to setCurrent(); like so:
CODE :
display.setCurrent(alert, newdisplayableobject);
Creating a new Alert object:
CODE :
Alert alert = new Alert("Alert Title Text", "Alert body text", alertImage, alertType);
alertType is a static from the AlertType class, it is a sound for the alert and can be: AlertType.ALARM, AlertType.CONFIRMATION, AlertType.ERROR, AlertType.INFO, AlertType.WARNING.
The setTimeout method will set the amount of time in milliseconds that the alert will stay active.
CODE :
alert.setTimeout(2000); //2 seconds
If you want the alert to remain until the user acknowledges it, use the static FOREVER
CODE :
alert.setTimeout(Alert.FOREVER);
If an Alert is set to Alert.FOREVER and you don’t add any commands and don’t set a commandListener onto an Alert object, it will have a ‘done’ option by default, however if you do, you will need to define all commands.
-List
A list can present a series of choices, accompanied with images, for the user to choose (I.E. a menu). A List can be MULTIPLE / EXCLUSIVE, making it effectively a full-screen ChoiceGroup (discussed later), but benefits most as a menu if it is IMPLICIT.
Creating a list object:
CODE :
List list = new List(“List Title”, List.IMPLICIT, listOptions, listImages);
Where listOptions is a String array containing menu options and listImages is an Image array containing Images corresponding to the options.
If you don’t want to include any images, set the parameter to null.
To find out which option(s) are selected you can use:
CODE :
list.getSelectedIndex();
However, if you are using an IMPLICIT list, and have set a command listener onto it you can use this in your commandAction() method:
CODE :
public void commandAction(Command c, Displayable d){
if(c == List.SELECT_COMMAND){
switch(list.getSelectedIndex()){
case n:
//etc
break;
default:
break;
}
}
}
-TextBox
A TextBox is a multi-line control which allows users to enter text.
Create a TextBox object:
CODE :
TextBox txtBox = new TextBox(“TextBox title”, “Text inside of textbox”, charlimit, restrictions);
Where ‘charlimit’ is an integer which defines the max amount of characters that can be entered, and ‘restrictions’ is a static int from the TextField class, which defines the type of text that can be entered. The Options are: ANY, NUMERIC, PASSWORD, PHONENUMBER, EMAILADDR, and URL.
Use the OR operator to combine these:
CODE :
TextField.EMAILADDR | TextField.PASSWORD
This would only accept a valid email address and it would mask the input like a password field.
*Note: If you are having text inside of a TextBox, make sure it doesn’t exceed the charlimit you set; otherwise an IllegalArgumentException will be thrown.
-Ticker
A Ticker is a little banner of scrolling text (like HTML marquee, you know, the scrolling text that you see advertising stuff on crappy websites) at the top of a direct descendant of Screen (Alert, TextBox, List, and Form). Ticker is not a child of Screen; it is a variable, which is why it can be displayed on Screen children.
Create a new Ticker object:
CODE :
Ticker tckr = new Ticker("A ticker, not a control- a variable of Screen");
To add a Ticker object to a direct Screen child use the method:
CODE :
screenchild.setTicker(tickerobject);
-Form
A Form is a direct child of Screen that can hold all typical UI controls. These controls are of superclass Item (ChoiceGroup, CustomItem, DateField, Gauge, ImageItem, Spacer, StringItem, and TextField) see the Display Hierarchy in ADDITIONAL. Like the other direct children of Screen, Form uses the whole display, but unlike the others (except List) it will scroll to accommodate the Item’s it houses. A Form is arranged in “rows”, and it will try to put as many controls as it can onto each row. With small-screened devices, usually only one control fits per row. If your device can fit more than one control per row, to tidy up the layout you can use Spacers (discussed later) and the layout options in Item.
Create a form object:
CODE :
Form frm = new Form(“Form Title”);
Once you have created a form object, you add Item’s onto it using the append method
CODE :
frm.append(item);
[code]
Every Item on a form can have a layout, set with the method:
[code]
setLayout(int layout);
where layout can be:
Item.LAYOUT_2, Item.LAYOUT_BOTTOM, Item.LAYOUT_CENTER, Item.LAYOUT_DEFAULT, Item.LAYOUT_EXPAND, Item.LAYOUT_LEFT, Item.LAYOUT_NEWLINE_AFTER, Item.LAYOUT_NEWLINE_BEFORE, LAYOUT_RIGHT, Item.LAYOUT_SHRINK, Item.LAYOUT_TOP, Item.LAYOUT_VCENTER, Item.LAYOUT_VEXPAND, Item.LAYOUT_VSHRINK.
Since Form is Displayable, it too can have commands, command listeners etc
Following are descriptions of the controls that can appear on a form:
-ChoiceGroup
The ChoiceGroup control is like a list, it presents the user with a selection to choose from. There are two types of ChoiceGroup, multiple-selection (checkbox) and exclusive-selection (radio-group).
Create a ChoiceGroup object:
CODE :
ChoiceGroup cg = new ChoiceGroup(“ChoiceGroup title”, type);
Or create a ChoiceGroup object with options / images:
CODE :
ChoiceGroup cg = new ChoiceGroup(“ChoiceGroup title”, type, options, images);
Where type is either ChoiceGroup.MULTIPLE or ChoiceGroup.EXCLUSIVE, options is a String array containing the choices and images are the corresponding images to accompany the choices. Use null for the image parameter if you aren’t having any images.
To add an option to your ChoiceGroup object:
CODE :
cg.append(“option”, image);
Where image is the accompanying image, otherwise use null.
To get the selected options you can use:
CODE :
getSelectedIndex();
Or to return a boolean array of the selected / unselected:
CODE :
getSelectedFlags(returnArray);
Where returnArray is a boolean array.
-CustomItem
A CustomItem lets you define your own Item to place on a form. To create a new CustomItem, create a class for your control, have it extend CustomItem. The CustomItem constructor requires a String title, and since it’s abstract you need to use a few methods. This leaves the shell of a CustomItem subclass looking like:
CODE :
class MyItem extends CustomItem
{
public MyItem(String title){
super(title);
}
protected int getMinContentHeight() {}
protected int getMinContentWidth() {}
protected int getPrefContentHeight(int width) {}
protected int getPrefContentWidth(int height) {}
protected void paint(Graphics g, int w, int h) {}
}
If we were to finish our MyItem (This will be covered in a later article), using it would be the same as the other Items:
CODE :
MyItem myItem = new MyItem(“My Custom Item”);
form.append(myItem);
-DateField
A DateField Item lets you view / change the date and time.
Creating a DateField object:
CODE :
DateField df = new DateField(“Title”, type);
DateField df = new DateField(“Title”, type, timezone);
Where type is either DateField.DATE, DateField.TIME, DateField.DATE_TIME, allowing the user to edit the date, the time, or both (respectively). The timezone parameter is an object of TimeZone.
You can set / get the date using:
CODE :
df.setDate(date);
Date date = df.getDate();
Where Date is defined in the java.util package.
-Gauge
A gauge is meter that displays the progress of something. It’s typically used to show the volume level when adjusting, however if can be used for whatever you want. You can have an interactive gauge (I.E. volume control), or a non-interactive gauge where the application itself must change the value.
Creating a gauge object:
CODE :
Gauge gauge = new Gauge(“Title”, interactive, maxvalue, startvalue);
Where interactive is a boolean, true: interactive, false: non interactive, maxvalue is an integer for the maximum value of the gauge and startvalue is the value the gauge should start at.
To get / set the value of a Gauge object:
CODE :
gauge.setValue(integervalue);
int value = gauge.getValue();
-ImageItem
An ImageItem lets you put an image onto a form.
Create and ImageItem object:
CODE :
ImageItem imageItem = new ImageItem(“Title”, image, layout, “Alt text”);
Where image is an object of type Image, layout is any of the LAYOUT statics in Item (mentioned above in –Form section).
You can create an Image Object using Image.createImage(). This method is overridden quite a few times, but the easiest way takes only a String path to an image file:
CODE :
Image.createImage(String imagePath);
-Spacer
A Spacer is simply a section of white space that you can size accordingly and use to put some extra ‘space’ into your form to help with layout.
Create a Spacer object:
CODE :
Spacer spcr = new Spacer(horizPadding, vertPadding);
Where horizPadding is an integer value for the horizontal white space and vertPadding is an integer value for the vertical white space.
Simply append the Spacer object to the form wherever you want the white space.
-StringItem
A StringItem is simply a label control to put text onto a form.
Create a StringItem object:
CODE :
StringItem str = new StringItem(“Title”, “Your Text”);
Alternatively, you can add text onto a form by simply appending a String:
CODE :
form.append(“Text to put on form”);
The reason there exists a StringItem class when you can use the above method is so that you can get / set the text etc.
CODE :
String recvStr = str.getText();
Str.setText(“New Text”);
-TextField
A TextField is a single-line TextBox control, which allows the user to enter the type of text allowed. TextBox shares the same text restrictions as TextField, which are: TextField.ANY, TextField.NUMERIC, TextField.PASSWORD, TextField.PHONENUMBER, TextField.EMAILADDR, and TextField.URL. Look up the TextBox section for more on using these restrictions.
Create a TextField object:
CODE :
TextField txt = new TextField(“Title”, “Text in box”, charlimit, restrictions);
Where charlimit is an integer to represent the max allowed characters (make sure if you have text inside the text field on initialisation that it doesn’t exceed the limit) and restrictions is an integer for a static restriction from the TextField class (discussed above).
== Using ItemStateListener
Where CommandListener is triggered on interaction with commands, ItemStateListener is triggered on interaction with controls. Using ItemStateListener is very similar to using CommandListener (discussed earlier). The class that’s going to listen for state changes will need to implement ItemStateListener, and then override the method:
CODE :
public void itemStateChanged(Item i){}
To set up a Displayable object to listen for state changes, use the method:
CODE :
displayableObj.setItemStateListener(listener);
where listener is the class that implements ItemStateListener, and hence has the itemStateChanged() method.
An example of usage is shown in SAMPLE PROGRAMS.
== Multithreading
There’s nothing special to multithreading in J2ME development, it can be used by inheriting Thread or implementing Runnable. J2ME classes that serve a UI purpose usually inherit a class (Canvas, GameCanvas etc) so it’s generally easier to use the implementation method. Multithreading should be used as little as possible in this type of development, bearing in mind the type of processor the destined device has. Obviously there are some situations where it’s absolutely necessary, such as updating a game screen, but it’s important to not go overboard. To limit multithreading in your J2ME application, you may need to reorganise your code a bit, so that you end up having one class with multithreaded support, updating the activities of the other classes that would have normally been multithreaded. In many situations this might not be preferable, but just try to use it as little as possible.
== RMS File Handling
See FILE HANDLING for an explanation of RMS.
The import:
CODE :
import javax.microedition.rms.*;
Create / Open a RecordStore:
CODE :
RecordStore recStore = RecordStore.openRecordStore(name, createIfDoesntExist);
Where name is the String name of the RecordStore and createIfDoesntExist is a boolean variable, true to create the RecordStore if it doesn’t exist, if it does exist, the RecordStore will be opened. False to not create the RecordStore if it doesn’t exist, if it does exist, the RecordStore will be opened.
Delete a RecordStore:
CODE :
RecordStore.deleteRecordStore(name);
Where name is the String name of the RecordStore to delete.
Close a RecordStore:
CODE :
recStore.closeRecordStore();
Add a Record:
CODE :
recStore.addRecord(data, offset, bytesAmount);
Where data is a byte array, offset is where you want to start writing to in the Record and bytesAmount is the number of bytes from data you want written. The addRecord() method returns the ID of the record you added.
Set / Overwrite a Record:
CODE :
recStore.setRecord(recID, data, offset, bytesAmount);
Same as the addRecord() method, only you need to include the recID parameter, which is the integer ID of the Record you want to overwrite.
Delete a Record:
CODE :
recStore.deleteRecord(recID);
Where recID is the integer ID of the Record you want to delete.
Get a Record:
CODE :
byte[] data = recStore.getRecord(recID);
//OR
recStore.getRecord(recID, data, offset);
Where recID is the Integer ID of the Record you want, data is a byte[] array to hold the bytes and offset is an Integer offset to say where to start reading from.
SAMPLE PROGRAMS:
Here are three, ready-to-compile and run J2ME applications, that use most of what is described or presented in this article. The first will display the High-Level UI, some controls, and using the Listeners, the second- the Low Level UI with Multithreading and the last, the RMS file handling / database emulating system. When I say ‘application’, I am not referring to something built to solve a problem, hell, or even be useful- these are just a compilation of some of the things shown here so you can see them work, and to give you an idea of how to implement them.
== High Level UI, CommandListener, ItemStateListener
CODE :
//File: DemoMIDlet.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class DemoMIDlet extends MIDlet implements CommandListener{
private Display display;
private ListDemo listDemo;
private TextBoxDemo textBoxDemo;
private FormDemo formDemo;
private AlertDemo alertDemo;
private Command exitCmd, menuCmd;
public DemoMIDlet(){
display = Display.getDisplay(this);
listDemo = new ListDemo("A List Menu", List.IMPLICIT, new String[]{"TextBox", "Form", "Alert"}, null);
textBoxDemo = new TextBoxDemo("A TextBox", "Stuff inside textBox, 500 char limit, ANY text", 500, TextField.ANY);
formDemo = new FormDemo("A Form");
alertDemo = new AlertDemo("An INFO Alert", "Alert content", null, AlertType.INFO);
exitCmd = new Command("Exit", Command.EXIT, 0);
menuCmd = new Command("Menu", Command.BACK, 1);
}
public void startApp() {
listDemo.addCommand(exitCmd);
listDemo.setCommandListener(this);
textBoxDemo.addCommand(exitCmd);
textBoxDemo.addCommand(menuCmd);
textBoxDemo.setCommandListener(this);
formDemo.addCommand(exitCmd);
formDemo.addCommand(menuCmd);
formDemo.setCommandListener(this);
display.setCurrent(listDemo);
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
private void exit() {
System.gc();
destroyApp(false);
notifyDestroyed();
}
public void commandAction(Command c, Displayable d){
if(c == exitCmd){
exit();
}else if(c == menuCmd){
display.setCurrent(listDemo);
}else if(c == List.SELECT_COMMAND && d == listDemo){
switch(listDemo.getSelectedIndex()){
case 0:
display.setCurrent(textBoxDemo);
break;
case 1:
display.setCurrent(formDemo);
break;
case 2:
display.setCurrent(alertDemo);
break;
default:
break;
}
}
}
}
CODE :
//File: ListDemo.java
import javax.microedition.lcdui.*;
public class ListDemo extends List
{
public ListDemo(String title, int TYPE, String[] options, Image[] images){
super(title, TYPE, options, images);
}
}
CODE :
//File: TextBoxDemo.java
import javax.microedition.lcdui.*;
public class TextBoxDemo extends TextBox
{
public TextBoxDemo(String title, String content, int MAXSIZE, int TYPE){
super(title, content, MAXSIZE, TYPE);
}
}
CODE :
//File: FormDemo.java
/*
* Make sure you comment out the ImageItem parts if you don’t supply an image
*/
import java.io.IOException;
import javax.microedition.lcdui.*;
public class FormDemo extends Form implements ItemStateListener
{
private Ticker tckr;
private DateField df;
private StringItem str;
private Gauge gauge;
private Spacer spcr;
private TextField txt;
private ChoiceGroup cg;
private ImageItem imgItem;
public FormDemo(String title){
super(title);
tckr = new Ticker("A ticker, not a control- part of Screen");
df = new DateField("A Date Field control", DateField.DATE_TIME);
str = new StringItem("stritem", "TEXT");
gauge = new Gauge("Volume Gauge", true, 10, 6);
try{
imgItem = new ImageItem("An Image", Image.createImage("/image.png"), ImageItem.LAYOUT_DEFAULT, "Alternate text");
}catch(IOException e){}
spcr = new Spacer(0,40);
txt = new TextField("TextField", "Enter Text", 20, TextField.ANY);
cg = new ChoiceGroup("ChoiceGroup", ChoiceGroup.MULTIPLE);
cg.append("Choice 1", null);
cg.append("Choice 2", null);
this.setTicker(tckr);
this.append(df);
this.append(str);
this.append("String Message 2!");
this.append(spcr);
this.append(gauge);
this.append(txt);
this.append(cg);
this.append(imgItem);
this.setItemStateListener(this);
}
public void itemStateChanged(Item i){
str.setText(i.getLabel()+" has changed");
}
}
CODE :
//File: AlertDemo.java
import javax.microedition.lcdui.*;
public class AlertDemo extends Alert
{
public AlertDemo(String title, String content, Image image, AlertType TYPE){
super(title, content, image, TYPE);
}
}
== Canvas / Multithreading
CODE :
//File: DemoMIDlet.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class DemoMIDlet extends MIDlet implements CommandListener{
private Display display;
private CanvasDemo canvas;
private Command exitCmd;
public DemoMIDlet(){
display = Display.getDisplay(this);
canvas = new CanvasDemo();
exitCmd = new Command("Exit", Command.EXIT, 0);
}
public void startApp() {
canvas.addCommand(exitCmd);
canvas.setCommandListener(this);
display.setCurrent(canvas);
}
public void pauseApp() { }
public void destroyApp(boolean unconditional) {
}
private void exit() {
System.gc();
destroyApp(false);
notifyDestroyed();
}
public void commandAction(Command c, Displayable d){
if(c == exitCmd){
exit();
}
}
}
CODE :
//File: CanvasDemo.java
import java.io.IOException;
import javax.microedition.lcdui.*;
public class CanvasDemo extends Canvas implements Runnable{
private Thread MainThread;
private long sleep = 50;
private boolean run = true;
private String keyAction = "Key";
private Image img;
private int[] moveShapeLoc = {
this.getWidth()/10,
this.getWidth()/4,
this.getHeight()/8
};
private int[] autoShapeDim = {
this.getWidth()/2,
this.getHeight()/2,
this.getWidth()/10,
this.getHeight()/10,
};
private int direction;
private static int DIRECTIONLEFT = 0;
private static int DIRECTIONRIGHT = 1;
public CanvasDemo(){
MainThread = new Thread(this);
try{
img = Image.createImage("/image.png");
}catch(IOException e){}
direction = DIRECTIONRIGHT;
MainThread.start();
}
public void run(){
while(run){
autoShape();
repaint();
try{
Thread.sleep(sleep);
}catch(InterruptedException e){}
}
}
protected void keyPressed(int keyCode){
int gameAction = getGameAction(keyCode);
keyAction = "Key Down: (int)"+keyCode;
if(gameAction == LEFT){
moveShape(-4, 0);
}else if(gameAction == RIGHT){
moveShape(4, 0);
}else if(gameAction == UP){
moveShape(0, -4);
}else if(gameAction == DOWN){
moveShape(0, 4);
}
}
protected void keyReleased(int keyCode){
int gameAction = getGameAction(keyCode);
keyAction = "Key Up: (int)"+keyCode;
}
private void moveShape(int hspeed, int vspeed){
moveShapeLoc[1] += hspeed;
moveShapeLoc[2] += vspeed;
}
private void autoShape(){
if(direction == DIRECTIONLEFT){
if(autoShapeDim[0] > 0){
autoShapeDim[0]--;
}else{
direction++;
}
}else{
if(autoShapeDim[0] + autoShapeDim[2] < this.getWidth()){ autoShapeDim[0]++; }else{ direction--; } } } public void paint(Graphics g){ g.setColor(0xFFFFFF); g.fillRect(0, 0, this.getWidth(), this.getHeight()); g.setColor(0x000000); g.drawString("CanvasDemo", 1, 1, Graphics.LEFT | Graphics.TOP); g.drawString(keyAction, 1, 20, Graphics.LEFT | Graphics.TOP); g.fillRect(autoShapeDim[0], autoShapeDim[1],autoShapeDim[2],autoShapeDim[3]); g.setColor(0xFF0000); g.drawArc(moveShapeLoc[1], moveShapeLoc[2], moveShapeLoc[0]*2, moveShapeLoc[0]*2, 0, 360); g.drawImage(img, this.getWidth()/2, this.getHeight()/2, Graphics.HCENTER | Graphics.VCENTER); } } == RMS CODE : //File: RMSDemoMIDlet.java import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import javax.microedition.rms.*; public class RMSDemoMIDlet extends MIDlet implements CommandListener{ private Display display; private Form form; private StringItem progress; private Command exitCmd; public RMSDemoMIDlet(){ display = Display.getDisplay(this); form = new Form("RMS Demo"); progress = new StringItem("Progress:", ""); exitCmd = new Command("Exit", Command.EXIT, 0); } public void startApp() { form.append(progress); form.addCommand(exitCmd); form.setCommandListener(this); rmsDemo(); display.setCurrent(form); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } private void exit(){ System.gc(); destroyApp(false); notifyDestroyed(); } public void commandAction(Command c, Displayable d){ if(c == exitCmd){ exit(); } } private void rmsDemo(){ progress.setText(progress.getText() + "\n>>Attempting to create RecordStore 'RecStore'");
RecordStore rs = null;
try{
rs = RecordStore.openRecordStore("RecStore", true);
progress.setText(progress.getText() + "\n>>Created RecordStore");
progress.setText(progress.getText() + "\n>>Attempting to add records");
String[] records = {
"The first record",
"The second record",
"The third record",
"The fourth record",
};
for(int i = 0; i < records.length; i++){ rs.addRecord(records[i].getBytes(), 0, records[i].length()); } progress.setText(progress.getText() + "\n>>Added records");
progress.setText(progress.getText() + "\n>>Attempting to read records: ");
for(int i = 1; i <= rs.getNumRecords(); i++){ progress.setText(progress.getText() + "\n"); for(int j = 0; j < rs.getRecord(i).length; j++){ progress.setText(progress.getText() + (char)(rs.getRecord(i)[j])); } } progress.setText(progress.getText() + "\n"); progress.setText(progress.getText() + "\n>>Attempting to edit records");
for(int i = 1; i <= rs.getNumRecords(); i++){ String newData = records[i-1]+" edited"; rs.setRecord(i, newData.getBytes(), 0, newData.length()); } progress.setText(progress.getText() + "\n>>Attempting to read new records: ");
for(int i = 1; i <= rs.getNumRecords(); i++){ progress.setText(progress.getText() + "\n"); for(int j = 0; j < rs.getRecord(i).length; j++){ progress.setText(progress.getText() + (char)(rs.getRecord(i)[j])); } } progress.setText(progress.getText() + "\n"); progress.setText(progress.getText() + "\n>>Attempting to delete records");
for(int i = 1; i <= rs.getNumRecords(); i++){ rs.deleteRecord(i); } progress.setText(progress.getText() + "\n>>Deleted records");
progress.setText(progress.getText() + "\n>>Attempting to close RecordStore 'RecStore'");
rs.closeRecordStore();
progress.setText(progress.getText() + "\n>>RecordStore closed");
progress.setText(progress.getText() + "\n>>Attempting to delete RecordStore 'RecStore'");
RecordStore.deleteRecordStore("RecStore");
progress.setText(progress.getText() + "\n>>RecordStore deleted");
}catch(RecordStoreException e){
progress.setText(progress.getText() + "\n>>Fail: "+e.getMessage());
}
}
}
ADDITIONAL
==Display Hierarchy:
Display
|
Displayable
| |
| Canvas
|
Screen
|
Form, List, Alert, TextBox
|
Item
|
ChoiceGroup, CustomItem, DateField, Gauge, ImageItem, Spacer, StringItem, TextField
OUTRO:
Well, that concludes my basic overview on coding with J2ME with the focus on mobile phone application development. I hope that you have found this useful, and all feedback (comments / suggestions / corrections) is very welcome. Feel free to contact me (eljonto {AT} live {DOT} com) if you have any questions, I’ll do my best to answer them. If I get around to writing more articles on J2ME, it will cover more areas, and revisit areas in depth (Such as Canvas, GameCanvas, etc), as this overview isn’t very comprehensive in many areas, if it was- it wouldn’t be a basic overview.
Hash Collisions and the Birthday Attack
Introduction
Last time, I talked about brute force attacks and how efforts to reduce the keyspace of a given algorithm can greatly reduce your computational time (link). This article will discuss hash collisions and the probability of collisions occuring via the birthday paradox. Though this doesnt inherently provide you with any more tools or methods in terms of cracking hashes, it does provide the theory behind generating hash collisions which can severely compromise the security of an algorithm.
Hash Collisions
To quickly review, cryptographic hash functions work by taking in a string (i.e., your password), performing some mathematical operations on it, and spitting out hexadecimal garbage that is utterly uninformative to anyone. If the algorithm is well-designed, the mathematical operations will be one-way; that is, it is either impossible or so computationally impractical to take a hash and run it backwards through the algorithm to regurgitate the original string. The easiest way to get your desired password is to match the hash by testing every possible password and seeing if the hashes match, otherwise known as brute-forcing. Unfortunately, this can take a long time and there are more efficient means at our disposal.
One method is to try and get the algorithm to generate what is known as a "hash collision". From the previous article, we showed that using the hashing algorithm from ExtBasic 11, passwords containing the same set of letters would always generate the same hash, regardless of what order the letters were in ("aab" was the same as "aba" was the same as "baa"). This is a hash collision, two or more separate strings creating an identical hash. Since real-world algorithms do not use such simplistic methods, collisions do not occur so easily, but they do occur. In fact, we know that they must occur!
Take the MD5 algorithm, for example. For every password that is entered, the algorithm will always return a hash that is 128-bits long, or a string of 32 hexadecimal characters. From that, we know that there are a finite number of hashes that can be generated, but the number of passwords entered can be infinite. To put this into perspective, there are 94 characters on a normal keyboard (52 capital and lower-case letters, 10 numbers, and 32 assorted symbols; as far as I know, there are no illegal characters in the MD5 algorithm). Assuming a password length of 20, we use our permutation equation from before:
CODE :
n^k = 16^32 = 2^128 = 3.4e38 possible hashes
94^20 = 2.9e39 possible passwords
So from this, we know that if we try every possible password with 20 characters or more, eventually we will generate a hash collision!
However, this is not really good news. To test every password at a speed of 6 million hashes per second (my laptops average hashing speed) would take 1.5e25 years, orders of magnitude longer than any timespan our brains could possibly conceive. Additionally, since we have to store each hash we compute so that we can check it against future ones and knowing each hash occupies 16 bytes, that means we would have to have so many 2TB HDD that if they were laid out in a grid, they would cover the entire Earths surface 1,100 miles deep. So what to do? Luckily, probability is on our side.
The Birthday Paradox
If you have ever taken a statistics and probability class, you have probably learned about the birthday paradox. It goes something like this: Take a room of 50 people. What are the odds that at least two people will have the same birthday?
Thinking about this quickly, there are 365 days in year (Leap year births not counted; they arent real people anyway), 50 people, so maybe 1 in 6, or about 17%? Wrong. In reality, the probability is a whopping 97%! This unbelievably high, surely there must be a mistake! Well, lets look at the math.
In a room of 50 people, were trying to match two birthdays. So taking any one birthday, there are 49 possible matches to be made. However, if we compare every birthday to every other birthday, our number of possible matches greatly increases and we can use our friend, the combination without replacement equation:
CODE :
50!
---------- = 1,225 combinations
2! (50-2)!
So to think about what this problem is asking in another way, if we had 2,450 people and we paired them off randomly with each other, what are the odds that a person would have the same birthday as the person he was paired with? With 1,225 pairs, now it doesnt seem so far fetched that theres a 97% chance there will be a match.
But how does this apply to hash collisions? Well, since we are simply trying to find to passwords with the same hash ("birthday") it turns out we dont have to calculate the heinous number of passwords we originally thought. The birthday paradox simplifies down to the following equation:
CODE :
k!
------------- = P
(k^n)(k - n)!
Where "k" is the maximum number of items were trying to match (birthdays, in the example), "n" is our sample space (number of people), and "P" is the probability of finding a match. Since factorial calculations rapidly exceed the allowable size of most calculators, the Taylor Series approximation is also useful (for those of us struggling to remember algebra, "e" is th exponential constant and is approximately 2.718):
CODE :
P = 1 - e^(-(n^2)/(2*k))
Solving for n:
n = sqrt(ln(1 - P)*-2*k)
Our "k" is determined by the maximum number of hashes for the algorithm, 3.4e38 as mentioned above. Alright, weve got our equation, now we just need to plug and chug. Since k is fixed, we just need to figure out what is an acceptable probability. I think 99% gives us pretty good odds, so well use P = 0.99. Plugging it into our equation, we discover that we only need to calculate 5.98e19 hashes for a 99% chance of generating a hash collision,less than one trillionth of a percent of our original keyspace. Note that this still presents a formidable logistic challenge, but the computing power is within reach for someone on a relatively modest budget; a cluster of 4 PlayStation 3s could crunch that many hashes in just over 8 months.
Conclusion
It is important to note that finding two passwords with the same hash is NOT the same as finding two passwords that will generate a specific hash. That is, if you have a specific hash, your best bet is to still go with a traditional brute force attack because the birthday problem only applies to matching ANY two passwords with the same hash, not just the one youre looking for. However, if we are able to generate a hash collision, we can start analyzing the calculations performed to generate the hash and, hopefully, figure why the collision occurred and manipulate that information to our advantage.
To that end, a distributed computing project in 2004 known as MD5CRK did that very thing and successfully found collisions within the MD5 algorithm. They were able to manipulate the algorithm and generate matching hashes with considerably less computing time than with a brute force attack. Improvements upon their work have resulted in astounding vulnerabilities in the MD5 algorithm. In 2006, a Czech cryptologist named Vlastimil Klima published an algorithm that was able to generate an MD5 hash collision, on average, in 17 seconds using a 3.4 GHz Pentium 4 (link, PDF). Despite these severe vulnerabilities, MD5 remains one of the most popular cryptographic hash functions in use.
Dynamic Memory Allocation in c
Dynamic Memory Allocation in C--------------------------
One of the big differences between a high-level scripting language and C is that all variables have to be declared at the beginning of a function in C. You cannot simply define a new variable when you need it, as you could in say, Perl or Python, or any other scripting language
for that matter. C is different; everything has to be declared at the beginning. This brings up some problems.
CODE :
#include
int main(){
int x;
printf ("Type a number: ");
scanf ("%d",&x);
printf ("You typed %d\n",x);
return 0;
}
For a simple program such as this, there's no problem. The necessity of declaring variables at the start of the program isn't a big deal. But what about when the value of one variable depends on another? An example is a program I wrote to find prime numbers, as an exercise in learning C. Here is the beginning of the the main function:
CODE :
int main() {
int maxprimes;
int count = 1;
int value = 1;
int composite;
int j;
int primes[maxprimes]; //this is the part that doesn't work.
printf ("How many primes? ");
scanf ("%d", &maxprimes);
...
I needed to set up an array, called 'primes' to hold a certain number of prime numbers, which was held in the variable 'maxprimes.' However, since I don't define maxprimes until I call scanf() later on, the size of the 'primes' array is arbitrary, just as the value of maxprimes is arbitrary. For example, if we run this code:
CODE :
#include
int main(){
int x;
printf ("%d\n",x);
return 0;
}
we get some interesting values:
CODE :
-1208182672
-1207551888
-1208387472
-1207273360
-1208219536
First of all, notice that the values are more or less random. This causes a problem simply because it will set up a random-sized array. Also, the values are negative.
So when the code is run with the array primes defined as it was above, I get a segmentation fault. How do we fix this?
The answer is called dynamic memory allocation. We use the malloc() function to allocate memory to a variable. The good thing about this is that we can do this using previously undefined variables. The beginning of the prime numbers program is now as follows:
CODE :
int main() {
int maxprimes;
int count = 1;
int value = 1;
int composite;
int j;
printf ("How many primes? ");
scanf ("%d", &maxprimes);
int *primes = malloc(maxprimes * sizeof(int));
...
There are a few things going on here. First of all, notice that the value of primes is actually a pointer. We have to dereference it with the * operator. This is because the malloc() function returns a pointer to a memory location--specifically, to the starting address of the block of memory that it allocates. Inside the parentheses, we define the size of the block we want allocated. In this case, we want maxprimes amount of blocks, and then we have to define the size. Since the variables to be stored in our memory are going to be the int type, we multiply maxprimes by the size of an integer. The sizeof() function returns the size of its argument (in bytes). Now, if maxprimes were, say, 50, we have just allocated enough memory for an array of 50 integers. This is C's way of getting around the need to declare every variable at the beginning of the program.
I said before that the malloc() function returns a pointer to a location in memory. Well, that's only if it works. If it doesn't work, you want to be notified. Mistakes in memory, especially with a language like C, can be catastrophic. At the very least, if malloc() doesn't work, your program won't work properly. So, after we allocate memory, we add this conditional statement:
CODE :
if(primes == NULL) {
fprintf(stderr, "Out of memory, exiting\n");
exit(1);
}
If the malloc() function fails, it returns a NULL pointer. So, if this happens, we simply output to stderr (the fprintf() function is simply a way to specify the filestream that it outputs to; printf() goes only to stdout) that the program is out of memory, and exit.
Another thing you always wanted to do when allocating memory for a program is to free it. Since malloc() allocates static memory, it stays allocated after the program exits, not allowing any other programs to access it. So, the end of this program looks like this:
CODE :
free (primes);
return 0;
}
The free() function takes the pointer returned by malloc() as its argument and frees any memory it had allocated to it.
There are two other allocation functions, calloc() and realloc(). The former is simply a way to fill the allocated memory with initialized data. It also works differently, in that you would say
CODE :
calloc(5, sizeof(int))
to allocate five integers. The five could also be variable.
The realloc() function is used to change the size of a memory block previously allocated with malloc(). For example, if we said
CODE :
int *primes = malloc(maxprimes * sizeof(int))
and we decided to store each value as a long int in a new array, we would say:
CODE :
int *new_primes = realloc(primes, maxprimes * sizeof(long int))
This function returns a pointer to a memory location of the newly specified size, and that new location has the same data as was in the old one, pointed to by the pointer (in this case, primes).
As a final note, to access elements of the array, one uses the syntax of *(pointer + x), where x is the number of the element you want to access. Here are a few examples:
CODE :
---------------------
| h | e | l | l | o |
---------------------
^--int *pointer
*(pointer + 0) = h
*(pointer + 3) = l
*(pointer + 5) = ? //this would give you an unpredictable value. this is known as a 'buffer overflow'
So there's dynamic memory allocation. I meant it to be an explanation of how it works to people who have programming experience in higher-level languages like Perl, Python, BASH scripting, etc.
Saturday, March 27, 2010
Top 5 Regrets After Migrating From Windows To Linux
t has been several months that I fully migrated to Linux. The whole company has moved 100% to Linux, all servers, desktop … every machine. The only traces of Windows are in two of my personal laptops, the IBM ThinkPad with Windows 2000 and the Compaq Presario with Windows XP, which I have kept for testing purposes only. My top 5 regrets after migrating to Linux are:
5. I should have bought a scanner after checking it's Linux compatibility. My UMax Astra 4100 is still not supported. I am using my Compaq Laptop to use it, which also adorns my desk and is remotely controlled from the keyboard and mouse on my Linux desktop machine.
4. Why did I spend so much on Windows software when I could get equivalent alternatives (for free) on Linux? All my Windows software are gathering dust nowadays.
3. Linux is like a Rolls Royce while Windows is like a Honda Accord. While Linux takes lots of configuration, the end result is your own operating system made to your taste. All these years I felt boxed in Windows; now I feel liberated. My only regret is why did I miss realizing this in my earlier analysis on migration.
2. It is regrettable that big brand names like Compaq or IBM would rather ship the computer with FreeDos than with Linux operating system. It appears to me their way of appeasing Microsoft; do I hear monopoly practices?
I would be happy to pay extra for well configured Linux boxes than for hardware without an OS or just FreeDos. Dell has taken the lead in providing Linux powered desktops.
1. Why didn't I migrate sooner? It pains me to see how much I missed over the years by sticking to Windows. It was bad for my business and bad for my personal productivity.
Linux, after you spend some time with it, can be a huge productivity booster. All of my developers and QA are extremely happy with it and wouldn't trade it for any other operating system. I am very much hooked to Linux.
I personally think Linux today heralds the beginning of the end for Microsoft. Linux is ready to take on Microsoft for what its worth today and now. Take the plunge today and thank me later.
Subscribe to:
Posts (Atom)










