LWUIT will be featured in 5 different JavaOne 2009 sessions/bof's which is pretty cool considering it will be one year old in the market by then. You can find out all of them by searching for LWUIT in the JavaOne content catalog.
A session & BoF will be presented by myself and Chen, the session will aim to create a more "wow' sort of effect presenting what can be done to create compelling portable UI's in LWUIT. I hope I still have enough tricks up my sleave to impress a jaded audience that already saw the stuff in the blog...
The BoF will probably aim to be a more open discussion although we will try to provide a guiding theme. Other than that there are quite a few other places to see LWUIT in JavaOne including Tamir's session for interactive TV development. Tamir is our "go to guy" for LWUIT on TV/CDC and I'm sure his session will be pretty cool especially if you are thinking of taking your skills into the realm of TV.
Tuesday, March 24, 2009
Wednesday, March 18, 2009
Breaking To Make Things Better
The side image to the post has nothing to do with the post, just a screenshot of the new MajiPic application from majimob.
Our stance on API backwards compatibility has always been to try as hard as possible but no more than that. When we find design mistakes, even painful ones we choose to cut them down and fix them even with a compatibility issue especially when the potential benefits are noticeable.
We are now in the process of fixing a mistake in Styles in regards to the fgSelection/bgSelection properties. We intend to make two potential styles for every component: Selected and unselected.
Let start with the practical terms... We would have three methods to get/set style in LWUIT's components: getStyle(), getSelectedStyle() & getUnselectedStyle().
The getStyle() method will return the selected/unselected style based on the focus state of the component so you will no longer have to write:
if(hasFocus()) {
color = getStyle().getFgSelectionColor();
} else {
color = getStyle().getFgColor();
}
Instead this will work pretty much as you would expect:
color = getStyle().getFgColor();
This would also mean that get/set*SelectionColor would now be deprecated. But this goes deeper still, we have some various hacks such as focus/pressed borders which will now be deprecated as well.
This is pretty revolutionary and we intend to offer a migration path to ease the pain, the Style class would have a compatibility mode flag which will implicitly synchronize the selected/unselected styles. Furthermore, calling the selected color methods will try to "do the right thing" for most use cases.
However, we are doing this for a reason and this compatibility will break if you try to leverage the newer features enabled by this change such as the newer LWUIT Designer (resource editor). This would allow designers to define far more elaborate themes with the LWUIT Designer including complex backgrounds depending on component state (we intend to offer "meta-styles" as well but this isn't finalized). If you will use the newer version of the LWUIT Designer you will be forced to disable compatibility mode which will naturally break these features. We feel that this new approach is far more intuitive and powerful!
Following is a short mini faq for this change with questions Chen and myself raised about this feature:
Q: Won't it increase the overhead to add a selected style for every component?
A: Selected styles are created lazily and so won't exist for most components, they will only be created when the component actually gets the focus. Even then, this would be more efficient since it would allow to generalize more code and reduce application size.
Q: How comitted are you to the current compatibility layer?
A: We assume some use cases will break even with the compatibility turned on (which would be the default in the immediate future), when possible we will try to get the compatibility working properly but we won't bend over backwards for that.
Q: Will you drop compatibility and if so when?
A: We defined the compatibility methods as deprecated, however there is no defined timeline. Once the code is available we will poll the community about the usage of compatibility and remove it when we feel migration is successful.
Q: When will this land?
A: It won't land next week. Probably.
I hope to commit by the end of the month but can't guarantee. We will also need the new LWUIT Designer to really take advantage of this feature. The delay is mostly because this change is a part of a major restructuring related to the LWUIT Designer as well and this takes quite some time...
Our stance on API backwards compatibility has always been to try as hard as possible but no more than that. When we find design mistakes, even painful ones we choose to cut them down and fix them even with a compatibility issue especially when the potential benefits are noticeable.
We are now in the process of fixing a mistake in Styles in regards to the fgSelection/bgSelection properties. We intend to make two potential styles for every component: Selected and unselected.
Let start with the practical terms... We would have three methods to get/set style in LWUIT's components: getStyle(), getSelectedStyle() & getUnselectedStyle().
The getStyle() method will return the selected/unselected style based on the focus state of the component so you will no longer have to write:
if(hasFocus()) {
color = getStyle().getFgSelectionColor();
} else {
color = getStyle().getFgColor();
}
Instead this will work pretty much as you would expect:
color = getStyle().getFgColor();
This would also mean that get/set*SelectionColor would now be deprecated. But this goes deeper still, we have some various hacks such as focus/pressed borders which will now be deprecated as well.
This is pretty revolutionary and we intend to offer a migration path to ease the pain, the Style class would have a compatibility mode flag which will implicitly synchronize the selected/unselected styles. Furthermore, calling the selected color methods will try to "do the right thing" for most use cases.
However, we are doing this for a reason and this compatibility will break if you try to leverage the newer features enabled by this change such as the newer LWUIT Designer (resource editor). This would allow designers to define far more elaborate themes with the LWUIT Designer including complex backgrounds depending on component state (we intend to offer "meta-styles" as well but this isn't finalized). If you will use the newer version of the LWUIT Designer you will be forced to disable compatibility mode which will naturally break these features. We feel that this new approach is far more intuitive and powerful!
Following is a short mini faq for this change with questions Chen and myself raised about this feature:
Q: Won't it increase the overhead to add a selected style for every component?
A: Selected styles are created lazily and so won't exist for most components, they will only be created when the component actually gets the focus. Even then, this would be more efficient since it would allow to generalize more code and reduce application size.
Q: How comitted are you to the current compatibility layer?
A: We assume some use cases will break even with the compatibility turned on (which would be the default in the immediate future), when possible we will try to get the compatibility working properly but we won't bend over backwards for that.
Q: Will you drop compatibility and if so when?
A: We defined the compatibility methods as deprecated, however there is no defined timeline. Once the code is available we will poll the community about the usage of compatibility and remove it when we feel migration is successful.
Q: When will this land?
A: It won't land next week. Probably.
I hope to commit by the end of the month but can't guarantee. We will also need the new LWUIT Designer to really take advantage of this feature. The delay is mostly because this change is a part of a major restructuring related to the LWUIT Designer as well and this takes quite some time...
Sunday, March 8, 2009
Validating And The Art Of GlassPane
The GlassPane in LWUIT is inspired by the Swing GlassPane & layered pane with quite a few twists (note: the picture on the right is of the Swing glass pane, I didn't have the energy to make one of my own)... We tried to imagine how Swing developers would have implemented the glass pane knowing what they do now about painters and Swings learning curve. But I'm getting ahead of myself, what is the glass pane?
A typical LWUIT application is essentially composed of 3 layers (this is a gross simplification though), the bg painters are responsible for drawing the background of all components including the main form. The component draws its own content which might overrule the painter and the glass pane paints last...
Essentially the glass pane is a painter that allows us to draw an overlay on top of the LWUIT application. Initially we didn't think we need a glass pane, we used to suggest that people should override the form's paint() method to reach the same result. Feel free to try and guess why this failed before reading the explanation in the next paragraph.
Overriding the paint method of a form worked initially, when you enter a form this behaves just as you would expect. However, when modifying an element within the form only that element gets repainted not the entire form! So if I had a form with a Button and text drawn on top using the Form's paint method it would get erased whenever the button got focus.
Thats good for the forms paint method, calling the forms paint method would be REALLY expensive for every little thing that occurs in LWUIT. However, we do want overlays for some things and we don't need to repaint every component in the screen to get them. The glass pane is called whenever a component gets painted, it only paints within the clipping region of the component hence it won't break the rest of the glass pane.
The painter chain is a tool that allows us to chain several painters together to perform different logistical tasks such as a validation painter coupled with a fade out painter. The sample bellow shows a crude validation panel that allows us to draw error icons next to components while exceeding their physical bounds as is common in many user interfaces
A typical LWUIT application is essentially composed of 3 layers (this is a gross simplification though), the bg painters are responsible for drawing the background of all components including the main form. The component draws its own content which might overrule the painter and the glass pane paints last...
Essentially the glass pane is a painter that allows us to draw an overlay on top of the LWUIT application. Initially we didn't think we need a glass pane, we used to suggest that people should override the form's paint() method to reach the same result. Feel free to try and guess why this failed before reading the explanation in the next paragraph.
Overriding the paint method of a form worked initially, when you enter a form this behaves just as you would expect. However, when modifying an element within the form only that element gets repainted not the entire form! So if I had a form with a Button and text drawn on top using the Form's paint method it would get erased whenever the button got focus.
Thats good for the forms paint method, calling the forms paint method would be REALLY expensive for every little thing that occurs in LWUIT. However, we do want overlays for some things and we don't need to repaint every component in the screen to get them. The glass pane is called whenever a component gets painted, it only paints within the clipping region of the component hence it won't break the rest of the glass pane.
The painter chain is a tool that allows us to chain several painters together to perform different logistical tasks such as a validation painter coupled with a fade out painter. The sample bellow shows a crude validation panel that allows us to draw error icons next to components while exceeding their physical bounds as is common in many user interfaces
public class ValidationPane implements Painter {
private Vector components = new Vector();
private static Image error;
public ValidationPane(Form parentForm) {
try {
if(error == null) {
error = Image.createImage("/error.png");
}
} catch (IOException ex) {
ex.printStackTrace();
}
PainterChain.installGlassPane(parentForm, this);
}
public void paint(Graphics g, Rectangle rect) {
for(int iter = 0 ; iter < components.size() ; iter++) {
Component c = (Component) components.elementAt(iter);
if(c == null) {
components.removeElementAt(iter);
continue;
}
Object p = c.getClientProperty(VALIDATION_PROP);
int x = c.getAbsoluteX();
int y = c.getAbsoluteY();
x -= error.getWidth() / 2;
y += c.getHeight() - error.getHeight() / 2;
g.drawImage(error, x, y);
}
}
public void addInvalid(Component c) {
components.addElement(c);
}
public void removeInvalid(Component c) {
components.removeElement(c);
}
}
Monday, March 2, 2009
Chen Just Updated The Featured Apps section
Chen just updated the featured apps section of the LWUIT web site to include more recent applications. We hear of many applications developed in LWUIT but often we aren't given explicit permission to use screenshots and resources related to the application.
If you have developed a good looking LWUIT based application which isn't highlighted in the featured applications section please let us know by writing to lwuit at sun.com with screenshots, a short descriptive blurb about the application and optionally a link for further details.
If you wrote to us a while back but you are not on the page please write to us again, as engineers we tend to suck in this marketing related efforts so please bare with us...
If you have developed a good looking LWUIT based application which isn't highlighted in the featured applications section please let us know by writing to lwuit at sun.com with screenshots, a short descriptive blurb about the application and optionally a link for further details.
If you wrote to us a while back but you are not on the page please write to us again, as engineers we tend to suck in this marketing related efforts so please bare with us...
Subscribe to:
Posts (Atom)