Thursday, October 8, 2009

Coordinating That Layout

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.

3 comments: