scene2d.ui has been using TableLayout for a long time. TableLayout sizes and positions actors using a logical table, similar to HTML tables. The resulting layout does not (usually) use pixel coordinates, so it automatically adapts to different resolutions. It can also scale positions, sizes, padding, etc based on the screen density. It is an extremely convenient way to position UI widgets. If you are manually doing the math to calculate widget positions, TableLayout is highly suggested. Once you learn the API, you can use it for libgdx, Android, Swing, and TWL.
Beyond just layout using a table, one of the big ideas in TableLayout was a DSL (domain specific language) for describing UI widget hierarchies. Writing layouts in code is flat. It is difficult to see the hierarchy in complex layouts that have a lot of nesting. Describing layouts in XML is a huge pain, and JSON isn’t much better. The TableLayout DSL put a minimal amount of cruft around the important bits. In the beginning it only allowed layout, using the half dozen or so TableLayout constraints. Features were added to reduce the amount of Java code by allowing more to be described in the DSL. Eventually it could do object creation, set field and bean properties, and more. The DSL syntax was still relatively simple, but the extra features certainly didn’t help new users get started.
Unfortunately, it turns out that the usefulness of the DSL is limited. Very often with a complex UI, portions of it are dynamic. Eg, sections A, B, or C are optionally shown based on some state, or you have a table or other container that has items added by code. The DSL can describe the main structure and then code can fill in the rest, but this ends up being awkward. When a large portion of the UI is built by code, the DSL no longer makes sense for the minimal remaining structure. At this point you are back to the Java API and probably would have saved time if you started there.
As TableLayout got used for a few big apps, the Java API has started to look very similar to the DSL. It is still flat, but specifying constraints is quite concise by using a builder pattern. Constraints can be specified for all cells, all cells in a column, all cells in a row, or for an individual cell. This greatly reduces repeating yourself. Here’s a quick example:
Table table = new Table(); table.pad(10).defaults().spaceBottom(10); table.row().fill().expandX(); table.add(button).fill(false); table.add(buttonMulti); table.add(imgButton); table.add(imgToggleButton); table.row(); table.add(checkBox); table.add(slider).width(100).fillX().colspan(3).left();
With the recent scene2d updates, I thought it was time for a TableLayout refuctoring. The DSL has been removed, along with a TON of support code, leaving only the Java API. It’s a little sad because it was a lot of work and very powerful — it even had an editor for the DSL, with syntax highlight and realtime rendering of the layout. Ultimately though, I came to the conclusion the DSL isn’t the right way to go. Implementing the DSL positively affected the Java API in many ways, so not all is lost.
A few other TableLayout changes have been made. All the int values have been changed to float. Also, it no longer parses strings for constraints. Instead, there is a Value interface, which can be implemented to compute a value however you like. This is a lot more flexible and avoids allocation. Setting the logical table size is gone, it was rarely needed and confused people. The scaling property is gone, it is replaced with the flexibility offered by Value.
These changes only affect the libgdx scene2d-new branch. If you use TableLayout, this is your heads up about the changes! The branch will likely be merged into trunk in the next few days.
Edit: The TableLayout documentation is now up to date. It has been completely rewritten.