Using Multiple Swing Layouts to Create Dynamic Forms
March 11th, 2009 Adam Menzies, Consultant
Anyone who has had to work on a Swing project has probably found that when you Google for good Swing tips, frameworks, etc…you’ll most likely come up empty handed. Oh you’ll find basic examples of how to build some Swing components and that will be enough if you want to just build static forms that stay the same forever, but truly dynamic forms and interfaces can be frustrating to say the least.
Recently I was on a project where not only did we have to use Swing, but the application also needed to have dynamic forms built on the fly depending on network connectivity, user access level, user input and existing data.
After reading through Sun’s lessons on what layout managers are available and how to use them (go ahead, they explain them better than I can) you’ll see that the only real option for a truly dynamic UI would be the dreaded GridBagLayout. GridBagLayout allows you to place components in more dynamic locations than the other available layouts but using it to place an unknown amount of elements on the screen and have them always look organized and uniform will drive you all kinds of insane, if you ever get it to work at all.
So, on to the solution we found to work best for us in our project.
The basic Swing layouts seem to work just fine for placing dynamic components in either horizontal or vertical “stacks”, but trying to use one layout for an entire screen filled with different components is where things seem to become overly complex. To simplify things we decided to use what could be described as “nested layouts” to use the basic strength of the layouts together.
BoxLayout allows you to stack components on top of each other but only allows one component per “row”. FlowLayout allows you to place components horizontally in left, right or center alignments and allows multiple components to be placed next to each other.
We had over 30 UI screens that all were not only unique but could be different each time they were displayed depending on multiple factors. To reduce time spent solving layout issues and keeping our code simple and easily reproducible we needed a generic way to create any screen for any set of data given.
What we did may best be described in pictures, so I have created a basic image of what we did below. We used JPanels with FlowLayout to create a “row” containing components. For example, a row may have held a JLabel that displayed a question, a set of JRadioButtons and another JLabel displaying the point value for that question. Or a row may have held a series of JLabels that gave details of one item in a set of search results, holding information such as name, date, time, etc…
These JPanel components were then added to a larger “container” JPanel or JScrollPane object that used BoxLayout. As the FlowLayout JPanels were added to the container JPanel they were stacked and gave a look of columns for search results or whatever the desired look was for that screen as the components were stacked on top of each other.
Below is an example of how a simple list of search results would look using this technique:

This seems rather simple but using some creativity rather complex user input forms and menu systems can be built from dynamic data, with each row being built as needed. We used this technique to build questionnaires with over 200 questions of different input types (radio buttons, combo boxes, text input, checkbox, etc…) that were seperated into sections with section headers and footers, comment areas, rows of buttons and more. In reality the size of the questionnaire was almost limitless because of the way we designed the layouts.
Using some basic looping and conditionals this can easily be built into a re-usable set of methods that can be used across your application.
List<String> returnedData = new ArrayList<String>();
returnedData = retrieveData();//create a container JPanel object to hold our rows
JPanel containerPanel = new JPanel(new BoxLayout(this, BoxLayout.PAGE_AXIS));for(String d:returnedData){
//create JPanel object for each row of returned data
JPanel rowPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));//create JLabels to hold columns of data
JLabel nameLabel = new JLabel(d.getName());
JLabel dateLabel = new JLabel(d.getDate());
JLabel sizeLabel = new JLabel(d.getSize());//add label to rowPanel
rowPanel.add(nameLabel);
rowPanel.add(dateLabel);
rowPanel.add(sizeLabel);//add filled row panel to container
containerPanel.add(rowPanel);
}
Hopefully this simple but useful technique helps developers to quickly build dynamic forms without the frustrations of the GridBagLayout.
Entry Filed under: Software Development






10 Comments Add your own
1. Jacek | March 12th, 2009 at 11:26 am
You need to learn about MigLayout…your whole approach is extremely OBSOLETE
2. John Doe | March 12th, 2009 at 9:12 pm
While it’s probably not the best approach, the article is still interesting. It presents one natural and simple way of doing things.
MigLayout would also have some limitations in some conditions depending on the data(i.e.. not much data or fully dynamic layout depending on what’s available).
I would probably use a combined/conditional use of layout managers depending on what to display for complex cases.
3. Jacek | March 13th, 2009 at 6:40 am
I have done extremely complex layouts using MigLayout. At worst, you may need nested JPanels. It’s an amazing piece of software. Any one still stuck using the horribly obsolete and verbose JDK layout managers in 2009 should really update their Swing knowledge.
4. e | March 15th, 2009 at 3:23 am
@Jacek
Take a rest. I can imagine several reasons for not using MigLayout in his case. MigLayout is certainly not a one size fits all solution.
For example, Adam needs “simple” but highly configurable layout based on data and user inputs. Nested basic layouts could be the best approach in this case. Or another example: perhaps his forms must be deployed on client machines with minimal jars and just jre 1.5 and not jre 1.8.
5. Adam Menzies | March 17th, 2009 at 12:07 pm
Thanks to everyone for their comments/suggestions.
“e” is correct, I should have mentioned in the introduction to the article that this solution was used for a client who not only needed a “simple” and easily repeatable solution but for a client that was using Java 1.4 and had developers that had little Java and no Swing experience.
So this is a very simplified, low-level solution that is meant as a starting point when building dynamic Swing interfaces. Obviously as you build UIs using this method the logic and structure will become more complex to meet different needs. The actual structure/logic used in our application is much more complex than what is here.
We did look at some other frameworks/layout managers including MigLayout and even GUI tools like Matisse (which we did use for another application that used static forms), but for the developers who would ultimately be maintaining the application and the deployment of the application we decided it was best to use standard Java libraries only.
While 3rd party/open source solutions can be excellent in the short-term, I think many consultants can attest to being burned by those solutions that seemed like the “next best thing” only to fizzle out in a year and no longer be supported, leaving you to maintain and bug fix what you had already used.
This is certainly not a fix-all solution, but it is a good starting point for new Swing developers who want to stick to the standard Java libraries.
Thanks again for the feedback!
6. Sahana | April 23rd, 2009 at 1:26 am
HI,
Thanks for a nice article. I hope this is going to help me in the dynamic UI construction. I also want to know how you constructed the ‘retreivedata’ method. is it xml based? if so can you please share a sample xml.
Thanks
Sahana
7. Ganesh | August 7th, 2009 at 11:48 am
Hi, Nice Article.
I have a doubt around this.
I am facing a big time problem reading the values from the components - form elements if I render the elements dynamically like this.
Can you help me to understand how to do that?
8. Ganesh | August 7th, 2009 at 12:55 pm
Hey, Thanks.. I got the answer for my question.
I created one level of abstraction(a bean) above the components(button,label, JLabel) to hold all those .
I use a collection HashMap / ArrayList to keep adding those bean elements.
Later I use the collection to retrieve the values which I require, on receiving the event.
9. k40s | June 29th, 2010 at 6:42 am
Hi!
Great article, but I arrived here with the same problem that Ganesh has had and my question is for him/her … Can you write a little example to show how did you resolved it? or, if you did found in another web, can you link it?
Thank you
PD sorry about my english, is a little bad
10. Amit kalra | August 14th, 2010 at 3:14 am
hi All,
Great matter,
I have once scenario which i need help.
We are creating a gui application such that ,all the screen that we are creating will not be stored on the client machine ,instead on the application server .
the gui application will consists as a standlone frame sort of thing which will call the function to the application server for the corresponding screen name .After validating the screen name ,the application server will process the screen and display it on the client gui standlone application.
Please provide some guidance as to how we can create the swing forms and save it into the application server,and call it from the remote locations.of course client system will containg jdk /jre.
Thanks
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed