My very first post in this blog (May 2008) was about creating a progress indicator component. At the time LWUIT only had one style per component and the post was mostly about threading in LWUIT. Over that time we considered adding a progress indicator component frequently but had a very difficult issue with its customization. How can we create a component which is both powerful enough for general usage and not too restricted for the various use cases.
Enter the new Slider component which thanks to some advantages such as the multiple styles is far more powerful than the original and it is now a part of LWUIT. The slider can be manipulated like a gauge to control elements such as volume, it can be used to indicate position (with a text overlay inherited from Label) and it can be customized in pretty much any way imaginable.
The demo you see to your right is ridiculously simple containing 3 such sliders, the top and middle one are identical with the middle one adding a status overlay. The bottom slider is set for infinite progress support which is useful to indicate a "please wait" status.
To create such a theme I just customized the "Slider" and "SliderFull" styles with a border for the full state and the empty state (essentially the squares in the center are just the style of SliderFull painted on top of a style of Slider).
Normally I try to keep my blog posts on the technical or showcase side but for a change I want to share some general thoughts I have about the state of LWUIT and the recent enlightening poll on this blog and the javalobby.
While there is still a day to go with our poll as I write this, the results are quite interesting and not what I expected. Although in retrospect they make sense, after all this is a blog for an open source project so it makes sense that most of you would vote to open source FX. However, the blog poll otherwise is almost identical to the JavaLobby poll in the sense that 70% of the votes voted for either open sourcing FX or giving up on it altogether (visitors to the JavaLobby preferred giving up on FX while visitors to this blog preferred open sourcing). This got me thinking a bit, is this the typical knee jerk reaction of "open sourcing will solve everything" or is there something specific in JavaFX that you saw and would want it to be open source? Please be specific in the comments and if possible try to describe the experience you have with FX.
On to a completely different subject... I was talking to a friend in the states a while back about LWUIT's portability to various platforms. He claimed that portability is problematic since the native platform will come out with new features which the application will need to assimilate meaning a constant race against the native OS and constantly providing an inferior experience.
I attacked that notion with the "Highest Common Denominator" approach we are trying to instill using LWUIT. Most native OS's (even the shiny new ones) are ridiculously huge beasts with heavy dependencies that tend to stagnate immediately. Even a small change to the underlying GUI core will break at least 20% of the 3rd party applications and cause the applications shipping with the OS heavy maintainability costs...
Since LWUIT is statically linked changes to LWUIT don't break everything so we are bold in our changes where OS manufacturers are timid and fragmented...
This means that OS's don't activate big changes by default since these changes cause huge regressions. A great example is touch scrolling on Symbian phones that took quite a while to provide the proper kinetic/tensile drag feel you get from comparable devices or even Nokia's own N900.
However, LWUIT on Nokia devices provided kinetic and later on tensile drag on all Symbian touch phones including those that don't "officially" support this functionality. Essentially LWUIT provided features that are "superior" to the native platform thus escaping the original "lowest common denominator" issue of portable code and striking back with a higher baseline of functionality. This isn't limited to Symbian, I recently demonstrated "Android like" thumb scrolling in LWUIT which is in some ways superior to the native Android scrolling. It allows device rotation while scrolling, is fully customizable and still allows tensile lists...
A highest common denominator strategy is harder to maintain since it requires a developer keeps his vigil over new platform features to introduce them immediately. A developer must also work against the LWUIT trunk where the new features are introduced constantly to support such development. The benefit however is in the ability to carry these features to the platforms that are behind which puts the developer at a vantage point in those platforms.
We believe that LWUIT enables this strategy and we are working hard to make this strategy practically seamless to anyone using LWUIT, most of our work and improvements (e.g. the major style change in 1.2) is designed around this premise.
The guys at the JavaLobby asked "How Can Oracle Make JavaFX More Popular?", however the discussion seems to be hopelessly slanted towards the desktop crowd and a couple of Android related posts. I'm quite curious to see what the thoughts of the crowd visiting this blog which mostly focuses on mobile and LWUIT. So I added a poll to the top of the blog, please vote your heart and try not to stuff the ballots ;-)
Growing stuff is usually the subject filling my spambox... But into my inbox came a question from Terrence on how to grow a container. Generally what he wanted was an effect similar to the one found on Google maps (that you can see in the video right here). I tried to implement something like this in the most generic way possible which required a minor tweak to LWUIT (allowing us to restore the original preferred size of a component).
Generally the whole grow/shrink logic is contained in one method: "grow". Its relatively simple and just creates a motion between the current size of the component and the preferred size thus allowing the new component to "grow into place". The motion updates the preferred size and relayouts the form to create the smooth animation effect we see in the video.
I needed the ability to restore the default preferred size otherwise I would be stuck in the larger size after animating once. An alternative solution would have been to use a custom Container sublclass or to keep the original values stored neither one of which is my favorite...
Another "complexity" relates to the rather complex nature of preferred size, text area reports a relatively large preferred size before layout actually occurs. The reason is that it can't possibly know the target size of the container it will be placed in so it just guesses. So to support this situation I needed to layout the text area once in order to allow it to fit into place.
The code for this demo is in the incubator and pasted bellow:
publicclassGrowMidletextendsMIDlet{ privatestaticfinalStringLONG_TEXT_1="There is some text that should take more than one line to show so it will be cut off at some point when shown in a single line but when we show it as multiline it should work out and layout just fine and dandy... "; privatestaticfinalStringLONG_TEXT_2="Growing text can be longer or shorter, it can be placed in the middle of the screen or anywhere really this is quite generic!"; privatestaticfinalStringLONG_TEXT_3="Using this is as simple as pie with any container type you can think of and any text length!"; publicvoidstartApp(){ try{ Display.init(this); Resourcesr=Resources.open("/pimpTheme.res"); UIManager.getInstance().setThemeProps(r.getTheme(r.getThemeResourceNames()[0])); Formf=newForm("Grow Demo"); f.addComponent(createGrowingContainer(LONG_TEXT_1, "TextAreaMe")); f.addComponent(createGrowingContainer(LONG_TEXT_2, "TextAreaThem")); f.addComponent(createGrowingContainer(LONG_TEXT_3, "TextAreaMe")); f.show(); }catch(IOExceptionex){ ex.printStackTrace(); } }
publicvoidactionPerformed(ActionEventevt){ growingContainer.removeAll(); growingContainer.addComponent(BorderLayout.CENTER, multiLine); Containerflow=newContainer(); if(shrink.getParent()!=null){ shrink.getParent().removeAll(); } flow.addComponent(shrink); growingContainer.addComponent(BorderLayout.SOUTH, flow); // the first time around the text area doesn't report the correct preferred size // since it doesn't know its screen placement if(firstTime){ growingContainer.revalidate(); } grow(growingContainer); growingContainer.revalidate(); } }); shrink.addActionListener(newActionListener(){
The touch device Swipe gesture has been well supported on LWUIT from day one however strictly for the purpose of scrolling. Its pretty easy and common to implement the swipe for other uses such as paging through pictures but there users often want immediate feedback which is a bit harder.
Novices to LWUIT might think it makes sense to try and combine the swipe and transition, but that is probably not so practical since the transitions assume speed and structure (partially because they are generic and can slide between anything)...
This demo shows off Yoga posture pictures taken from beyoga.co.il (copyrighted!) in such a slide demo on the HD2. The code works well on pretty much any device with or without touch and is actually really simple to implement. I will commit it to my incubator directory soon: