Mobility Blogs
While Thorsten & myself wrote build instructions for the BlackBerry in the forum/mailing list in the past they are somewhat outdated by now and aren't as easy to find using Google. So here is a step by step guide on porting to the BlackBerry devices with some explanations of the Caveats.

The standard LWUIT won't work on the Blackberry since it references API's such as 184/226, notice that LWUIT doesn't need or use these API's when they are not available! On the Blackberry device the very reference to these API's will cause the application to fail. Furthermore, as I explained in a previous post, Blackberry devices have some "issues" when using classes compiled without the RIM toolchain and LWUIT isn't compiled with the RIM toolchain.
Last but not least, the performance and user experience of the MIDP based LWUIT on Blackberry isn't very good...

The solution for all these issues is to use the RIM API's, which unfortunately means you need to create two separate versions of your application (3 if you need blackberry Storm support) .

I won't go into too many details on the BlackBerry devices, but a couple of years ago they introduced the Storm device which was their first touch screen device (featuring a click screen). Supporting the Storm requires importing classes of the API that aren't supported in older versions of RIM's API, hence Storm compatibility requires using a relatively new BlackBerry OS that most users don't have.
So you will need two builds and two blackberry Java Development Environments (JDE's) if you need to support Storm.

The instructions bellow are also geared towards the NetBeans IDE and Ant build.

LWUIT currently has two maintained BlackBerry ports, one created by Thorsten & another created by myself. Each has its advantages and you can easily go back and forth between them. Since I used NetBeans I will explain based on my port but you can easily replace the content of the src directory with Thorsten's port and it should be pretty seamless.

A standard LWUIT MIDlet should work fine on a RIM device using the ports, however RIM also offers support for a CLDC application. Using this approach tends to provide improved performance/security handling for RIM although its completely optional.

  1. Download the JDE versions, I recommend 4.2.x and 4.7.x (for Storm support).
  2. Follow the NetBeans BlackBerry knowledge base article to add the JDE versions as platforms to NetBeans (no need to follow the part about editing the build.xml).
  3. Fetch the LWUIT sources from SVN and open the BlackBerry project. Clean & Build the project (notice that you MUST clean & build, a plain build will often fail since the RIM port needs to replace some classes from LWUIT).
  4. If using storm as well, change the configuration of the Blackberry LWUIT port to "touch" and again clean & build.
  5. Download the BB ant tasks which are much easier to work with than the approach taken by the knowledge base article.
  6. Add "configurations" to the NetBeans project for BlackBerry and BlackBerryTouch. Set them to use the appropriate JDE Platforms.
  7. In the blackberry configurations add an "Ability" called RIM. This will allow you to use #ifdef RIM
    rather than #ifdef BlackBerryTouch && BlackBerry
    (yes, I can't stand #ifdef's but they are better than just copy and pasting the entire code and with RIM we don't have a choice).
  8. In the libraries for the project add both LWUIT & the appropriate blackberry project. Make sure to add the touch JAR only to the touch (Storm) configuration and the standard jar to the other BlackBerry configuration.
  9. Open the build.xml file of your NetBeans project and add the following, update the paths and names marked in bold:
    <target name="post-init">
    <available file="${platform.home}/bin/rapc.exe" property="do.rapc">
    <available file="${platform.home}/simulator/9500.bat" property="bbtouch">
    <condition property="jpda.port" value="8000">
    <isset property="do.rapc">
    </isset>
    </condition>

    <target name="post-preprocess" depends="copyBBSources,copyBBTouchSources">
    </target>

    <typedef resource="bb-ant-defs.xml" classpath="bb-ant-tools.jar">
    <target name="bbbuild" description="blackberry build" depends="init,copyBBSources,copyBBTouchSources">
    <echo message="Compiling ${preprocessed.dir}"></echo>
    <mkdir dir="${dist.dir}/bbant">
    <rapc verbose="true" output="${name}" jdehome="${platform.home}" import="${platform.bootclasspath}" destdir="${dist.dir}/bbant/" noconvert="true">
    <src location="${basedir}/${preprocessed.dir}">
    <jdp title="Vendor" version="1" type="cldc" icon="${basedir}/src/icon.png" />
    </jdp>
    <!-- sigtool jdehome="C:\Program Files\Research In Motion\BlackBerry JDE 4.7.0" codfile="${dist.dir}/bbant/${name}.cod" password="" / -->
    <alx destdir="${dist.dir}/bbant" filename="${name}.alx">
    <application id="AppName">
    <codset>
    <fileset dir="${dist.dir}/bbant" includes="*.cod">
    </fileset>
    </codset>
    </application>

    <mkdir dir="${dist.dir}/bbant-final">
    <jadtool description="desc" id="appId" input="${dist.dir}/${dist.jad}" destdir="${dist.dir}/bbant-final">
    <fileset dir="${dist.dir}/bbant" includes="*.cod">
    </fileset>
    </jadtool>

    <target name="copyBBTouchSources" if="bbtouch">
    <echo message="Copying blackberry touch sources"></echo>
    <copydir forceoverwrite="true" src="$%7Bproject.BlackberryPort%7D%5Cbuild%5Ctouch%5Cpreprocessed" dest="${basedir}/${preprocessed.dir}">
    <touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/M3G.java">
    <touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/SVGImage.java">
    <touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/animations/Transition3D.java">
    <touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/impl/midp/SVGImplementation.java">
    </touch>

    <target name="copyBBSources" if="do.rapc">
    <echo message="Copying blackberry sources ${preprocessed.dir}"></echo>
    <copydir src="$%7Bproject.LWUIT%7D%5Csrc" dest="${basedir}/${preprocessed.dir}">
    <copydir forceoverwrite="true" src="$%7Bproject.BlackberryPort%7D%5Cbuild%5Cpreprocessed" dest="${basedir}/${preprocessed.dir}">
    <touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/M3G.java">
    <touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/SVGImage.java">
    <touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/animations/Transition3D.java">
    <touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/impl/midp/SVGImplementation.java">
    </touch>

    <target name="post-jar" if="do.rapc">
    <rapc verbose="true" output="${name}" jdehome="${platform.home}" import="${platform.bootclasspath}" destdir="${platform.home}/simulator/" noconvert="true">
    <src location="${basedir}/${preprocessed.dir}">
    <jdp title="Vendor" version="1" type="cldc" icon="${basedir}/src/icon.png" />
    </jdp>
    </src>

    <target name="post-clean">
    <delete failonerror="false">
    <fileset dir="${platform.home}/simulator">
    <include name="**/${name}.*">
    </include>
    </fileset>
    </delete>
    </target>



It was a morning of keynotes examining the workings of technology professional, and a contrast of preaching styles.

Ivar Jacobson's Lutheran delivery allowed the audience to share in the nordic dispair of a participating in an industry in still seeking a single development methodology, before raising the collective spirit with a gospel of a universal one to be resurrected from the common elements of all the ones developed to-date. But it was hard for the Janitor's mundane mind to see if there was anything left in this intersection-of-methodologies except for good old fashioned common sense. And will probably Bourne in shell for saying so.

Next up was the evangleical Bob Martin whose exhortive style raised a lot of chuckles, mining such rich seams as: Developer versus Manager, and Project Trainwrecks We've All Survived. At times seeming like he might speak in tongues, the Janitor thought he was, unfortunately, glossolalia-ing over some nice practical advice about how to be more of a professional that produces write well-crafted code in which QA will find no fault.

And the day continued a stylistic Tower of Babel, with an last minute standin presenter of an excellent talk on Java classloaders having the nerves of steel to allow the audience to debug and fix his demo that had gone wrong; Stephen Chin's engaging JavaFX talk on the many excellent components in JFXtras (like the JavaFX table which performed beautifully with 16 million items), and FEST saw him running up and down the stairs asking questions and handing out t-shirts.

The stylistic nightmare that was four geeks in hats dancing to Rick Astley meant you were at the start of the live recording of the JavaPosse. There were predictably big cheers for Scala, Java EE 6's imminent (December 10th) release, mostly cheers for closures, and lots of other fun which you can catch up to when they edit the bad words out and publish it, if you weren't there.

Stephan Janssen really puts on a great show at Devoxx.

The Janitor is here at Devoxx, just down the road from Neelie Kroes !

 Her influence was on show at the Oracle keynote, which began with a legal disclaimer saying something about forward looking statements about products not being indicative of anything. One has to be sympathetic as the commission's wheels grind on, but it was a bit like hearing that the tenor has a sore throat before the opera starts. Happily, Roberto and Ludo were more melodious, announcing the imminent December 10th release date for Java EE 6 and Glassfish v3 and a demo of deploy-on-save in Eclipse (it could equally have been in NetBeans), re-deploying deployment descriptor-free servlets and EJBs to Glassfish v3 in about a second. Adobe gave an engaging keynote, and although the Janitor didn't love the smell of all the multistep automagical conversion to massage an app developed in the flash tool into something allowed to run on the iPhone (pretty sure Apple doesn't either), the image-to-widget tool in Adobe Catalyst demoed very well. Something to think about for the JavaFX Production Suite.

Next up the Janitor sat in on Mark Reinhold's session on JDK 7. There was a progress update on the projects you already know about, some of the Project Coin code snippets provoking murmurs of appreciation and the odd ripple of applause, as did Mark's proposal to add simplified closures proposal to JDK 7. Less good news on the schedule, but as Roberto is finding for Java EE 6, sometimes the wait can be satisfying.

After lunch, the voices became hushed and the big room where James was about to speak suddenly filled up. James talked about the JavaStore, which is in live beta, as well as a new set of cash registers. While you can still only purchase apps from the store in the US (until the legal team works through the retailing laws of every other country), you can submit apps today if you are in US, UK, Australia, India, China, Sweden, Brazil or Russia, with Belgium, Canada, Israel, Germany, Italy, France, Spain coming soon.

Richard and Jasper and Tor's session on JavaFX focused on the upcoming features in JavaFX 1.3 and on the authoring tool. Covering tasks, the new UI controls (like tree, menus, popups, tooltips, scrollviews etc), new region architecture for expanded CSS styling and super fast rendering, it looks like a tasty package in the works, and the authoring tool (last seen at JavaOne) was looking better than ever. Can't wait to get it out the door.

And for a while today #devoxx was trending on Twitter. Right now beer and frites are trending high. More tomorrow.
The look of some modern phones is wasteful in screen real-estate but stunning in visual effect. The rounded UI and faded scrolling are are gorgeous effects on newer devices that make a huge difference with very little work.

These effect can be added to LWUIT easily without overhauling anything. I neglected to add padding to the softbutton area in the demo code but other than that the code is trivial. I used a glass pane for the rounded border effect, you can use hardcoded image files to provide proper anti-aliasing.
The fade effect required gradient image masks and replacing the look and feel which in itself wasn't too difficult either.

BTW I very much enjoyed reading Angelo's post on gradients, this is something that our UI designer has been riding on me to get for a very long time... I'm still trying to figure out a way to integrate this into the whole designer/style paradigm in an easy to use way...

/**
* Allows overriding the form to give it a "rounded border" look and feel
* with a fade out in the bottom in case of scrolling.
*
* @author Shai Almog
*/

public class RoundFadeGlassPane implements Painter {
private Image topLeft;
private Image topRight;
private Image bottomLeft;
private Image bottomRight;
private Form parentForm;

public RoundFadeGlassPane(Form f) {
parentForm = f;
Image blackCorner = Image.createImage(60, 60);

Graphics cornersGraphics = blackCorner.getGraphics();
cornersGraphics.setColor(0);
cornersGraphics.fillRect(0, 0, blackCorner.getWidth(), blackCorner.getHeight());
cornersGraphics.setColor(0xffffff);
cornersGraphics.fillRoundRect(0, 0, 200, 200, 60, 60);

// get the white color since it might be modified when rendering and might not actually be 0xffffff
// e.g. it might be 0xfefefe due to rendering issues
int white = blackCorner.getRGBCached()[blackCorner.getHeight() / 2 * blackCorner.getWidth()];

// remove the white color from the image so only the black corners remain
blackCorner = blackCorner.modifyAlpha((byte)0xff, white);

topLeft = blackCorner;
topRight = topLeft.rotate(90);
bottomRight = topLeft.rotate(180);
bottomLeft = topLeft.rotate(270);
PainterChain.installGlassPane(f, this);
}

public void paint(Graphics g, Rectangle rect) {
g.drawImage(topLeft, 0, 0);
g.drawImage(topRight, parentForm.getWidth() - topRight.getWidth(), 0);
g.drawImage(bottomLeft, 0, parentForm.getHeight() - bottomRight.getHeight());
g.drawImage(bottomRight, parentForm.getWidth() - topRight.getWidth(), parentForm.getHeight() - bottomRight.getHeight());
}
}

/**
* Simple look and feel automatically installing the "round look" for applications
*
* @author Shai Almog
*/

public class RoundFadeLookAndFeel extends DefaultLookAndFeel {
private Object topMask;
private Object bottomMask;
private Image topCache;
private Image bottomCache;

public void bind(Component c) {
if(c instanceof Form) {
new RoundFadeGlassPane((Form)c);
}
}

private Object createFadeMask(boolean direction) {
Image mask = Image.createImage(Display.getInstance().getDisplayWidth(), Display.getInstance().getDisplayHeight() / 10);
Graphics g = mask.getGraphics();
g.setColor(0xffffff);
g.fillRect(0, 0, mask.getWidth(), mask.getHeight());
if(direction) {
g.fillLinearGradient(0, 0xffffff, 0, -5,
mask.getWidth(), mask.getHeight(), false);
} else {
g.fillLinearGradient(0xffffff, 0, 0, 5,
mask.getWidth(), mask.getHeight(), false);
}
return mask.createMask();
}

private Object getTopMask() {
if(topCache == null || topCache.getWidth() !=
Display
.getInstance().getDisplayWidth()) {
topMask = createFadeMask(false);
topCache = Image.createImage(
Display.getInstance().getDisplayWidth(),
Display.getInstance().getDisplayHeight() / 10);
}
return topMask;
}

private Object getBottomMask() {
if(bottomCache == null || bottomCache.getWidth() !=
Display.getInstance().getDisplayWidth()) {
bottomMask = createFadeMask(true);
bottomCache = Image.createImage(
Display.getInstance().getDisplayWidth(),
Display.getInstance().getDisplayHeight() / 10);
}
return bottomMask;
}

public void drawVerticalScroll(Graphics g, Component c,
float offsetRatio, float blockSizeRatio) {
if(offsetRatio + blockSizeRatio < 0.995) {
// we need to draw the fade on the bottom
Object bottom = getBottomMask();
Graphics temp = bottomCache.getGraphics();
temp.translate(0, bottomCache.getHeight() - c.getHeight());
c.paintBackgrounds(temp);
g.drawImage(bottomCache.applyMask(bottom), c.getX(), c.getY() + c.getHeight() - bottomCache.getHeight());
}
if(offsetRatio > 0) {
// we need to draw the fade on the top
Object top = getTopMask();
Graphics temp = topCache.getGraphics();
temp.translate(0, topCache.getHeight() - c.getHeight());
c.paintBackgrounds(temp);
g.drawImage(topCache.applyMask(top), c.getX(), c.getY());
}
super.drawVerticalScroll(g, c, offsetRatio, blockSizeRatio);
}
}

There is always a challenge what to do with the components that are scaled to a small size. As you can see from the screenshot you can still edit them when they are small (unless it has no point even with magnifying glass). Fortunatelly you can edit the components in other "state" when they are scaled to "normal" size. It creates nice effect when switching between the pages. And all the effects were set up in the UI (no code).


There is something in the green box on right bottom.
It synchronizes the selection even in Navigator (as shown by arrow).



Components in full size in different state.
Notice the small orange box. Those are the User and Tag textfields.


How it looks when the application runs?

I hope that you'll be able to try the preview of the new tool for Java FX very very soon. The only thing that I can show you for now is a screenshot. Click to it to enlarge it.



  • Are you interested in more details? More screenshots? A screencast? A working demo?
    • then leave me a comment

  • What would you miss most in a designer tool for FX?
    • then leave me a comment

  • Do you know what the "States" means? What all is in the palette? What are the small icons next to the properties?
    • then stay tuned for preview release

The LWUIT developer guide generally recommends increasing the padding of components to make them "finger friendly" as a generic guide for LWUIT on touch devices. While this is true, its somewhat basic and we can do much more in LWUIT and outside of it to make our application easier for the touch...

Two of the newer features in LWUIT's SVN are touch menus and tactile feedback, both are off by default and should be explicitly activated. The reason for this is that we don't want to "enforce" our opinion on how touch should look/feel on an application.
You can query whether the device supports touch by invoking Display.getInstance().isTouchScreenDevice()

Notice that the isTouchScreenDevice() method doesn't work properly on some simulators... However, it seems to work reasonably well on the actual devices.

To enable touch menus just use:
UIManager.getInstance().getLookAndFeel().setTouchMenus(true);

You can customize the look of the buttons via the "TouchCommand" selector in the theme.

The tactile feedback causes the phone to vibrate when the user presses a component that is intractable (e.g. list/button). Since most touch screens aren't of very good quality this is very useful in giving the user a sense that the screen actually registered his interaction. To enable this you can use:
UIManager.getInstance().getLookAndFeel().setTactileTouchDuration(100);

The argument is the number of milliseconds to vibrate on touch 50 to 100 seem like reasonable numbers, 0 disables the feature.

Component now has isTactileTouch()/setTactileTouch(boolean) methods to toggle the tactile touch vibration per a specific component. By default LWUIT tries to initialize this based on focusability so for custom components it might be useful to manipulate this flag.

A somewhat older flag which we would recommend is fireOnClick() for Lists. By default lists require two clicks to activate an entry, the first selects the entry and the second opens it.
This allows "context command flow", e.g. a command such as "remove" that removes the current selected entry. However, on touch devices this sort of behavior is often inconvenient and you would expect the "remove" command to move you to a separate list of checkboxes to select the entries to remove.
You would normally expect a single tap on the entry to act like the fire key (send an action event immediately) and not like simple selection. Calling List.fireOnClick(true) makes the list behave like that which is more convenient for touch device, however you need to ensure your application flow can handle this.

There is also the virtual keyboard that Chen blogged about recently, this is immensely useful for touch and Chen has improved its performance considerably!

As a side note unrelated to LWUIT, many devices have a "compatibility" mode on by default where keys are placed by the device at the bottom of the touch screen to allow "none-touch" Java ME applications to run on the device. Applications are expected to explicitly declare their support for touch to utilize the full screen of the device. This is done using the following Jad flags:

Navi-Key-Hidden: true
Nokia-MIDlet-On-Screen-Keypad: no
MIDlet-Touch-Support: true

Notice that the last entry (MIDlet-Touch-Support) is required by current/older Samsung/LG devices but is illegal by the MIDP specification hence fails on Nokia etc. so for support on these devices you would need a copy of your JAD (only the jad) with this attribute added.

I’ve been working on a project using CodeIgniter recently, and have been trying to clean some stuff up so that long running background scripts use the same code as the live system. Sane, every framework has some way of wiring it up so you can run command line tasks using the same framework as you’re running for web requests, and CodeIgniter is no exception. For some reason stuff that used to run find as bare mysql scripts kept running out of memory when I ran it within CI. Turns out the DB wrapper actually stores all the queries it runs in a big array. Not an issue when processing web requests I’m sure, but definitely an issue when you’re running big background tasks. If you want to keep your scripts from running out of memory it’s easy enough to do:

$this->db->save_queries = false;

I wanted to review some issues at netbeans.org web site. But I recieved following message :



Nothing unexpected obviously, the netbeans.org is being migrated. The migration started on Monday, November 2, at 5:00 PM CET/8:00 AM PST. Everything will be back on November 9.

What is going to happen during and after the migration?
  • All services (except hg.netbeans.org) will switch to read-only mode or become completely unavailable till 11/9
  • Bug tracking system, Mailing lists server, and the Wiki won't be available (or only in RO mode) during the migration
  • Accounts
    • You'll receive new password for the account in new infrastructure by email
    • If you used more accounts with the same email address then only the latest used account will be migrated (more details)
    • We will use same password for all services in netbeans.org after migration. It means, you will have just one password for web, mercurial and wiki
  • Mailing list changes
  • Bug tracking system
    • will be changed to bugzilla
    • there will be lot of changes in the RESOLUTIONS, STATUSES, KEYWORDS - see complete list
    • filling new bug will be easier because the list of projects will be shorter
    • table of all new components/subcomponents
    • all issues in RESOLVED/LATER were closed as WONTFIX in last days. If you don't agree reopen them after the migration. However most of these issues are low priority bugs that were out of the radar of the development anyway. Test in latest NB6.8 Beta if they are still valid, please.
  • More details in the FAQs mentioned in the previous post
What to do after migration
  • Login to https://www.netbeans.org/people/login with the password mentioned in the e-mail; then create your new password.
  • If you use Mercurial to check out the NetBeans sources, you must also change the password in your local hg netbeans repositories
  • Update your email client's filters for mailing lists because some mailing lists will have new names

By Johan Karlsson

You have just developed your new cool MIDlet, the one that is going to rule the world. It runs like a well oiled machine on the emulator. But when you download and install it on your target device, the MIDlet seems to take ages to start up. Finally, you see the splash screen. Oh no! The MIDlet crashes and you get an error pop-up saying "Application Error," and the MIDlet shuts down. What happened? This is not the way you pictured it. Is there something that shows what really happened behind the scenes?

Have you been in a situation like this? Have you ever wanted to log from your MIDlet? Read on, and I will teach how to add powerful logging to your MIDlets.

You may have considered doing your own logging facility. But why not use an existing solution: The Microlog open-source logging library. It is based on the well known Log4j API or logging library, but has been created from the ground up with Java ME limitations in mind.

Read the full article.

The netbeans.org site is going to be migrated into kenai.com infrastructure during next week

Have you see the monthly challenges over at JFXStudio ?

All the entries have to have less than 30 lines or 3000 charcters of code. Last month the theme was Time, this month its the number 5. Numerologically speaking, the number 5 goes hand in hand with sociability, and a tendency to excess. Guess which member of the JavaFX team picked that one ?


And ProJavaFX co-author Jim Weaver has been running a JavaFX challenge of his own.
Disclaimer: goal of this blog post isn't to show all the features that are available but to point out some of them which were improved or fixed...

The Java FX plugins for NetBeans were released together with the NetBeans 6.8 Beta. The functionality is available in following two NetBeans IDE distributions - All, Java FX. If you have different distro you can enhance it from "Tools > Plugins".

New or Improved Features: For the "old" NetBeans user some of the features could "WT*? It works for years". However it wasn't true for Java FX files and projects in previous versions.
  • Click through navigation in Editor - . Navigates using Ctrl + mouse over selected type, which provides hyperlink to used type.
  • Go To Type
  • Java FX Editor Hints
    • Add Imports -


    • Unused variables -


    • Remove unused imports -


    • Surround with try-catch -


    • Implement abstract methods -


    • Overridden method -


    • Fix package -


    • and some static hints -


  • Code Completion - Overall fixes in code completion. Faster, more accurate. Unfortunately there are still issues when compiler is not able to parse not compilable source files.
  • Debugger - the old debugger has been removed and rewritten to use common debugger infrastructure in NetBeans. This brings better extensibility and performance, but the set of fundamental issues (such as non functional watches) remains due to JavaFX class files weaknesses.
  • Profiler - the same feature set as in previous versions.
  • Refactoring - Refactoring is turned off by default because issues in compiler may cause data loss. Turn refactoring on by running NetBeans with command line switch -J-Djavafx.refactoring=true on your own risk.


What you can expect soon?
  • quality is increasing as the whole team focused on bugfixing. You can noticed the positive bug progress in last weeks.
  • fixed refactoring will be part of the plugins asap
  • fixed debugger - there are some bugs in javafx compiler that are blocking the fixes in NetBeans IDE however there is lot of issues that have to be fixed before FCS
  • reformatting of code - will be re-written for the 6.8 to provide much more better results than in "old" releases.
  • fxd composer - lot of fixes for better performance and usability
Where to report problems?

The Java Store team here at Sun is in the final stage of readying things to fling open the doors to shoppers in the next week or so !

This means one more tweak of the store front: just like in a physical store, polishing signage, perfecting the display areas and checkouts: in this case making the final UI changes to the all-JavaFX desktop app that showcases all the Java and JavaFX applications in stock and allows purchase and installation.

And it means final verification of the apps that will be on the shelves of the store on the day it opens - approaching 50 already, as participants in the beta program will already know - with more applications, ranging from free to paid, to come. All coming in at the back of the store, the Java Warehouse, which has been pretty busy of late.

So if you have a Java or JavaFX app that's looking for an audience (like, perhaps the 60-70m that download the JRE each month...), you should stay tuned to the Planetarium. Much more in the coming weeks !


Last week was a pretty busy one, with the release of Java ME SDK for Mac (early access), and the NetBeans 6.8 beta.

The Java ME SDK is the all-in-one phone to Blu-Ray app development kit, and the news is that its now available on the Mac platform too. Ready for the final NetBeans 6.8 release on December 1st, whose beta has already had a bunch of promising reviews for the new features, like zapping up the JavaFX code editing  and hinting niceties that Tor has often mentioned.

It's strange no-one suggested doing home launch parties for them. They can be such fun !
Iwan wanted to know if the Java ME SDK works with the NetBeans 6.8 Beta. And if it could e available at Update Center to let you download the SDK directly from NetBeans.

NetBeans and Java ME SDK - picture is worth a thousand words...

Open "Tools > Java Platforms"

Press the "Add Platform" button


Select the "Java ME MIDP Platform Emulator"


Browse to your Java ME SDK location - usually /Applications/Java_ME_SDK_3.0


Platform has been found



Java ME SDK 3.0 Ea as module at NB Udate Center - this is most probably worthless as there is no added value then that the users find it quickly. The maintenance of the modules at UC takes a lot of time. You have to upload it, test it, then you have to be careful when the final version appears and remove it from UC or replace with the new version. I can't see any volunteer ;)
OTOH, the module with the SDK would just download it and install it. If you brave enough to use Early Access yhis steps - download, install - will warn you that you are doing something "special".
Bidi has finally landed after quite a wait this effort was contributed by Telmap and implemented mostly by Ofir Leitner.

Besides bidi Chen and myself committed allot of groundbreaking changes. Chen made some very significant performance improvements for LWUIT very noticeable in the Virtual Keyboard code. I committed more elaborate Scrollbar styling code, we now also have HorizontalScroll and can generally customize all aspects of a scroll/scroll thumb using the theme rather than using the old approach of look & feel override.

But the meat and potatoes of the commit is the bidi code... BiDi is the term refering to Bi-directional language support, generally RTL languages. There is plenty of information about RTL languages (Arabic, Hebrew, Syriac, Thaana) on the internet but as a brief primer here is a minor summary.

Most western languages are written from left to right (LTR), however some languages are normally written from right to left (RTL) speakers of these languages expect the UI to flow in the opposite direction otherwise it seems weird just like reading this word would be to most English speakers: "drieW".

The problem posed by RTL languages is known as BiDi (Bi-directional) and not as RTL since the "true" problem isn't the reversal of the writing/UI but rather the mixing of RTL and LTR together. E.g. numbers are always written from left to right (just like in English) so in an RTL language the direction is from right to left and once we reach a number or English text embedded in the middle of the sentence (such as a name) the direction switches for a duration and is later restored.

LWUIT's support for bidi includes the following components:

  • Bidi algorithm - allows converting between logical to visual representation for rendering
  • Globabl RTL flag - default flag for the entire application indicating the UI should flow from right to left
  • Individual RTL flag - flag indicating that the specific component/container should be presented as an RTL/LTR component (e.g. for displaying English elements within a RTL UI).
  • RTL text field input
  • RTL bitmap font rendering

Most of LWUIT's RTL support is under the hood, the LookAndFeel global RTL flag can be enabled using:
UIManager.getInstance().getLookAndFeel().setRTL(true);

(Notice that setting the RTL to true implicitly activates the bidi algorithm).

Once RTL is activated all positions in LWUIT become reversed and the UI becomes a mirror of itself. E.g. A softkey placed on the left moves to the right, padding on the left becomes padding on the right, the scroll moves to the left etc.
This applies to the layout managers (except for group layout) and most components. Bidi is mostly seamless in LWUIT but a developer still needs to be aware that his UI might be mirrored for these cases.
It's time for celebration. The NetBeans team released the Beta of NetBeans 6.8 finally. The plan was to publish it yesterday but sometimes you cannot make it. Reason? Slow upload. Could you imagine how many GB have to be uploaded? This could be great quiz question for Geertjan's NB podcast :)

If you are interested what's new in it comparing to the Milestone 2 then there is simple answer. It is more stable and we added the support for Java FX. The list of all features is available at the official page - http://www.netbeans.org/community/releases/68/. The team resolved around 1000 bugs - http://quality.netbeans.org/metrics/Bugs-Reported-vs-Resolved-.html

So it's Friday, it's time to celebrate the release. Do you want to see the old NetBeans team? Watch this video.
Lot of the users were asking when the Java ME SDK will be available at the Mac. The time has come. Now. If you want to try the new release of the Java ME SDK for Mac then the Early Access is available for download.

As it is early access provide your feedback to the guys who developed it at their blog blogs.sun.com/javamesdk.

AFAIK, only the CLDC/MIDP devices are available for the Mac. And two devices with JavaFX support.
Note: the Java ME SDK for Mac won't be in NetBeans 6.8 as its final version won't be ready when the NB will ship.

Santiago has written a blog  that provides details including a screencast of the Mobility Platform telematics demo that was shown recently at Oracle OpenWorld 2009.

The demo shows a simulation of vehicles synchronizing events collected on a local database (BDB) to a back-end Oracle database. Events collected from vehicle sensors are stored in an embedded BDB database and periodically synchronized; in addition, critical events are reported immediately using the dynamic capabilities of the Mobility Platform. A JavaFX front-end was developed to increase the demo's coolness factor.

Here is the architecture of the solution:

Please contact us at mep-feedback@sun.com if you would like to get more details including an early access version of the latest Mobility Platform software for evaluation.

In a recent post I discussed LWUIT 1.3's upcoming table component. This new component is based on a new underlying layout manager also introduced in LWUIT 1.3: the table layout.

The table layout is largely inspired by the HTML table tag and slightly by AWT's GridBagLayout.
The table layout is a constraint based layout (similar to the border layout) this means that unlike other layout managers that expect components to be added on their own:
container.addComponent(component);

The table layout container expects something like this:
container.addComponent(tableConstraint, component);

Notice that this syntax is optional if omitting the constraint a default behavior will ensue of placing the component in the next available cell.

The table layout will automatically size components to the largest preferred size in the row/column until running out of space, if the table is not horizontally scrollable this will happen when the edge of the parent container is reached (close to the edge of the screen) and further components will be "crammed together". Notice that all cells in the table layout are sized to fit the entire cell always. To align, or margin cell's a developer can use the methods of the component/Style appropriately.

A developer can provide hints to the table layout to enable spanning and more detailed column/row sizes using the constraint argument to the addComponent method. The constraint argument is an instance of TableLayout.Constraint that must not be reused for more than one cell, this will cause an exception.

A constraint can specify the absolute row/column where the entry should fit as well as spanning between cell boundaries. Notice that in the picture the "First" cell is spanned vertically while the "Spanning" cell is spanned horizontally. This is immensely useful in creating elaborate UI's,

Constraints can also specify a height/width for a column/row that will override the default, this size is indicated in percentage of the total table layout size. In the picture you can see that the "First" label is sized to 50% width while the "Forth" label is sized to 20% height.

Form mainForm = new Form("Table Layout");
TableLayout layout = new TableLayout(4, 3);
mainForm.setLayout(layout);
TableLayout.Constraint constraint = layout.createConstraint();
constraint.setVerticalSpan(2);
constraint.setWidthPercentage(50);
mainForm.addComponent(constraint, new Label("First"));
mainForm.addComponent(new Label("Second"));
mainForm.addComponent(new Label("Third"));

constraint = layout.createConstraint();
constraint.setHeightPercentage(20);
mainForm.addComponent(constraint, new Label("Forth"));
mainForm.addComponent(new Label("Fifth"));
constraint = layout.createConstraint();
constraint.setHorizontalSpan(3);
Label span = new Label("Spanning");
span.getStyle().setBorder(Border.createLineBorder(2));
span.setAlignment(Component.CENTER);
mainForm.addComponent(constraint, span);
mainForm.show();
NetBeans teams are working on the next release. That's obviously no big surprise. However there was a small change in the release schedule that influenced a lot of the people, including the community. If you are following the release schedule carefully then you might notice the small shift of the release dates. The main reason was the JavaFX support. The support wasn't planned for the NB 6.8 Beta originally. The main reason was that the team working on the support needed more time to stabilize the features for JavaFX SDK 1.2.1 and the new NetBeans APIs. Therefore we wanted to release the FX plugins together with a release candidate.

However it wouldn't be a good message to community that we don't have Java FX support, right? That's why we decided to ship Beta later then expected. So you should have chance to try the Java FX in NB 6.8. It will be in Beta quality and I really don't recommend it for production work. Anyway, it is better then the 6.7! Some features will be disabled as the decision to release it in Beta came in last minute and there isn't enough time to stabilize them more (more in some next post).

What are the pros / cons of the postponed Beta release?
  • +More bugs will be fixed. It should mean more stable release.
  • +Java FX will be part of the Beta.
  • -Community received M2 instead of Beta.
  • +but the M2 i in Beta quality already ;)
Is it news of the week? The JetBrains opensourced their great IntelliJ IDEA.

It seems that the company is moving to the open source waters (at least a little bit). They've released their MPS and YouTrack to community already. However nobody expected that they'll do it even with the jewel in their portfolio - IntelliJ IDEA. But they did it ;) If you want to know more details about why? what will be the business model? etc. listen to latest Javaposse podcast with Roumen and Dmitry Jemerov.

Its been a while since my original LWUIT ticker list post and quite a few has changed, back when I originally posted there was no built in tickering functionality in LWUIT itself. Recent questions in the mailing list and from partners prompted me to write the code bellow, generally for tickering a ComboBox however I tried to make it as generic as possible so it can be installed into every list out there.

Notice that to ticker custom components you need to set them as a cell renderer to prevent the label from throwing an exception when invoking startTicker. You can use the TickerRenderer bellow with practically every list and it doesn't need to be a part of a combo box.

public class TickerComboDemo extends MIDlet {
public void startApp() {
try {
Display.init(this);
Resources r = Resources.open("/javaTheme.res");
UIManager.getInstance().setThemeProps(r.getTheme(r.getThemeResourceNames()[0]));
Form form = new Form("Ticker Combo");
ComboBox combo = new ComboBox(new String[]{"Jack",
"Name that should probably trigger a ticker",
"Another name that should probably trigger a ticker",
"Kate", "Sawyer", "Sayid", "Hurley", "Jin", "Sun", "Charlie", "Claire",
"Aaron"
, "Michael", "Walt", "Boone", "Shannon", "Locke", "Mr. Eko",
"Ana-Lucia", "Libby", "Desmond", "Benjamin Linus", "Juliet Burke"}) {
protected List createPopupList() {
List l = super.createPopupList();
l.setListCellRenderer(new TickerRenderer());
return l;
}
};
form.addComponent(combo);
form.show();
} catch (IOException ex) {
ex.printStackTrace();
}
}

class TickerRenderer extends DefaultListCellRenderer {
private DefaultListCellRenderer selectedRenderer = new DefaultListCellRenderer(false);
private List parentList;
public TickerRenderer() {
super(false);
}

public boolean animate() {
if(parentList != null && parentList.getComponentForm() != null) {
if(selectedRenderer.isTickerRunning()) {
if(selectedRenderer.animate()) {
parentList.repaint();
}
}
}
return super.animate();
}

public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected) {
if(isSelected) {
selectedRenderer.getListCellRendererComponent(list, value, index, isSelected);

// sometimes the list asks for a dummy selected value for size calculations and this might
// break the tickering state
if(index == list.getSelectedIndex()) {
if(selectedRenderer.shouldTickerStart()) {
if(!selectedRenderer.isTickerRunning()) {
parentList = list;
list.getComponentForm().registerAnimated(this);
selectedRenderer.startTicker(UIManager.getInstance().getLookAndFeel().getTickerSpeed(), true);
}
} else {
if(selectedRenderer.isTickerRunning()) {
selectedRenderer.stopTicker();
}
}
}
return selectedRenderer;
} else {
return super.getListCellRendererComponent(list, value, index, isSelected);
}
}
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}
}

Our binaries are no longer hosted on java.net to avoid confusion between the binary drops and the source version. All of LWUIT binary elements are now a part of the new LWUIT product page at java.sun.com.
The java.net project home page and forum are still the development hub for discussion and ongoing development.
Chen & myself are huge advocates of placing everything within LWUIT using layout managers, maybe its due to our Swing background and maybe its just our bad experience with the unique ways in which phones break when placing things absolutely.

A common request from users after LWUIT 1.0 was published was for a means of placing a component at an X/Y coordinate. We generally avoided that, since it doesn't make much sense. In that case why not just use Graphics, images etc.

We did however see two minor use cases for coordinate layouts, the ability to place elements in elaborate structures and the ability to place components one on top of the other (z-ordering). Notice that z-ordering can be achieved with other layout managers (in theory) but its not currently supported by any other layout.

Unlike an "absolute layout" that would just take X/Y coordinates and place a component within them, the coordinate layout "shifts coordinates" based on the amount of space it has available. E.g. in a 240x320 phone the size of the content pane might change for the following reasons:
  • Different font size for the title/soft button areas.
  • Signal/battery status on the top of the screen is shown by some operator firmwares even in game canvas!
  • Rotation of the screen for newer devices
  • Virtual keyboard opening on some devices
Etc.

So you would need to constantly check and recalculate coordinates in order to make sure that they are correct if you were to use an "absolute layout". Coordinate layout does that check for you and lays out the components in the proper positions based on your intentions.

The following code produces the image you see above I will commit it to my incubator project soon:
mainForm.setLayout(new CoordinateLayout(200, 200));

Label centeredLabel = new Label("Center");
centeredLabel.setX(90);
centeredLabel.setY(90);
centeredLabel.getUnselectedStyle().setBgTransparency(100);
centeredLabel.getUnselectedStyle().setBgColor(0xff);

Label underCenter = new Label("Under Center");
underCenter.setX(80);
underCenter.setY(95);

Label top = new Label("Top Left");
top.setAlignment(Component.CENTER);
top.setX(0);
top.setY(0);
top.setPreferredW(200);
top.setPreferredH(30);
top.getUnselectedStyle().setBgColor(0xff0000);

mainForm.addComponent(underCenter);
mainForm.addComponent(centeredLabel);
mainForm.addComponent(top);

Notice several things:
  • We create a coordinate layout in 200x200 rather than screen resolution, these are "virtual" coordinates and they would be adapted to actual coordinates when the layout occurs. We can now "assume" that our resolution will always be 200x200.
  • Preferred size is used for all the components, we can determine absolute (unscaled size in pixels) using setPreferredSize
  • Alignment etc. still works just as expected
  • Z-order is determined by the order of addition to the container and is quite trivial using coordinate layout
BTW java.net is experiencing some issues this week with a DOS attack, read more about it in Terrences blog.
        

There will a demonstration of a telematics usecase  that uses Sun's Mobility Platform and Oracle's embedded Berkeley DB-Java Edition and Oracle 11g DB during Oracle OpenWorld in San Francisco. Here are the details of when and where it will be shown.

Meeting Name:             BDB Demo Session
Meeting Date:             Monday, October 12, 2009 
Meeting Time:             11:00 a.m. - 1:00 p.m. 
Meeting Location:         Hilton Hotel - Union Square 
                          Room 6, 4th Fl
                          San Francisco, USA

This usecase will demonstrate an embedded telematics application used in a vehicle to collect data from the vehicle sensors and store them locally on a Bekeley DB as well as synchronizing them on a Oracle DB repository on the enterprise using the GlassFish Mobility Platform. It also flags critical events and responses so that any problems can be quickly identified.

I would like to invite all those going to Oracle OpenWorld to attend this session and view the demo. Please contact us at  mep-feedback@sun.com if you would like to get more details including an early access version of the latest Mobility Platform software for evaluation.



Don't bottle up any unexpressed opinions about JavaFX, take the survey.

Mixed in with the usual snoozeville multichoice questions about the kind of project you work on, you get to rate the current feature set and rank the importance of new features the team's working on: tooling, more controls, performance.

When was the last time you did anything anonymous on the internet so quick ?

It's hard to believe that the JVM Language Summit is only a year old, and the recent second iteration appears to have been a great success.

Hopefully soon you'll be able to watch the talks online, like last year's, but in the meantime all the talk materials are online, and there are some home video style vignettes here. For a concise written summary, take a look at these short summaries of day one, day two, and day three. All the LOLs and OMGs are archived here. Organizer and JSR 292 lead John Rose was inspired by the Greats, even as sartorial inspiration was reportedly in shorter supply.

As you will hear on the Java Posse, language success comes with great responsibility: Noop take heed. This new language (No-awp) for the JVM (or the idea of one) was introduced; the dust is still settling as to whether this year's Fan is going to storm the developer world, or just its own coffee cup.

Is mobile handset differentiation based on hardware coming to an end?

Back in 2007 I wrote a piece on my blog titled: The future of handset design: from hardware to software. And today this is getting more real (and validated) than ever.

When it comes to mobile handsets the rate of innovation introduced via hardware (HW) vs. sofware (SW) is and will be mainly on the SW side.

Differentiation, especially on common platforms (such as Android), will be primarily driven by SW, this is: Innovation on UIs and interface paradigms (on Android we can see this with the introduction of Moto Blur and HTC Sense), better applications (developer ecosystem adding lots of application that in turn adds to the usefulness of the handset), and better services (some phones will be very good at social things, while others at music, and so on). At the end it is SW what makes the handset more dynamic and useful and different.

Today is a great time for those doing R&D in the areas of Human-Computer Interactions (HCI).

Differentiation is necessary. But typically differentiation drives fragmentation. So the follow-up big question is on the fragmentation introduced by the different UI paradigms. Will applications need to be adapted to each new paradigm (i.e. as in many versions?). Yes, very likely.

Developers writing SW for the iPhone only have one paradigm to worry about. On the Android though, as expected we are seeing different UI paradigms (with related APIs) but fortunately the rest of the platform should remain consistent across manufacturers so fragmentation is hopefully localized to the UI only. For mobile Java (beyond Android) fragmentation is yet to be solved. For mobile web and widgets, the same although I am seeing a lot of noise around the JIL Widget SDK.

Fragmentation across platforms will continue. Fragmentation within a single platform shall be localized to the user interface (or the user interactions). Allowing for the UI to be redefined/reconfigured allows for incredible innovation on human to machine interactions which basically redefines the perception for a given handset. The next best thing is re-configurable software and hardware, but for that you will have to go play with platforms such as Bug Labs (which BTW is an extremely cool platform).

ceo

(Images sources: PopSci, Nokia, HTC Phones, Benzinga)