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

  • I played the ice hockey for the second time in about 8 years. I was about as good as ever, I guess. Which was fairly bad. 16 hrs ago
  • I finally jailbroke an iPhone. Now I feel like I have decent geek cred again. 2 days ago
  • Lost a bolt on my lower control arm. Found out about it when the wheel came partly off. http://twitgoo.com/fw9e0 3 days ago
  • Wow we have the craziest channel 1.6 on broadcast TV where I live, that runs this show: http://intensit.tv/ 5 days ago
  • Dorfmeister is playing Zurich the day after I leave. Worst! 6 days ago
  • 70 fresh, organic oranges from our tree were sitting on the table this morning. So, marmalade had to be canned. It's tasty! 6 days ago
  • Moles, cousins, and unattended baggage #10kpyramid 1 week ago
  • @mdauber You live in Sunnyvale too? And NBC is ruining your olympics also? We should get together. 1 week ago
  • More updates...

Powered by Twitter Tools

Podcasts I’m listening to