Monday, October 12, 2009

LWUIT Binaries Are Now At java.sun.com Only

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.

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.

Wednesday, September 30, 2009

LWUIT Virtual Keyboard - by Chen Fishbein

Touch devices are relatively a new trend in mobile and almost every manufacturer has released a Touch device lately.
Although LWUIT supports touch events out of the box, there are a few things you need to consider when you develop for a touch screen device.
One of the major issues is the device Virtual Keyboard, every device has it's own Virtual Keyboard and there is no standard API to popup the device Virtual Keyboard.
In the past year we got tons of requests to create a LWUIT virtual keyboard, so expect to see this as part of LWUIT 1.3 (the code is already committed to the workspace, so if you work directly with the sources you can see the code already there).

To use the Virtual Keyboard call:

VKBImplementationFactory.init();
Display.init(this);

This implementation provides some basics input modes such as "Qwerty, symbols and numbers", but a developer can extend this easily and add his own input mode including different languages.


Thursday, September 24, 2009

New Components In LWUIT


We are working full steam ahead towards LWUIT 1.3 and have gotten several of the key features in LWUIT 1.3 already into the SVN. We implemented a tree component very similar to the one mentioned in a previous post in this blog and now I committed yet another major component a table component.
Unlike our list which we discussed several times before this time we chose to go with the composite approach for building elaborate components. Our general thought process is that these components are elaborate and would include complex editing, while the list is more of a selection component designed for scalability.

Here is a minor sample of using the standard table component, it should be pretty self explanatory:
final Form f = new Form("Table Test");
TableModel model = new DefaultTableModel(new String[] {"Col 1", "Col 2", "Col 3"}, new Object[][] {
{"Row 1", "Row A", "Row X"},
{"Row 2", "Row B", "Row Y"},
{"Row 3", "Row C", "Row Z"},
{"Row 4", "Row D", "Row K"},
}) {
public boolean isCellEditable(int row, int col) {
return col != 0;
}
};
Table table = new Table(model);
table.setScrollableX(true);
f.setLayout(new BorderLayout());
f.addComponent(BorderLayout.CENTER, table);
f.show();
However, IMO the more "interesting" aspect of the table is the table layout and its ability to create rather unique layouts relatively easily similarly to HTML's tables. You can use the layout constraints (also exposed in the table class) to create spanning and elaborate UI's.
In order to customize the table cell behavior you can now derive the table to create a "renderer like" widget, however unlike the list this component is "kept" and used as is. This means you can bind listeners to this component and work with it as you would with any other component in LWUIT.

Saturday, September 19, 2009

LWUIT Finally On java.sun.com


LWUIT is now finally featured among other prominent Java ME technologies in its own page on java.sun.com. Its been a great ride taking LWUIT from a small project that Chen started on the side and seeing it materialize.

Sunday, September 13, 2009

Lost Again: Searchable List With Text Field

I'm really excited about the final season of Lost as is probably evidence by this and my previous demo on the subject, the new demo celebrating the upcoming season is now within the incubator SVN and in the video on youtube to your right.
This demo shows off an ability often requested by people, searching within a list without actually using a text field that "steals" the focus. As you can see a standard LWUIT text field is drawn on top of the List and accepts user input as it always does thus allowing me to narrow my search within a large unordered list.
This is accomplished rather easily by painting the text field on top of the list and redirecting game key events to the list while all others are sent to the text field.

The text field is hidden after 1000 milliseconds of no activity, no need for glasspane or anything of that magnitude. You do need the latest LWUIT trunk for this to work since text field assumed it has a parent from when getting input (which isn't the case here). To workaround this you can override install/remove commands in text field with an empty implementation.

List l = new List(LIST_DATA) {
private long lastSearchInteraction;
private TextField search = new TextField(3);
{
search.getSelectedStyle().setBgTransparency(255);
search.setReplaceMenu(false);
search.setInputModeOrder(new String[]{"Abc"});
search.setFocus(true);
}

public void keyPressed(int code) {
int game = Display.getInstance().getGameAction(code);
if (game > 0) {
super.keyPressed(code);
} else {
search.keyPressed(code);
lastSearchInteraction = System.currentTimeMillis();
}
}

public void keyReleased(int code) {
int game = Display.getInstance().getGameAction(code);
if (game > 0) {
super.keyReleased(code);
} else {
search.keyReleased(code);
lastSearchInteraction = System.currentTimeMillis();
String t = search.getText();
int modelSize = getModel().getSize();
for(int iter = 0 ; iter < modelSize ; iter++) {
String v = getModel().getItemAt(iter).toString();
if(v.startsWith(t)) {
setSelectedIndex(iter);
return;
}
}
}
}

public void paint(Graphics g) {
super.paint(g);
if (System.currentTimeMillis() - 1000 < lastSearchInteraction || search.isPendingCommit()) {
search.setSize(search.getPreferredSize());
Style s = search.getStyle();
search.setX(getX() + getWidth() - search.getWidth() - s.getPadding(RIGHT) - s.getMargin(RIGHT));
search.setY(getScrollY() + getY());
search.paintComponent(g, true);
}
}

public boolean animate() {
boolean val = super.animate();
if(lastSearchInteraction != -1) {
search.animate();
if(System.currentTimeMillis() - 1000 > lastSearchInteraction && !search.isPendingCommit()) {
lastSearchInteraction = -1;
search.clear();
}
return true;
}
return val;
}
};

Wednesday, September 9, 2009

New Stuff In LWUIT - Heading To 1.3

I recently committed some code signifying the direction LWUIT is now taking towards our 1.3 release and hopefully towards a more organized development plan that would include more official releases with predefined features. Some of the major changes going into 1.3 are already beginning to appear and some of the other architectural changes are already drawn in the sand.
One major change is that we now removed the compatibility mode for the old style syntax, to migrate into 1.3 you would need to update your code to use the new approach to styles. Normally we would keep compatibility indefinitely however since LWUIT needs to be packaged into your application on the mobile device the size issue becomes very relevant and we think removing features such as these is essential for trimming the application sizes. LWUIT grew noticeably over the past few years which is naturally inevitable however we intend to keep it trim and fit for devices despite newer features.

Other than that the current JWS version of the LWUIT designer finally allows adding SVG files to resources, LWUIT will show them as standard PNG's however if you use LWUIT's SVG Implementation factory and your device supports SVG you will get the full benefit of SVG support within LWUIT! Our goal is to provide seamless migration allowing developers to shift their code to SVG while keeping 100% compatibility with existing device and a single binary! Ambitious but so far it seems that it works...

Another major feature making its way into LWUIT is the table component, this will be an elaborate component from which you can pick and choose functionality as you go along. The first portion of the Table is already committed and its the table layout class. Its pretty much what it sounds allowing you to layout components as you would a table with support for the spanning of rows/columns using table constraints. I tried to make it simpler than Gridbag, I hope I was successful in that but its indeed a complex component...

We have some more things up our sleeve for LWUIT I will try to keep you posted on all of these changes as they occur.