Wednesday, June 15, 2011

LWUIT's New Layout Animation Facility


I'd like to create some more demo animations and some additional animation utilities like this one and I probably will as soon as I get some time.

While the animations in this video might seem elaborate, they are really simple to achieve and work great even on feature phones. All that is really needed is one LWUIT method: Container.animateLayout(int)

To understand this I'll just explain a couple of things about LWUIT components, when we add a component to a container its generally just added but not positioned anywhere. A novice might notice the setX/Y/Width/Height methods on a component and just try to position it absolutely.
This won't work since these methods are meant for the layout manager which it implicitly invoked when a form is shown (internally in LWUIT) and the layout manager uses these methods to position the components as it sees fit.
However, if you add components to LWUIT on your own it is your responsibility to invoke revalidate (or layoutContainer) to arrange the newly added components. LWUIT doesn't "reflow" implicitly since that would be hugely expensive, imagine doing the layout calculations for every component added to the container the cost would be closer to a factorial of the original cost of adding a component.

The animateLayout() is simply a fancy form of revalidate. After changing the layout when you invoke this method it will animation the components to their new sizes and positions seamlessly.

The first example in the tipster demo shows an "interlace" effect where the components each slide from a separate direction into the screen.  This is the code I used before showing the form:

        f.revalidate();
        for(int iter = 0 ; iter < c.getComponentCount() ; iter++) {
            Component current = c.getComponentAt(iter);
            if(iter % 2 == 0) {
                current.setX(-current.getWidth());
            } else {
                current.setX(current.getWidth());
            }
        }
        c.setShouldCalcPreferredSize(true);
        c.animateLayout(1000);

Lets go over this line by line:

        f.revalidate();
I make sure the layout is valid so I can start from the correct component positions.

            if(iter % 2 == 0) {
                current.setX(-current.getWidth());
            } else {
                current.setX(current.getWidth());
            }
I manually position every component outside of the screen, if they are odd I place them to the right and if they are even I place them to the left.



        c.setShouldCalcPreferredSize(true);
I mark the UI as needing layout. This is crucial since I validated the UI earlier (by calling revalidate). Changing the X/Y/Width/Height doesn't trigger a validation! LWUIT doesn't know I made that change!
By calling setShouldCalcPreferredSize I'm explicitly telling LWUIT that I changed something in the UI and I want it to validate, normally this method is implicitly invoked by LWUIT.

        c.animateLayout(1000);
Perform the animation over the length of a second, this might seem like much but the animation starts before the form entry transition so it isn't that much.

The other animations are even simpler than this one and all follow the same basic rules, place the components wherever you want either manually (or by changing the layout) and use animateLayout() to automatically rearrange them to the new position.


BTW we fully intended to have a new LWUIT release by now but its getting delayed due to the typical bureaucratic nonsense that is an unavoidable reality within a large corporation. We apologize it is taking so long and even more so that we do not have an ETA. Those of you following the SVN know we already have everything ready for 1.5.

Thursday, June 9, 2011

Interesting Couple Of Weeks

This post isn't about LWUIT, its about Java on the desktop and its current direction. Microsoft just introduced Windows 8, for those of you who haven't been following here is the gist:
Run's on Arm (as well as Intel obviously), Completely new touch/gesture based UI, less emphasis on Windows.

Apple also introduced Tiger (next Mac OS X), which also focuses more on full screen applications as well as eliminates the scrollbar... Mac OS X will now scroll like the iPhone and hide the scrollbar when it isn't used.
Rumors are also abundant about Apple's laptop line moving to Arm chips which they can easily do since they have a fat binary .app directory structure (which MS doesn't have).

To me these things signal a massive UI convergence trend where the mobile UI takes the lead. Up until now mobile UI's were influenced by desktop paradigms and now we finally see the reverse coming on in full force.

Where does this leave Java developers?

Swing hasn't been moving forward for quite a while now & Java FX isn't even in production and already it seems behind the curve on these sort of features. I'd love to say that LWUIT can take over but right now we still don't have many of the features necessary to write full scale desktop apps...
However, I would say that this is a great time to be a mobile developer since an upheaval is on its way and it seems that we are leading the pack.

This sort of convergence also means a huge migration to the cloud, when using multiple mobile devices its just impossible to sync them in any other way. Even those reluctant about privacy and security would probably shift to the cloud to remain competitive.

Monday, June 6, 2011

LWUIT Timeline Tutorial Video Part One


This one required tremendous amounts of work to make and I still didn't finish. Since its quite a long video I have some doubts on whether people will have the energy to watch it all the way through and follow up to part two.
This actually goes most of the way in creating the theme for the t-zone demo (which is now in the LWUIT SVN), if I do the second part it will continue from where I left off all the way to creating the actual code backing this.

BTW I uploaded a new binary of the resource editor today, this new version includes theme templates based both on this theme and on the Tipster demo theme. Check them out and please improve your UI designs accordingly ;-)

Wednesday, June 1, 2011

Martin Is On Fire: New LWUIT Tipster Demo


Martin (our designer) has finally come through with two professionally designed demos in a row, showing off the difference a proper designer makes when building such applications. He cranked the designs for these ridiculously fast and once I had the designs in place it reduced allot of the doubt of designing. Overall I got the design yesterday morning and now the video is on youtube... I will commit the code to SVN in a few hours (hopefully).
I already committed the code for Martin's previous t-zone demo which I've been showing around a bit and getting allot of surprised reactions from people. It just goes to show you how far the effect of a good UI designer can take your UI regardless of the technology you are using.

We are trying to get a release up to speed so I don't have the time to do the tutorials but I would like to get detailed step by step "how to" tutorials explaining exactly how I implemented both applications.

Sunday, May 29, 2011

Preview Of The New LWUIT Friends t-Zone Demo


This demo is coming soon, full source code and everything. It doesn't really have much source code since the whole thing was created in the GUI builder with very little code. I hope to also create a tutorial showing off exactly how this demo was made.
BTW If you have a stack overflow account please go to this question and vote up my answer, its amazing how the worst possible LWUIT screenshots could be picked off this blog... Frankly its also a bit of my fault since finding proper screenshots of newer applications (not videos) is a bit hard. I should get on to that.

Wednesday, May 25, 2011

Clicking Within A Cell Renderer

One of the things people looked for quite often in Lists was the ability to click on a specific element within a ListCellRenderer to get an event specific to that element. E.g. a list with X's drawn on the side to remove the element.
In the past we contended that since the list is stateless its impossible for us to provide such information and recommended people use a Container with items. We now have a solution which works only for touch devices, this feature allows adding a listener to a component within the renderer which will now trigger an event if the component is touched.
Notice that the component will not contain the right data since the list selection indicates the actual selection, however if you add a listener to a button containing the X you should get an action event on that button before the list action event. This will allow you to toggle a flag indicating that the X was pressed and not a different portion of the renderer.
This isn't ideal but since the list is stateless this is the best we could come up with.

Assuming you used the GUI builder & GenericListCellRenderer you can use the method GenericListCellRenderer.extractLastClickedComponent() in the action listener for the list to get the button that was pressed to generate this event or null if no button was pressed.

I apologize for the lack of videos recently, we are working very hard towards a LWUIT release in June (hopefully, bureaucracy is always our foe) so I don't have quite the same amount of cycles to dedicate for proper blogging. I'll try to get something decent going soon.

Wednesday, May 18, 2011

Logging & Caching In LWUIT4IO

We've been quite busy with holidays and Chen going off to JavaOne in India so I didn't have as much time to blog as I normally do or prepare the videos I should be working on. Hopefully I'll recover some time soon and be able to get back to my normal pace.
In recent LWUIT SVN's I deprecated and effectively removed the venerable log class. The main motivation behind that is the fact that logging didn't go through the platform code and never made sense in LWUIT. It was hardcoded for MIDP and had many issues.

That class is replaced by an almost identical class within LWUIT4IO which has similar functionality with a few cool new features. First, it can run on all platforms including Java SE, RIM, MIDP and even Thorsten's new Android port of LWUIT4IO.
Then it has one more "killer feature", it can track file IO seamlessly!

Unlike J2SE, most mobile platforms are really sensitive regarding forgotten streams and its essential to close every stream you open. The problem is that its often really hard to keep track in a large application that deals with many dynamic files constantly. However, since all LWUIT4IO streams are buffered it can easily tell when a stream is opened/closed or double closed. This gets logged automatically if you invoke Log.getInstance().trackFileSystem() which will cause entries to appear in your log containing the URL opened/closed and the number of open streams. This feature helped me in tracking some pretty hairy bugs.

Another feature in LWUIT4IO to which I didn't give enough spotlight is the cache map, its effectively a lean hashtable which stores its data using weak/soft references (depending on the platform) and falls back to storage when not enough memory is available. Its a great way to cache data without going overboard.
One of the cool things about it is the fact that we use it seamlessly for our storage abstraction (which hides RMS or equivalent services) in effect providing faster access to RMS storage which is often slow on devices.

While writing on that subject it dawned on me that I never blogged about our "seamless" serialization support in LWUIT4IO. The Storage class and util class contain methods for reading/writing of objects. All the basic JavaME data types should be supported including: primitive arrays, Strings, Object arrays, Hashtable's and vectors. Arbitrary objects can be stored by implementing com.sun.lwuit.io.Externalizable. This allows easy/efficient persistence and networking between applications.
Give these features a try and let us know how they work for you.

As a side note: due to recent issues with the forum/mailing list that unfortunately remain unresolved to this moment I decided to start answering issues in stack overflow which has a great LWUIT section.