Structuring Java code that assembles a UI

Saturday, November 1st, 2008 | Uncategorized

I’m dong some GWT coding today, which is a lot like writing Swing. It’s very procedural. Create a new UI element, then call methods on it to set up the state. Even when you do the right thing and split your UI into many Composite classes, you get something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
StackPanel stackPanel = new StackPanel();
stackPanel.add(new Label("Recently Eaten"));
stackPanel.add(new Label("Manual Entry"));
stackPanel.add(new Label("Search the database"));
 
DockPanel panel = new DockPanel();
panel.add(stackPanel, DockPanel.CENTER);
 
FlowPanel buttonsPanel = new FlowPanel();
buttonsPanel.add(new Button("Done"));
buttonsPanel.add(new Button("Next"));
 
panel.add(buttonsPanel, DockPanel.SOUTH);

This is really annoying. The order of assembly is important, but it’s also very arbitrary. I’m creating my DockPanel before my FlowPanel, but you should always declare variables in the narrowest scope possible (item 45 in Effective Java). On the other hand, maybe I want to finish referring to my StackPanel, adding it to the parent, before I create my FlowPanel. Also, it’s easy to make a mistake here. I might accidentally add something to the wrong parent container, if the variable names are similar, and there isn’t a good way to test this code aside from inspecting the UI visually.

Maybe Java is just not a good language to express this UI layout, but for now I considered an under-used construct, inline instance initialization blocks:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
final StackPanel stackPanel = new StackPanel() {{
  add(new RecentlyEatenPanel(), "Recently Eaten");
  add(new ManualEntryPanel(), "Manual Entry");
  add(new DatabaseSearchPanel(), "Search the database");
}};
 
final FlowPanel buttonsPanel = new FlowPanel() {{
  add(nextButton);
  add(doneButton);
}};
 
DockPanel panel = new DockPanel() {{
  add(stackPanel, DockPanel.CENTER);
  add(buttonsPanel, DockPanel.SOUTH);
}};

This is kind of cool – the structure is certainly more evident in this code. The extra braces define an initializer that is copied into each constructor – see the Sun tutorial. I assume that the code in the initializer block executes after the constructor has finished its work, so we can depend on the add() method having a place to do its work.

The limitations: this creates a subclass, so you can’t use it to initialize fields in a final class. Also, as you see, any variables must be declared final to be used in the initializer block, just like with any anonymous inner class.

Links:

Here’s a clever DSL to build the GUI in a “fluent” way: http://www.pathf.com/blogs/2007/09/expressing-rich/

And a project to use Flex-style XML to configure the layout: http://code.google.com/p/gwt-ui/

1 Comment to Structuring Java code that assembles a UI

jonathan wolter
August 20, 2009

Watch out though for memory leaks when using this clever trick. It hit us a while back, http://jawspeak.com/2009/03/10/using-these-anonymous-inner-classes-is-probably-too-clever-for-your-own-good/

Leave a comment

About Me

I'm Alex Eagle. I live in Sunnyvale, CA and I'm a code monkey.

eag...@captcha.me
LinkedIn.com/in/AlexEagle
Twitter.com/jakeherringbone

Add to Google Reader or Homepage

 Subscribe in a reader

Tweets

  • @LaChilangringa thank you, he will be called Walter and might like trains or frogs. You were at the rally? What did your sign say? in reply to LaChilangringa 2010-11-06
  • It says I'm not eligible to get a payout in the Buzz settlement. I'll have to settle for juggling with the Buzz developers. :) 2010-11-03
  • It's Movember and you can sponsor my mustache. http://goo.gl/Z1O4 I miss the beard; It's very drafty on my face today. 2010-11-02
  • Can 4 guys make themselves look enough like Mount Rushmore to fool Google Goggles image search? Love the demo slam. http://demoslam.com 2010-10-20
  • Saw Dalai Lama on Thurs, running last 6mi of SF women's marathon with Peggy today. Too many crazy crowds this week! 2010-10-17
  • Attn: people of the future. We wanted to avoid all that litter! It was our 2nd priority, right after annoying noises. http://bit.ly/cJzkGT 2010-10-09
  • Headed to Hardly Strictly bluegrass in GG park. Elvis Costello free! 2010-10-03
  • I vote that @TCooganPlants is having a rough week and deserves nachos. Who's with me? 2010-09-29
  • More updates...

Powered by Twitter Tools